# Angular 19 Zoneless: Wydajnosc i Change Detection bez Zone.js > Przewodnik techniczny po Zoneless Change Detection w Angular 19 i 20. Architektura detekcji zmian oparta na Signals, aktywacja provideZonelessChangeDetection, migracja setTimeout i Reactive Forms, SSR bez Zone.js oraz benchmarki wydajnosci. - Published: 2026-04-27 - Updated: 2026-04-27 - Author: SharpSkill - Tags: angular, zoneless, change-detection, performance, signals, zone-js - Reading time: 10 min --- Zoneless Change Detection stanowi najbardziej znaczaca zmiane architekturalna w Angular od czasu wprowadzenia standalone components. Calkowite usuniecie Zone.js z aplikacji przeklada sie na mniejsze bundle (okolo 33 KB mniej), redukcje zbednych cykli detekcji zmian o 30-40% oraz czyste stack trace bez szumu generowanego przez Zone.js. Dla programistow Angular w 2026 roku opanowanie tego mechanizmu jest kluczowe zarowno w codziennej pracy, jak i podczas przygotowania do [pytan rekrutacyjnych z Angular dotyczacych change detection](/pl/technologies/angular/interview-questions/change-detection). > **Harmonogram wdrazania Zoneless** > > Angular 18 wprowadzil Zoneless jako funkcjonalnosc eksperymentalna. Angular 19 udoskonalil eksperymentalne API za pomoca `provideExperimentalZonelessChangeDetection()`. Angular 20 przeniosl je do wersji stabilnej jako `provideZonelessChangeDetection()`. Angular 21 uczynil Zoneless domyslnym ustawieniem dla nowych projektow. ## Jak dziala Change Detection oparty na Zone.js Zanim mozna w pelni zrozumiec zalety trybu Zoneless, warto dokladnie przeanalizowac mechanizm, ktory zastepuje. Zone.js dziala poprzez monkey-patching wszystkich asynchronicznych API przegladarki: `setTimeout`, `setInterval`, `Promise.then`, `addEventListener`, `XMLHttpRequest` i kilkudziesieciu innych. Za kazdym razem, gdy jedna z tych operacji asynchronicznych zostaje zakonczona, Zone.js powiadamia Angular, ktory nastepnie uruchamia detekcje zmian w calym drzewie komponentow. Podejscie to ma fundamentalna wade: Zone.js nie posiada zadnej informacji o tym, czy stan aplikacji faktycznie ulegl zmianie. Wywolanie `setTimeout` wykorzystywane wylacznie do celow animacyjnych nadal wyzwala pelny cykl detekcji zmian. W duzych aplikacjach z setkami komponentow ten narzut staje sie wymierny i odczuwalny. ```typescript // app.config.ts - Traditional Zone.js setup (Angular 18-19) import { ApplicationConfig } from '@angular/core'; import { provideZoneChangeDetection } from '@angular/core'; export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), // Zone.js patches ~130+ browser APIs // Every async callback triggers change detection ] }; ``` Mechanizm event coalescing (wprowadzony w Angular 14) czesciowo redukuje narzut poprzez laczenie wielu zdarzen w pojedynczy cykl detekcji zmian, jednak rdzen problemu pozostaje niezmieniony: detekcja zmian uruchamia sie znacznie czesciej niz jest to konieczne. ## Aktywacja Zoneless Change Detection w Angular 19 i 20 Sciezka migracji rozni sie w zaleznosci od wersji Angular. Angular 19 wykorzystuje eksperymentalne API, natomiast Angular 20 udostepnia wersje stabilna. ```typescript // app.config.ts - Angular 19 (experimental) import { ApplicationConfig } from '@angular/core'; import { provideExperimentalZonelessChangeDetection } from '@angular/core'; export const appConfig: ApplicationConfig = { providers: [ provideExperimentalZonelessChangeDetection(), // No more Zone.js patching ] }; ``` ```typescript // app.config.ts - Angular 20+ (stable) import { ApplicationConfig } from '@angular/core'; import { provideZonelessChangeDetection } from '@angular/core'; export const appConfig: ApplicationConfig = { providers: [ provideZonelessChangeDetection(), ] }; ``` Po zmianie providera nalezy usunac `zone.js` z tablicy polyfills w pliku `angular.json` zarowno dla targetow build, jak i test, a nastepnie odinstalowac pakiet: ```bash # Remove zone.js polyfill from angular.json build and test targets # Then uninstall the package npm uninstall zone.js ``` Redukcja rozmiaru bundle jest natychmiastowa: Zone.js odpowiada za okolo 33 KB surowego kodu (10 KB po gzip), ktory jest ladowany eagerly przy starcie aplikacji. ## Co wyzwala detekcje zmian w trybie Zoneless Bez Zone.js przechwytujacego kazda operacje asynchroniczna Angular opiera sie na jawnych powiadomieniach. Framework planuje uruchomienie detekcji zmian, gdy wystapi ktorakolwiek z ponizszych sytuacji: - Signal odczytywany w szablonie zmieni swoja wartosc - Zostanie wywolane `ChangeDetectorRef.markForCheck()` (automatycznie przez `AsyncPipe`) - Zmieni sie input komponentu poprzez `ComponentRef.setInput()` - Zostanie wykonany callback listenera szablonu lub hosta (click, input itp.) - Wczesniej oznaczony jako dirty widok zostanie dolaczony do drzewa komponentow ```typescript // counter.component.ts - Signal-driven change detection import { Component, signal, computed } from '@angular/core'; @Component({ selector: 'app-counter', template: `
{{ count() }}

