Për më shumë se një dekadë, Angular ka zgjidhur një problem themelor -kur të kontrolloni përsëri ndërfaqen e përdoruesit pasi diçka ka ndryshuar- me një zgjidhje sa zgjuar aq edhe invazive:Zona.js, një bibliotekë që rishkruan API-në asinkrone të shfletuesit në kohën e ekzekutimit për të kapur çdo shkak të mundshëm ndryshimi. Me ardhjen eSinjalet, Angular po e braktis gradualisht këtë qasje në favor të një modeli ku vetë të dhënat, jo një arnim global i majmunëve, e dinë se kush duhet të përditësohet. Ky artikull shpjegon se si Zone.js funksionon brenda, pse modeli i tij ka kufizime strukturore të pazgjidhshme dhe çfarë përfshin në praktikë bërja e një aplikacioni Angularpa zona.
Si funksionon zbulimi i ndryshimeve bazuar në Zone.js
Zone.js zgjidh një problem shumë real: Angular duhet të dijëKurkontrolloni përsëri komponentët për të përditësuar DOM-in, por JavaScript nuk ofron në mënyrë origjinale një mënyrë për të "shikuar" kur një vlerë ndryshon në një mënyrë të përgjithshme. Zgjidhja e Zone.js është drastike: pas nisjes së aplikacionit,mbishkruan(monkey-patch) API-të globale asinkrone të shfletuesit -setTimeout,setInterval,shtoniEventListener,Premtim,XMLHttpKërkesë— kështu që sa herë që një nga këto API përfundon një operacion, Zone.js e përgjon atë dhe njofton Angular.
Cikli "i përhapur" i zbulimit të ndryshimeve
Kur Zone.js njofton një ngjarje, Angular nuk e diçfarë saktësishtai ka ndryshuar - ai thjesht e di këtëdiçka, diku, mund të ketë ndryshuar. Përgjigja është të kontrolloni përsëri të gjithë pemën përbërëse nga lart poshtë (kontrolli i pisët), duke krahasuar vlerat në shabllone me ato të dhëna më parë:
// Semplificato: cosa succede concettualmente dopo OGNI evento asincrono
zone.onMicrotaskEmpty.subscribe(() => {
applicationRef.tick(); // ricontrolla l'intero albero dei componenti
});
Kjo është arsyeja pse, historikisht, një singleklikoninë një buton në një cep të aplikacionit mund të bëjë që komponentët krejtësisht të palidhur diku tjetër në pemë të rishikohen -ChangeDetectionStrategy.OnPushzbut problemin (kapërcen nënpemët e të cilëve@Input()nuk ndryshohen me referencë), por nuk e eliminon atë: Zone.js ende vazhdon të aktivizojë një qark kontrolli në çdo ngjarje të vetme asinkrone, pavarësisht nëse ajo çon në një ndryshim aktual.
Kufijtë strukturorë të Zonës.js
Zone.js funksionoi mirë si një zgjidhje "e vetme për të gjithë", por qasja e saj ka probleme që nuk mund të zgjidhen me optimizime në rritje:
1. Paketa dhe koha e ekzekutimit
Zone.js peshon rreth 30-35 KB (minuar) në paketën fillestare – një kosto fikse për çdo aplikacion Angular, pavarësisht se sa e përdor aktualisht funksionalitetin e tij. Në kohën e ekzekutimit, rregullimi i majmunëve për çdo API asinkron prezanton shpenzime të larta të matshme në çdo telefonatë individuale, edhe kur kjo nuk çon në asnjë ndryshim real në UI.
2. Zbulimi jo selektiv i ndryshimit
Zone.js e diSediçka ka ndodhur, por ai nuk e diÇfarë. Rezultati është një qark kontrolli që në shumicën e rasteve kontrollon shumë më tepër se sa është e nevojshme - madje edhe meOnPushaktive kudo, çdo ngjarje asinkrone ende shkakton një raund verifikimi në të gjithë pemën e përfshirë potencialisht.
3. Brishtësia me bibliotekat e palëve të treta
Rregullimi global i majmunëve të API-ve siPremtimosemarrmund të ndërveprojë në mënyrë të paparashikueshme me bibliotekat që nuk presin që këto API të rishkruhen në kohën e ekzekutimit - është një shkak i zakonshëm dhe i vështirë për t'u diagnostikuar i gabimeve të përhershme në aplikacionet e mëdha Angular.
4. Korrigjimi më kompleks
Gjurmët e stivës përshkojnë kodin korrigjues të Zone.js, duke e bërë më të vështirë gjurmimin e burimit të vërtetë të një gabimi asinkron - këdo që ka korrigjuar një të tillëRefuzimi i Premtimit të Patrajtuarnë një aplikacion të madh Angular e di këtë problem.
Çfarë ndryshojnë sinjalet
Sinjalet përmbysin modelin: në vend që "diçka ka ndodhur diku, kontrolloni gjithçka përsëri", vetë të dhënat e dinëPikërishtkush varet prej tij, sepse varësia regjistrohet shprehimisht në momentin e leximit:
import { signal, computed, effect } from '@angular/core';
const count = signal(0);
const doubled = computed(() => count() * 2); // dipendenza tracciata automaticamente
effect(() => {
console.log('Il valore doppio è', doubled());
// questo effect si ri-esegue SOLO quando doubled() cambia realmente,
// non ad ogni evento asincrono dell'applicazione
});
count.set(5); // notifica solo i consumer reali: doubled, e l'effect
Kurcount.set (5)quhet, Angular e di saktësisht se cilati llogaritur, e cilaefektdhe nga cilat lidhje shabllone varen atonumëroj— Nuk ka nevojë të kontrolloni dy herë të gjithë pemën përbërëse, sepse grafiku i varësisë tashmë dihet paraprakisht.
Zone.js vs Sinjalet: krahasimi i drejtpërdrejtë
| Unë pres | Zone.js (zbulimi klasik i ndryshimeve) | Sinjalet |
|---|---|---|
| Si i dallon ndryshimet | Përgjoni çdo API asinkron global | Gjurmimi i qartë i varësive të leximit |
| Çfarë kontrolloni dy herë | E gjithë pema (ose nënpema me OnPush) | Vetëm konsumatorët që janë në të vërtetë të varur |
| Pako sipër | ~ 30-35 KB fikse | Të përfshira në bazë, pa kosto shtesë |
| Pajtueshmëria me bibliotekat e palëve të treta | Rreziku i konflikteve nga arnimi i majmunit | Nuk ka nevojë për korrigjim global |
| Parashikueshmëria e korrigjimit | Gjurmët e rafte arnimi kryq | Rrjedha e varësisë e qartë dhe e gjurmueshme |
| Kurba e adoptimit | Punon "falas" që nga dita e parë | Kërkon rifaktorim të gjendjes ekzistuese |
Çfarë do të thotë "pa zonë këndore" në praktikë
Pa zonë këndore nuk do të thotë vetëm "përdor sinjale në komponentë" - do të thotëhiqni Zone.js farenga pakoja dhe besojini të gjithë zbulimin e ndryshimit në grafikun e reaktivitetit të sinjaleve. Ai aktivizohet me një ofrues të dedikuar gjatë fazës së bootstrap:
import { bootstrapApplication } from '@angular/platform-browser';
import { provideZonelessChangeDetection } from '@angular/core';
bootstrapApplication(AppComponent, {
providers: [
provideZonelessChangeDetection(),
// ...altri provider
],
});
Pasi Zone.js të hiqet, Angular nuk ka më asnjë mënyrë "automatike" për të vërejtur një ndryshim të përgjithshëm -Gjithçka është në rregullgjendja që duhet të pasqyrohet në UI duhet të kalojë në mënyrë eksplicite përmes një sinjali (ose aChangeDetectorRef.markForCheck()manual në raste ekstreme). Kjo është arsyeja pse migrimi nuk është një flamur i thjeshtë për t'u aktivizuar, por një ndryshim i vërtetë paradigme në menaxhimin e shtetit.
Udhëzues praktik: migroni një aplikacion në pa zona
1. Kontrolloni mbulimin tuaj OnPush
Nëse aplikacioni ende përdorChangeDetectionStrategy.Defaultnë shumë komponentë, është shenja e parë që gjendja nuk menaxhohet në mënyrë eksplicite - kaloni gjithçkaOnPushështë një parakusht praktik para se të hiqni Zone.js.
2. Zëvendësoni gjendjen "të nënkuptuar" me Sinjalet
// Prima: proprietà di classe normale, aggiornata via mutazione diretta
export class CartComponent {
itemCount = 0;
addItem(): void {
this.itemCount++; // senza Zone.js, la UI non si aggiornerebbe
}
}
// Dopo: signal, aggiornamento esplicito e tracciato
export class CartComponent {
itemCount = signal(0);
addItem(): void {
this.itemCount.update(n => n + 1); // il template si aggiorna automaticamente
}
}
3. Kontrolloni bibliotekat e palëve të treta
Disa biblioteka (veçanërisht përbërës të vjetër të palëve të treta ose kodi që supozon në mënyrë implicite praninë e Zone.js për të "zgjuar" Angular pas një ngjarjeje) mund të ndalojnë përditësimin e saktë të ndërfaqes së përdoruesit në modalitetin pa zona. Ato duhet të testohen individualisht, ose të mbështillen në njëmarkForCheck()manual në pikat e integrimit.
4. Hiq Zone.js nga paketa
Pasi të jetë verifikuar që e gjithë gjendja kalon përmes Sinjaleve (ose zbulimit të qartë manual të ndryshimit), Zone.js mund të hiqet nga varësitë dhe skedari polifill, duke reduktuar paketën fillestare.
Kur NUK është ende e përshtatshme të shkosh pa zona
- Aplikacione me shumë varësi të vjetëruara nga palët e treta: Nëse bibliotekat kritike supozojnë praninë e Zone.js, migrimi kërkon testim të gjerë rast pas rasti.
- Baza kodesh shumë të mëdha me gjendje të menaxhuar në mënyrë të pabarabartë: nëse gjendja shpërndahet midis veçorive të klasës me mutacion të drejtpërdrejtë, shërbimeve me RxJS të pa integruara me Sinjalet dhe logjikës së trashëguar, rifaktorimi i nevojshëm është thelbësor.
- Ekipet e panjohura me Sinjalet: Zoneless amplifikon çdo boshllëk në menaxhimin e qartë të gjendjes — ia vlen të forconi njohuritë tuaja për Sinjalet fillimisht me Zone.js ende aktive si një rrjet sigurie.
Pyetjet e bëra shpesh
A duhet të heq Zone.js për të përdorur Sinjalet?
Jo, Sinjalet funksionojnë në mënyrë perfekte edhe me Zone.js ende aktive — është hapi i ndërmjetëm më i zakonshëm: fillimisht miratoni Sinjalet për gjendjen, më pas (opsionale) hiqni Zone.js kur mbulimi të përfundojë.
A zëvendësojnë sinjalet RxJS në Angular?
Jo, ato mbulojnë raste të ndryshme përdorimi: Sinjalet janë krijuar për gjendjen sinkrone lokale të komponentëve, RxJS mbetet mjeti i duhur për flukset komplekse asinkrone (kërkesat HTTP, WebSockets, kombinimi i ngjarjeve të shumta me kalimin e kohës). Shërbimet komunaletoSignal ()Dheshumë e vëzhgueshme ()lejojnë të dy modelet të bashkëjetojnë.
A është Zoneless gati ende për prodhim?
Mbështetja pa zona është e qëndrueshme në versionet e fundit të Angular, por kërkon që i gjithë aplikacioni (duke përfshirë bibliotekat e palëve të treta në përdorim) të jetë i pajtueshëm me një model të qartë të zbulimit të ndryshimeve - ai duhet të vlerësohet rast pas rasti, nuk është një ndërprerës i thjeshtë universal.
Çfarë ndodh nëse harroj të përdor një sinjal për një gjendje që duhet të përditësojë UI?
Në modalitetin pa zona, UI thjesht nuk përditësohet derisa të ndodhë një tjetër shkaktar i zbulimit të ndryshimit (p.sh. një ngjarje shabllon) - është një gabim i heshtur, prandaj migrimi kërkon testim të gjerë në çdo rrjedhë.
A përmirësojnë sinjalet performancën edhe pa shkuar pa zona?
Po: edhe me Zone.js ende aktive, lidhjet e bazuara në sinjale në shabllone lejojnë Angular të përditësojë vetëm nyjet DOM të varura në të vërtetë, duke reduktuar punën e interpretimit në krahasim me lidhjet klasike.
A duhet të rishkruaj të gjithë aplikacionin për të miratuar Sinjalet?
Jo, sinjalet dhe gjendja "klasike" mund të bashkëjetojnë në të njëjtin komponent dhe aplikacion - mund të migroni gradualisht, komponent pas komponenti.
Në përmbledhje
Zone.js ka lejuar Angular të ofrojë zbulimin automatik të ndryshimeve "falas" që nga dita e parë, por çmimi është një model që kontrollon dyfish shumë më tepër sesa i nevojitet, me një kosto fikse të paketës dhe një brishtësi të njohur në integrimin me bibliotekat e palëve të treta. Sinjalet e zgjidhin problemin në rrënjë, duke gjurmuar varësitë në mënyrë eksplicite në vend që të përgjojnë çdo ngjarje asinkrone të shfletuesit – dhe i hap rrugën një Angular pa zona që është më i lehtë dhe më i parashikueshëm për korrigjim. Nëse po mendoni se kur të përdorni Sinjalet kundrejt RxJS në menaxhimin e përditshëm të shtetit, ky udhëzues lidhet drejtpërdrejt meSinjalet këndore vs RxJS: kur të përdoret njëra dhe kur tjetra.