性能优化 #
一、性能优化概述 #
Angular性能优化主要关注以下几个方面:
- 变更检测优化
- 模块懒加载
- 编译优化
- 运行时优化
- 内存管理
二、变更检测优化 #
2.1 使用OnPush策略 #
typescript
import { Component, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'app-user-list',
template: `
<app-user-card
*ngFor="let user of users"
[user]="user">
</app-user-card>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class UserListComponent {
@Input() users: User[];
}
2.2 OnPush触发条件 #
- 输入属性引用变化
- 组件内部触发事件
- 手动触发变更检测
- Async管道订阅的Observable发出新值
2.3 不可变数据 #
typescript
// 推荐:创建新引用
addUser(user: User) {
this.users = [...this.users, user];
}
updateUser(updatedUser: User) {
this.users = this.users.map(user =>
user.id === updatedUser.id ? updatedUser : user
);
}
// 不推荐:直接修改
addUser(user: User) {
this.users.push(user);
}
2.4 使用markForCheck #
typescript
import { Component, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'app-example',
template: '{{ data }}',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ExampleComponent {
data: string;
constructor(private cdr: ChangeDetectorRef) {}
updateData() {
this.data = 'new value';
this.cdr.markForCheck();
}
}
2.5 使用detach/reattach #
typescript
@Component({
selector: 'app-heavy',
template: '...'
})
export class HeavyComponent implements OnInit {
constructor(private cdr: ChangeDetectorRef) {}
ngOnInit() {
this.cdr.detach();
setInterval(() => {
this.cdr.reattach();
this.cdr.detectChanges();
this.cdr.detach();
}, 1000);
}
}
三、模板优化 #
3.1 使用trackBy #
typescript
@Component({
template: `
<li *ngFor="let user of users; trackBy: trackById">
{{ user.name }}
</li>
`
})
export class UserListComponent {
trackById(index: number, user: User): number {
return user.id;
}
}
3.2 避免复杂表达式 #
html
<!-- 不推荐 -->
<div>{{ formatName(user.firstName, user.lastName, user.middleName) }}</div>
<!-- 推荐:预先计算 -->
<div>{{ user.fullName }}</div>
3.3 使用纯管道 #
typescript
@Pipe({
name: 'formatDate',
pure: true
})
export class FormatDatePipe implements PipeTransform {
transform(value: Date): string {
return value.toLocaleDateString();
}
}
3.4 减少模板绑定 #
html
<!-- 不推荐 -->
<div [style.color]="color" [style.background]="bg" [style.padding]="padding">
{{ content }}
</div>
<!-- 推荐 -->
<div [ngStyle]="styles">{{ content }}</div>
四、懒加载优化 #
4.1 路由懒加载 #
typescript
const routes: Routes = [
{
path: 'admin',
loadChildren: () => import('./admin/admin.module')
.then(m => m.AdminModule)
}
];
4.2 组件懒加载 #
typescript
@Component({
template: `
<ng-template #container></ng-template>
`
})
export class LazyComponent {
@ViewChild('container', { read: ViewContainerRef }) container!: ViewContainerRef;
async loadComponent() {
const { HeavyComponent } = await import('./heavy.component');
this.container.createComponent(HeavyComponent);
}
}
4.3 预加载策略 #
typescript
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes, PreloadAllModules)
]
};
五、编译优化 #
5.1 AOT编译 #
bash
ng build --aot
5.2 生产构建 #
bash
ng build --configuration production
5.3 构建优化选项 #
json
{
"optimization": true,
"buildOptimizer": true,
"aot": true,
"sourceMap": false,
"extractLicenses": true,
"vendorChunk": false,
"commonChunk": false
}
5.4 Budget配置 #
json
{
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
]
}
六、内存优化 #
6.1 取消订阅 #
typescript
export class ExampleComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>();
ngOnInit() {
this.service.getData()
.pipe(takeUntil(this.destroy$))
.subscribe();
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}
6.2 清理定时器 #
typescript
export class ExampleComponent implements OnInit, OnDestroy {
private timer: any;
ngOnInit() {
this.timer = setInterval(() => {}, 1000);
}
ngOnDestroy() {
clearInterval(this.timer);
}
}
6.3 清理事件监听 #
typescript
export class ExampleComponent implements OnInit, OnDestroy {
private listener: () => void;
constructor(private renderer: Renderer2, private element: ElementRef) {}
ngOnInit() {
this.listener = this.renderer.listen(
this.element.nativeElement,
'click',
this.onClick
);
}
ngOnDestroy() {
this.listener();
}
}
七、网络优化 #
7.1 HTTP缓存 #
typescript
@Injectable()
export class CacheInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler) {
const cachedResponse = this.cache.get(req.url);
if (cachedResponse) {
return of(cachedResponse);
}
return next.handle(req).pipe(
tap(event => {
if (event instanceof HttpResponse) {
this.cache.set(req.url, event);
}
})
);
}
}
7.2 请求合并 #
typescript
getUsers(ids: number[]): Observable<User[]> {
const requests = ids.map(id => this.http.get<User>(`/api/users/${id}`));
return forkJoin(requests);
}
7.3 请求取消 #
typescript
export class SearchComponent implements OnDestroy {
private searchSubject = new Subject<string>();
private destroy$ = new Subject<void>();
constructor(private http: HttpClient) {
this.searchSubject.pipe(
debounceTime(300),
switchMap(query => this.http.get(`/api/search?q=${query}`)),
takeUntil(this.destroy$)
).subscribe();
}
search(query: string) {
this.searchSubject.next(query);
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}
八、图片优化 #
8.1 图片懒加载 #
typescript
@Directive({
selector: '[appLazyLoad]',
standalone: true
})
export class LazyLoadDirective implements OnInit {
@Input() appLazyLoad: string;
constructor(private el: ElementRef) {}
ngOnInit() {
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
this.el.nativeElement.src = this.appLazyLoad;
observer.unobserve(this.el.nativeElement);
}
});
});
observer.observe(this.el.nativeElement);
}
}
8.2 使用NgOptimizedImage #
typescript
import { NgOptimizedImage } from '@angular/common';
@Component({
imports: [NgOptimizedImage],
template: `
<img
ngSrc="assets/image.jpg"
alt="描述"
width="800"
height="600"
priority
/>
`
})
九、性能监控 #
9.1 使用Angular DevTools #
bash
# 安装Angular DevTools浏览器扩展
9.2 性能指标 #
typescript
// 使用Performance API
const start = performance.now();
// 执行操作
const end = performance.now();
console.log(`耗时: ${end - start}ms`);
9.3 变更检测周期 #
typescript
import { ApplicationRef } from '@angular/core';
constructor(private appRef: ApplicationRef) {
this.appRef.isStable.subscribe(stable => {
console.log('应用稳定:', stable);
});
}
十、优化检查清单 #
10.1 变更检测 #
- [ ] 使用OnPush策略
- [ ] 使用trackBy
- [ ] 避免复杂模板表达式
- [ ] 使用纯管道
10.2 编译 #
- [ ] 启用AOT编译
- [ ] 生产构建优化
- [ ] 配置Budgets
10.3 网络 #
- [ ] 启用懒加载
- [ ] 配置预加载
- [ ] HTTP缓存
- [ ] 请求取消
10.4 内存 #
- [ ] 取消订阅
- [ ] 清理定时器
- [ ] 清理事件监听
十一、总结 #
| 优化方向 | 策略 |
|---|---|
| 变更检测 | OnPush、trackBy、纯管道 |
| 模板优化 | 简化表达式、减少绑定 |
| 懒加载 | 路由懒加载、组件懒加载 |
| 编译优化 | AOT、生产构建 |
| 内存优化 | 取消订阅、清理资源 |
| 网络优化 | 缓存、请求合并 |
恭喜完成Angular完全指南!
最后更新:2026-03-26