Double: {{ doubled() }}

` }) export class CounterComponent { // Signal updates automatically notify the template count = signal(0); doubled = computed(() => this.count() * 2); increment() { this.count.update(v => v + 1); // No markForCheck() needed - signal handles notification } decrement() { this.count.update(v => v - 1); } } ``` Signals stanowia naturalne uzupelnienie trybu Zoneless. Gdy wartosc sygnalu sie zmienia, Angular wie dokladnie, ktore szablony od niego zaleza, i planuje ukierunkowana detekcje zmian wylacznie dla tych widokow. > **OnPush jest zalecany, ale nie wymagany** > > Przyjecie strategii `ChangeDetectionStrategy.OnPush` to zalecany krok w kierunku zgodnosci z trybem Zoneless, ale nie jest to wymog bezwzgledny. Domyslna strategia detekcji zmian nadal dziala w trybie Zoneless. Niemniej jednak OnPush zapewnia, ze komponenty sa ponownie renderowane tylko wtedy, gdy zmienia sie ich inputy lub zostanie wywolane `markForCheck()`, co naturalnie wpisuje sie w model mentalny Zoneless. ## Migracja istniejacych aplikacji: typowe pulapki Przejscie z Zone.js na tryb Zoneless rzadko ogranicza sie do jednolinijkowej zmiany w istniejacych aplikacjach. Kilka wzorcow, ktore opieraly sie na niejawnym zachowaniu Zone.js, wymaga jawnej obslugi. ### setTimeout i setInterval nie wyzwalaja juz aktualizacji W trybie Zone.js callbacki `setTimeout` automatycznie wyzwalaly detekcje zmian. W trybie Zoneless tak sie nie dzieje. ```typescript // user-status.component.ts - Before: relies on Zone.js @Component({ selector: 'app-user-status', template: `{{ statusMessage }}` }) export class UserStatusComponent { statusMessage = 'Loading...'; ngOnInit() { setTimeout(() => { // Zone.js would trigger CD here - zoneless does NOT this.statusMessage = 'Ready'; }, 2000); } } ``` ```typescript // user-status.component.ts - After: signal-based approach import { Component, signal } from '@angular/core'; @Component({ selector: 'app-user-status', template: `{{ statusMessage() }}` }) export class UserStatusComponent { statusMessage = signal('Loading...'); ngOnInit() { setTimeout(() => { // Signal update notifies Angular automatically this.statusMessage.set('Ready'); }, 2000); } } ``` ### Reactive Forms wymagaja jawnego powiadomienia Zmiany stanu formularzy za posrednictwem `FormControl.setValue()` lub `patchValue()` nie wyzwalaja automatycznie detekcji zmian w trybie Zoneless. Dwa podejscia rozwiazuja ten problem: polaczenie observabli formularza z `markForCheck()` lub eksponowanie danych formularza poprzez sygnaly. ```typescript // search.component.ts - Reactive forms with zoneless import { Component, inject, signal } from '@angular/core'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { toSignal } from '@angular/core/rxjs-interop'; import { debounceTime, distinctUntilChanged } from 'rxjs'; @Component({ selector: 'app-search', imports: [ReactiveFormsModule], template: `

