angular-zoneless

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Angular Zoneless

Angular Zoneless

Version: Angular 19+ (2025) Tags: Zoneless, Change Detection, Signals, Reactivity
References: Zoneless GuideSignals
版本: Angular 19+ (2025) 标签: Zoneless、变更检测、Signals、响应式
参考资料: Zoneless指南Signals

API Changes

API变更

This section documents recent version-specific API changes.
  • NEW: provideZonelessChangeDetection — Enable zoneless mode source
  • NEW: afterNextRender — Run code after rendering without zone.js
  • NEW: Experimental Zoneless — Available since Angular 17, stable in Angular 19+
  • NEW: signal() + computed() — Works without zone.js
本部分记录了近期各版本对应的API变动:
  • 新增:provideZonelessChangeDetection — 启用无zone模式 来源
  • 新增:afterNextRender — 无需zone.js即可在渲染结束后运行代码
  • 新增:实验性无zone模式 — 自Angular 17起提供,Angular 19+版本正式稳定
  • 新增:signal() + computed() — 无需依赖zone.js即可正常工作

Best Practices

最佳实践

  • Enable zoneless change detection
ts
export const appConfig: ApplicationConfig = {
  providers: [
    provideZonelessChangeDetection()
  ]
};
  • Use signals for reactivity
ts
@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <p>Count: {{ count() }}</p>
    <p>Double: {{ double() }}</p>
  `
})
export class CounterComponent {
  count = signal(0);
  double = computed(() => this.count() * 2);

  increment() {
    this.count.update(c => c + 1);
  }
}
  • Use afterNextRender for DOM operations
ts
constructor() {
  afterNextRender(() => {
    // Runs after rendering, outside zone
    this.initChart();
  });
}
  • Use afterRender for repeated operations
ts
constructor() {
  afterRender(() => {
    // Runs after every render
  });
}
  • Handle async without zone.js
ts
@Component({
  template: `
    @if (data$ | async; as data) {
      {{ data.name }}
    }
  `
})
export class AsyncComponent {
  data$ = from(fetch('/api/data')).pipe(
    share()
  );
}
  • Use ChangeDetectorRef manually when needed
ts
constructor(private cdr: ChangeDetectorRef) {}

update() {
  this.value = newValue;
  this.cdr.markForCheck();
}
  • Remove zone.js from polyfills
ts
// polyfills.ts
// Remove or comment out zone.js import
// import 'zone.js';
  • Use untracked for non-reactive reads
ts
import { untracked } from '@angular/core';

ngOnInit() {
  // Read without creating dependency
  const value = untracked(() => this.signal());
}
  • Handle browser events
ts
@HostListener('click')
onClick() {
  // Works without zone.js
  this.count.update(c => c + 1);
}
  • Test in zoneless mode
ts
TestBed.configureTestingModule({
  providers: [
    provideZonelessChangeDetection()
  ]
});
  • 启用无zone变更检测
ts
export const appConfig: ApplicationConfig = {
  providers: [
    provideZonelessChangeDetection()
  ]
};
  • 使用Signals实现响应式
ts
@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <p>Count: {{ count() }}</p>
    <p>Double: {{ double() }}</p>
  `
})
export class CounterComponent {
  count = signal(0);
  double = computed(() => this.count() * 2);

  increment() {
    this.count.update(c => c + 1);
  }
}
  • 对DOM操作使用afterNextRender
ts
constructor() {
  afterNextRender(() => {
    // Runs after rendering, outside zone
    this.initChart();
  });
}
  • 对重复操作使用afterRender
ts
constructor() {
  afterRender(() => {
    // Runs after every render
  });
}
  • 无需zone.js处理异步逻辑
ts
@Component({
  template: `
    @if (data$ | async; as data) {
      {{ data.name }}
    }
  `
})
export class AsyncComponent {
  data$ = from(fetch('/api/data')).pipe(
    share()
  );
}
  • 需要时手动使用ChangeDetectorRef
ts
constructor(private cdr: ChangeDetectorRef) {}

update() {
  this.value = newValue;
  this.cdr.markForCheck();
}
  • 从polyfills中移除zone.js
ts
// polyfills.ts
// Remove or comment out zone.js import
// import 'zone.js';
  • 非响应式读取时使用untracked
ts
import { untracked } from '@angular/core';

ngOnInit() {
  // Read without creating dependency
  const value = untracked(() => this.signal());
}
  • 处理浏览器事件
ts
@HostListener('click')
onClick() {
  // Works without zone.js
  this.count.update(c => c + 1);
}
  • 在无zone模式下测试
ts
TestBed.configureTestingModule({
  providers: [
    provideZonelessChangeDetection()
  ]
});