Ionic性能优化 #
一、性能优化概述 #
1.1 优化维度 #
text
性能优化
│
├── 加载性能
│ ├── 首屏加载
│ ├── 路由懒加载
│ └── 资源压缩
│
├── 运行性能
│ ├── 虚拟滚动
│ ├── 变更检测
│ └── 内存管理
│
└── 渲染性能
├── CSS优化
├── 动画优化
└── 图片优化
1.2 性能指标 #
| 指标 | 目标值 | 说明 |
|---|---|---|
| FCP | < 1.8s | 首次内容绘制 |
| LCP | < 2.5s | 最大内容绘制 |
| FID | < 100ms | 首次输入延迟 |
| CLS | < 0.1 | 累积布局偏移 |
| TTI | < 3.8s | 可交互时间 |
二、虚拟滚动 #
2.1 基本用法 #
html
<ion-content>
<ion-virtual-scroll [items]="items" [itemHeight]="56">
<ion-item *virtualItem="let item">
<ion-label>{{ item.name }}</ion-label>
</ion-item>
</ion-virtual-scroll>
</ion-content>
2.2 复杂列表项 #
typescript
import { Component } from '@angular/core';
interface ListItem {
id: string;
name: string;
avatar: string;
description: string;
}
@Component({
selector: 'app-list',
template: `
<ion-content>
<ion-virtual-scroll
[items]="items"
[itemHeight]="getHeight"
[headerFn]="getHeader">
<ion-item-divider *virtualHeader="let header">
{{ header }}
</ion-item-divider>
<ion-item *virtualItem="let item">
<ion-avatar slot="start">
<img [src]="item.avatar">
</ion-avatar>
<ion-label>
<h2>{{ item.name }}</h2>
<p>{{ item.description }}</p>
</ion-label>
</ion-item>
</ion-virtual-scroll>
</ion-content>
`
})
export class ListPage {
items: ListItem[] = [];
getHeight(item: ListItem): number {
return item.description ? 80 : 56;
}
getHeader(item: ListItem): string {
return item.name.charAt(0).toUpperCase();
}
}
2.3 无限滚动优化 #
html
<ion-content>
<ion-virtual-scroll [items]="items" [itemHeight]="56">
<ion-item *virtualItem="let item">
{{ item.name }}
</ion-item>
</ion-virtual-scroll>
<ion-infinite-scroll (ionInfinite)="loadMore($event)">
<ion-infinite-scroll-content></ion-infinite-scroll-content>
</ion-infinite-scroll>
</ion-content>
typescript
loadMore(event: any) {
this.page++;
this.api.getItems(this.page).subscribe(items => {
this.items = [...this.items, ...items];
event.target.complete();
if (items.length === 0) {
event.target.disabled = true;
}
});
}
三、懒加载 #
3.1 路由懒加载 #
typescript
const routes: Routes = [
{
path: 'home',
loadChildren: () => import('./home/home.module').then(m => m.HomePageModule)
},
{
path: 'detail/:id',
loadChildren: () => import('./detail/detail.module').then(m => m.DetailPageModule)
}
];
3.2 组件懒加载 #
typescript
import { Component } from '@angular/core';
@Component({
selector: 'app-home',
template: `
<ng-container *ngIf="showDetail">
<app-detail></app-detail>
</ng-container>
`
})
export class HomePage {
showDetail = false;
async loadDetail() {
this.showDetail = true;
}
}
3.3 图片懒加载 #
html
<ion-img [src]="imageUrl" alt="图片"></ion-img>
typescript
// 自定义懒加载指令
import { Directive, ElementRef, OnInit } from '@angular/core';
@Directive({
selector: '[lazyLoad]'
})
export class LazyLoadDirective implements OnInit {
constructor(private el: ElementRef) {}
ngOnInit() {
const img = this.el.nativeElement;
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});
observer.observe(img);
}
}
四、变更检测优化 #
4.1 OnPush策略 #
typescript
import { Component, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'app-item',
templateUrl: 'item.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ItemComponent {
@Input() item: any;
}
4.2 手动触发变更检测 #
typescript
import { Component, ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html'
})
export class HomePage {
constructor(private cdr: ChangeDetectorRef) {}
updateData() {
this.data = newData;
this.cdr.detectChanges();
}
// 在异步操作后
async loadData() {
this.data = await this.api.getData();
this.cdr.markForCheck();
}
}
4.3 不可变数据 #
typescript
// 使用不可变数据
this.items = [...this.items, newItem];
// 而不是
this.items.push(newItem);
五、内存管理 #
5.1 清理订阅 #
typescript
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html'
})
export class HomePage implements OnInit, OnDestroy {
private destroy$ = new Subject<void>();
ngOnInit() {
this.data$.pipe(
takeUntil(this.destroy$)
).subscribe(data => {
this.data = data;
});
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}
5.2 清理事件监听 #
typescript
import { Component, OnInit, OnDestroy } from '@angular/core';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html'
})
export class HomePage implements OnInit, OnDestroy {
private resizeHandler: () => void;
ngOnInit() {
this.resizeHandler = () => this.onResize();
window.addEventListener('resize', this.resizeHandler);
}
ngOnDestroy() {
window.removeEventListener('resize', this.resizeHandler);
}
onResize() {
// 处理窗口大小变化
}
}
5.3 清理定时器 #
typescript
import { Component, OnInit, OnDestroy } from '@angular/core';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html'
})
export class HomePage implements OnInit, OnDestroy {
private timer: any;
ngOnInit() {
this.timer = setInterval(() => {
this.updateTime();
}, 1000);
}
ngOnDestroy() {
if (this.timer) {
clearInterval(this.timer);
}
}
updateTime() {
// 更新时间
}
}
六、打包优化 #
6.1 代码分割 #
typescript
// angular.json
{
"projects": {
"app": {
"architect": {
"build": {
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
}
}
}
}
}
}
}
6.2 Tree Shaking #
typescript
// 只导入需要的模块
import { IonicModule } from '@ionic/angular';
// 而不是
// import * as Ionic from '@ionic/angular';
6.3 压缩优化 #
bash
# 生产构建
ionic build --prod
# 或
ng build --prod --aot --build-optimizer
七、运行时优化 #
7.1 防抖与节流 #
typescript
import { Component } from '@angular/core';
import { debounceTime, throttleTime } from 'rxjs/operators';
@Component({
selector: 'app-search',
templateUrl: 'search.page.html'
})
export class SearchPage {
// 防抖
onSearch(event: any) {
fromEvent(event.target, 'input').pipe(
debounceTime(300)
).subscribe(value => {
this.search(value);
});
}
// 节流
onScroll(event: any) {
fromEvent(event.target, 'scroll').pipe(
throttleTime(100)
).subscribe(() => {
this.handleScroll();
});
}
}
7.2 Web Worker #
typescript
// worker.ts
self.onmessage = (event) => {
const result = heavyComputation(event.data);
self.postMessage(result);
};
function heavyComputation(data: any): any {
// 执行耗时计算
return result;
}
// 组件中使用
const worker = new Worker('./worker.ts', { type: 'module' });
worker.postMessage(data);
worker.onmessage = (event) => {
this.result = event.data;
};
7.3 请求优化 #
typescript
// 缓存请求结果
private cache = new Map<string, Observable<any>>();
getData(key: string): Observable<any> {
if (this.cache.has(key)) {
return this.cache.get(key)!;
}
const request = this.http.get(`/api/data/${key}`).pipe(
shareReplay(1)
);
this.cache.set(key, request);
return request;
}
八、性能监控 #
8.1 Angular性能监控 #
typescript
import { Component } from '@angular/core';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html'
})
export class HomePage {
constructor() {
// 开发模式下启用性能监控
if (!environment.production) {
this.enablePerformanceMonitoring();
}
}
private enablePerformanceMonitoring() {
// 监控变更检测
console.time('changeDetection');
// ...
console.timeEnd('changeDetection');
}
}
8.2 Lighthouse审计 #
bash
# 安装Lighthouse
npm install -g lighthouse
# 运行审计
lighthouse https://your-app.com --view
九、最佳实践总结 #
9.1 性能检查清单 #
- [ ] 使用虚拟滚动处理长列表
- [ ] 路由懒加载
- [ ] 图片懒加载
- [ ] 使用OnPush变更检测
- [ ] 清理订阅和事件监听
- [ ] 代码分割和Tree Shaking
- [ ] 启用生产模式优化
- [ ] 使用防抖和节流
- [ ] 缓存HTTP请求
- [ ] 性能监控
9.2 下一步 #
掌握了性能优化后,接下来让我们学习 测试策略,了解Ionic应用的测试方法!
最后更新:2026-03-28