Results for: {{ searchTerm() }}

` }) export class SearchComponent { searchControl = new FormControl(''); // Convert observable to signal for automatic template updates searchTerm = toSignal( this.searchControl.valueChanges.pipe( debounceTime(300), distinctUntilChanged() ), { initialValue: '' } ); } ``` ## Server-Side Rendering bez Zone.js SSR w aplikacjach Angular bez Zone.js wymaga szczegolnej uwagi. Zone.js dotychczas pomagal Angular okreslac, kiedy aplikacja osiagnela stan "stabilny" odpowiedni do serializacji. Bez niego te role przejmuje serwis `PendingTasks`. ```typescript // data-loader.component.ts - SSR-compatible async loading import { Component, inject, signal } from '@angular/core'; import { PendingTasks } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { firstValueFrom } from 'rxjs'; @Component({ selector: 'app-data-loader', template: ` @if (data()) {
{{ data()!.title }}
} @else {
Loading...
} ` }) export class DataLoaderComponent { private http = inject(HttpClient); private pendingTasks = inject(PendingTasks); data = signal<{ title: string } | null>(null); ngOnInit() { // PendingTasks.run() prevents SSR serialization until complete this.pendingTasks.run(async () => { const result = await firstValueFrom( this.http.get<{ title: string }>('/api/data') ); this.data.set(result); }); } } ``` Bez `PendingTasks` Angular dokonalby serializacji strony przed zaladowaniem danych asynchronicznych, wysylajac do klienta pusta tresc zamiast prawidlowo wyrenderowanej strony. ## Benchmarki wydajnosci: Zone.js kontra Zoneless Korzysci wydajnosciowe wynikajace z usuniecia Zone.js mozna podzielic na trzy kategorie: | Metryka | Zone.js | Zoneless | Poprawa | |---------|---------|----------|---------| | Poczatkowy rozmiar bundle | +33KB surowo / +10KB gzip | 0KB narzutu | 100% redukcja | | Cykle detekcji zmian (typowa aplikacja) | 150-300 na interakcje | 5-15 na interakcje | 80-95% mniej | | Glebokosc stack trace | 8-12 dodatkowych ramek Zone | Czyste natywne trace | Natychmiastowa czytelnosc | | Time to Interactive (TTI) | Baseline | 15-25% szybszy | Eliminacja bootstrapu Zone | Najbardziej spektakularna poprawa widoczna jest w aplikacjach z intensywna aktywnoscia asynchroniczna: polling HTTP, polaczenia WebSocket, timery i zlozone handlery zdarzen. Kazda z tych operacji wczesniej wyzwalala zbedne cykle detekcji zmian, ktore tryb Zoneless calkowicie eliminuje. > **Kompatybilnosc bibliotek** > > Niektore biblioteki zewnetrzne nadal wewnetrznie polegaja na Zone.js. Okna dialogowe, pewne wrappery Web Components i niektore biblioteki animacji moga zachowywac sie nieprzewidywalnie w trybie Zoneless. Przed wdrozeniem trybu Zoneless na srodowisko produkcyjne nalezy dokladnie przetestowac wszystkie integracje z bibliotekami zewnetrznymi. ## API NgZone, ktore przetrwaja migracje Czeste nieporozumienie: usuniecie Zone.js oznacza koniecznosc usuniecia wszystkich odwolan do `NgZone`. Jest to nieprawda. Metody `NgZone.run()` i `NgZone.runOutsideAngular()` pozostaja kompatybilne z aplikacjami Zoneless i powinny byc zachowane w bibliotekach wspoldzielonych. Ich usuniecie moze spowodowac regresje wydajnosciowe w aplikacjach, ktore nadal uzywaja Zone.js i korzystaja z tych bibliotek. Jednak trzy observable NgZone musza zostac wyeliminowane: - `NgZone.onMicrotaskEmpty` -- nigdy nie emituje w trybie Zoneless - `NgZone.onUnstable` -- nigdy nie emituje w trybie Zoneless - `NgZone.onStable` -- nigdy nie emituje w trybie Zoneless Logike zaleznac od czasu, ktora wykorzystywala te observable, nalezy zastapic uzyciem `afterNextRender()` lub `afterEveryRender()` z `@angular/core`. ## Od Angular 19 Experimental do Angular 21 Default Ewolucja API Zoneless podaza wyrazna sciezka stabilizacji: - **Angular 18.1**: Wprowadzenie `provideExperimentalZonelessChangeDetection()` jako API eksperymentalne - **Angular 19**: Udoskonalenie eksperymentalnego API, szersze testy ekosystemu - **Angular 20**: Zmiana nazwy na `provideZonelessChangeDetection()`, przeniesienie do wersji stabilnej - **Angular 20.2**: API w pelni stabilne, bez oczekiwanych zmian behawioralnych - **Angular 21**: Zoneless staje sie domyslnym ustawieniem dla projektow tworzonych przez `ng new`, bez koniecznosci jawnego wywolania providera Dla zespolow pracujacych z Angular 19 sciezka aktualizacji jest prosta: aktualizacja do Angular 20, zastapienie `provideExperimentalZonelessChangeDetection` przez `provideZonelessChangeDetection` i usuniecie polyfilla `zone.js`. Angular 19 osiaga koniec wsparcia 19 maja 2026 roku, co nadaje tej migracji pilny charakter. Przygotowanie do rozmow rekrutacyjnych z Angular? Modul [pytan rekrutacyjnych Angular dotyczacych change detection](/pl/technologies/angular/interview-questions/change-detection) na SharpSkill szczegolowo omawia wzorce detekcji zmian, w tym scenariusze Zoneless, o ktore rekruterzy pytaja coraz czesciej. Szerszy przeglad tematow oferuje przewodnik [top 25 pytan rekrutacyjnych Angular](/pl/blog/angular/top-25-angular-interview-questions). Modul [Angular Signals](/pl/technologies/angular/interview-questions/angular-signals) obejmuje z kolei model reaktywnosci, ktory umozliwia dzialanie trybu Zoneless. ## Podsumowanie - Usuniecie Zone.js eliminuje 33 KB wagi bundle i likwiduje warstwe monkey-patchingu przechwytujaca ponad 130 API przegladarki - Angular Signals zapewniaja jawny model reaktywnosci, ktory czyni tryb Zoneless praktycznym rozwiazaniem, automatycznie powiadamiajac szablony o zmianach stanu - Migracja wymaga konwersji wzorcow `setTimeout`/`setInterval`, Reactive Forms oraz logiki zalezncej od czasu na podejscie oparte na sygnalach lub wywolaniach `markForCheck()` - Aplikacje SSR musza zaadoptowac `PendingTasks` jako zamiennik mechanizmu detekcji stabilnosci Zone.js - Metody `NgZone.run()` i `NgZone.runOutsideAngular()` powinny byc zachowane w bibliotekach wspoldzielonych dla zachowania kompatybilnosci wstecznej - Eksperymentalne API Angular 19 (`provideExperimentalZonelessChangeDetection`) mapuje sie bezposrednio na stabilne `provideZonelessChangeDetection()` z Angular 20, co sprawia, ze aktualizacja sprowadza sie do zmiany nazwy - Kompatybilnosc bibliotek zewnetrznych pozostaje glownym czynnikiem ryzyka i wymaga gruntownego testowania przed wdrozeniem produkcyjnym --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/pl/blog/angular/angular-19-zoneless-change-detection-performance