Zoneless bỏ zone.js, nên Angular không còn tự động chạy change detection sau mỗi setTimeout, event listener hay HTTP response.
Thay vào đó nó chỉ chạy khi có tín hiệu tường minh: signal thay đổi, markForCheck() (kể cả gián tiếp qua async pipe), hoặc event trên template binding.
bootstrapApplication(App, {
providers: [provideZonelessChangeDetection()],
})Những chỗ thường hỏng và cách sửa:
- State gán trong callback ngoài Angular (websocket, setInterval, SDK bên thứ ba, addEventListener thủ công): UI đứng yên → chuyển state sang signal, hoặc gọi cdr.markForCheck().
- Field thường được binding trong template: không có gì báo Angular biết nó đổi → dùng signal / computed cho state hiển thị.
- Test dựa vào fakeAsync/whenStable theo hành vi zone: cần rà lại, dùng await fixture.whenStable() với API zoneless.
- Thư viện cũ dựa vào NgZone.onStable hoặc NgZone.run() để ép cập nhật: kiểm tra bản hỗ trợ zoneless.
Lộ trình an toàn: bật OnPush toàn bộ trước, chuyển dần state sang signal/async pipe, chạy dev với provideZonelessChangeDetection() để lộ chỗ hỏng, rồi mới gỡ zone.js khỏi polyfills. Đổi lại là bundle nhỏ hơn (~bỏ zone.js), ít vòng change detection thừa và stack trace sạch hơn.