angular-performance

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Angular Performance

Angular性能

Version: Angular 21 (2025) Tags: Performance, Optimization, Bundle Size, Change Detection
版本: Angular 21 (2025) 标签: 性能, 优化, 包体积, 变更检测
参考资料: 性能指南变更检测

API Changes

API变更

This section documents recent version-specific API changes.
  • NEW: Zoneless change detection — Disable zone.js for better performance source
  • NEW: Deferrable views (@defer) — Lazy load component code
  • NEW: Signal-based reactivity — Use signals instead of zone.js
  • NEW: afterNextRender — Run code after rendering without zone.js
本部分记录了近期版本专属的API变动。
  • 新增:无Zone变更检测 —— 禁用zone.js以提升性能 来源
  • 新增:可延迟视图(@defer)—— 懒加载组件代码
  • 新增:基于Signal的响应式 —— 使用signals替代zone.js
  • 新增:afterNextRender —— 在渲染完成后运行代码,无需依赖zone.js

Best Practices

最佳实践

  • Use OnPush change detection strategy
ts
@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  // ...
})
export class MyComponent {}
  • Use trackBy with @for
ts
@Component({
  template: `
    @for (item of items; track item.id) {
      {{ item.name }}
    }
  `
})
export class MyComponent {}
  • Use lazy loading for routes
ts
const routes: Routes = [
  {
    path: 'dashboard',
    loadComponent: () => import('./dashboard/dashboard.component').then(m => m.DashboardComponent)
  }
];
  • Use @defer for lazy loading
ts
@Component({
  template: `
    @defer (on viewport) {
      <heavy-chart-component />
    } @placeholder {
      <div>Loading...</div>
    }
  `
})
export class MyComponent {}
  • Use trackBy in @for loops
ts
@for (item of items; track item.id) {
  <li>{{ item.name }}</li>
}
  • Use pure pipes
ts
@Pipe({
  name: 'myPipe',
  pure: true // Default - only runs when input changes
})
export class MyPipe implements PipeTransform {}
  • Avoid function calls in templates
ts
// ❌ Bad
{{ calculateTotal() }}

// ✅ Good
{{ total }}
  • Use ngSrc for images
ts
<img [ngSrc]="imageUrl" width="100" height="100" priority>
  • Use ChangeDetectionRef manually when needed
ts
constructor(private cdr: ChangeDetectorRef) {}

updateData() {
  this.data = newData;
  this.cdr.detectChanges();
}
  • Use runOutsideAngular for third-party libs
ts
import { runOutsideAngular } from '@angular/core/zone';

onClick() {
  runOutsideAngular(() => {
    this第三方Lib.doSomething();
  });
}
  • Use provideZonelessChangeDetection
ts
export const appConfig: ApplicationConfig = {
  providers: [
    provideZonelessChangeDetection()
  ]
};
  • Use afterNextRender for initialization
ts
constructor() {
  afterNextRender(() => {
    // Runs after rendering, outside zone
  });
}
  • Optimize bundle size
bash
undefined
  • 使用OnPush变更检测策略
ts
@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  // ...
})
export class MyComponent {}
  • 在@for中使用trackBy
ts
@Component({
  template: `
    @for (item of items; track item.id) {
      {{ item.name }}
    }
  `
})
export class MyComponent {}
  • 为路由使用懒加载
ts
const routes: Routes = [
  {
    path: 'dashboard',
    loadComponent: () => import('./dashboard/dashboard.component').then(m => m.DashboardComponent)
  }
];
  • 使用@defer实现懒加载
ts
@Component({
  template: `
    @defer (on viewport) {
      <heavy-chart-component />
    } @placeholder {
      <div>加载中...</div>
    }
  `
})
export class MyComponent {}
  • 在@for循环中使用trackBy
ts
@for (item of items; track item.id) {
  <li>{{ item.name }}</li>
}
  • 使用纯管道
ts
@Pipe({
  name: 'myPipe',
  pure: true // 默认配置 - 仅在输入变化时运行
})
export class MyPipe implements PipeTransform {}
  • 避免在模板中调用函数
ts
// ❌ 错误写法
{{ calculateTotal() }}

// ✅ 推荐写法
{{ total }}
  • 图片使用ngSrc
ts
<img [ngSrc]="imageUrl" width="100" height="100" priority>
  • 必要时手动使用ChangeDetectionRef
ts
constructor(private cdr: ChangeDetectorRef) {}

updateData() {
  this.data = newData;
  this.cdr.detectChanges();
}
  • 第三方库使用runOutsideAngular
ts
import { runOutsideAngular } from '@angular/core/zone';

onClick() {
  runOutsideAngular(() => {
    this.第三方Lib.doSomething();
  });
}
  • 使用provideZonelessChangeDetection
ts
export const appConfig: ApplicationConfig = {
  providers: [
    provideZonelessChangeDetection()
  ]
};
  • 使用afterNextRender进行初始化
ts
constructor() {
  afterNextRender(() => {
    // 在渲染完成后运行,脱离zone管控
  });
}
  • 优化包体积
bash
undefined

Analyze bundle

分析包体积

ng build --stats-json npx webpack-bundle-analyzer dist/stats.json

- Use standalone components

```ts
@Component({
  standalone: true,
  imports: [CommonModule],
  // ...
})
export class MyComponent {}
ng build --stats-json npx webpack-bundle-analyzer dist/stats.json

- 使用独立组件

```ts
@Component({
  standalone: true,
  imports: [CommonModule],
  // ...
})
export class MyComponent {}