The playground

More information here

jævnere på sidebelastning med Vinkelopløsere

som udvikler søger du altid at optimere din kode. Dette inkluderer den hastighed, hvormed du præsenterer brugeren med det fuldt indlæste brugergrænseflade, som ofte afhænger af data, der kommer fra en database. uundgåeligt begynder du at lede efter måder at løse data straks efter navigation til en ny side / område i din applikation, uden […]

som udvikler søger du altid at optimere din kode. Dette inkluderer den hastighed, hvormed du præsenterer brugeren med det fuldt indlæste brugergrænseflade, som ofte afhænger af data, der kommer fra en database.

uundgåeligt begynder du at lede efter måder at løse data straks efter navigation til en ny side / område i din applikation, uden at brugeren støder på det, der kaldes page JANK.

Dette er, når siden bevæger sig rundt op og ned under indlæsning af visse komponenter. Det kan i væsentlig grad påvirke den til det punkt, hvor det ser ‘buggy’.

Angular giver en intuitiv tilgang til forudhentning af data, før ruten indlæses; før den navigerede rute løser.

det kaldes en Vinkelopløser.

en Vinkelopløser er i det væsentlige en Vinkeltjeneste. En injicerbar klasse, som du leverer til et rutemodul i rutekonfigurationen. Denne særlige type tjeneste injiceres og udføres, når den indeholdende rute navigeres til.

Resolveren løser derefter dataene før sidebelastningen, som bliver tilgængelig viaActivatedRoute service. Dette giver en enkel og effektiv måde at sikre, at din bruger har dataene så hurtigt som muligt, før en komponent, der er vigtig for den oprindelige sideindlæsning, har brug for dem.

en anden måde at bruge en Vinkelopløser på er ved at bruge den som en metode til at udfylde SEO-metadataene med det samme.

med en resolver giver du en garanti for, at data vil eksistere, før siden er indlæst, hvilket sikrer, at alt har det, det har brug for ved initialisering.

lad os nedbryde Vinkelopløseren

en Vinkelopløser er en klasse, der implementererResolve interface. GrænsefladenResolve kræver, at du implementerer en funktion i klassen kaldetresolve.

Her er Resolve interface signature …

export interface Resolve<T> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<T> | Promise<T> | T {
return 'data';
}
}

som vi kan se fra interface signaturen, kræver det et generisk argument T som vil være typen af vores løste data.

resolve-funktionen returnerer enObservablePromiseeller bare dataene af typenT. Derfor er der et forslag om, at dette skal håndteres asynkront, især hvis du henter dataene fra databasen.

hovedformålet med resolve-funktionen er, at den skal udføres. Denne kendsgerning skal huskes, når man henter data i observerbare. Den observerbare skal udfyldes. Det er trods alt en resolver.

Hvis den observerbare ikke fuldføres, løses dataene aldrig, og siden indlæses aldrig. Derfor skal du definere det punkt, hvor du ikke behøver at tage flere værdier, og dataene kan løse, da du har alt hvad du behøver fra databasen. Når du bruger asynkrone datastrømme, såsom observerbare, er dette en brugssag for pipeable operatører.

de rørbare operatører, der kommer til at tænke på, når man tænker på at fuldføre en datastrøm baseret på en tilstand, er en kombination affiltertakefirst . Med denne kombination kan du filtrere alle værdier, som du ikke vil tage, såsom null eller undefined eller et tomt array , derefter take den første gyldige værdi med take(1).

operatører, der kan være nødvendige for at fuldføre en observerbar tidligt, når de støder på problemer eller fejl, hvor du vil returnere null eller omdirigere, ercatchError ogtimeout . En kombination af timeout og catchError er nyttig, hvis dine data tager for lang tid, og du gerne vil returnere null så du kan prøve igen inde i komponenten, eller du vil omdirigere.

Hvis dine data ikke løser hurtigt, er baseret på kompleks filtrering, logik, enorme mængder databaseopkald, vil du sandsynligvis opleve problemer fra tid til anden.

det er bedst at bestemme det mindste antal databaseopkald og minimale data, der er nødvendige for at kunne og yndefuldt indlæse siden.

derfor kan du med fordel bruge lidt tid, før du implementerer din resolver, til at fokusere på at adskille indholdet ‘over folden’ fra data, der kan indlæses, når siden initialiseres.

derfor kan du opdele de data, der er nødvendige for en jævn hastighed, fra resten af de data, der kunne kaldes fra komponenten, snarere end resolveren.

Du kan derefter udelukkende håndtere det minimale, over folden, indhold gennem resolveren.

denne dynamiske tilgang til sideindlæsning kan hjælpes med brugen af skeletter. Så hvis brugeren ruller ned med det samme, kan du give brugeren en indikation af, at indholdet indlæses, og derefter forbedre den.

Trin 1: Oprettelse af Resolveren

Vi skal oprette Vinkelopløseren. Der er dog ikke en vinkel CLI-kommando, der genererer en resolver. Derfor bliver vi nødt til at skrive dekoratøren (resolver metadata) selv.

heldigvis er det kun et par kodelinjer, der danner kedelpladen til en resolver, og vi kan tage den injicerbare dekoratør fra en eksisterende service, hvis du kæmper for at huske det.

Kommenter Profilopløsningsklassen med en injicerbar dekoratør

først giver vi den injicerbare dekoratør providedIn: any i konfigurationen.

@Injectable({ providedIn: 'any'})

Vi vil så navngive vores resolver ved at tilføje konventionenResolver. I dette eksempel løser vi profildata (brugerdata), så vi kalder det ProfileResolver .

da det er en resolver, og Angular genkender funktionen af resolvere, kan vi implementereResolve klasse, som vil give den signatur, som vi skal implementere i vores resolve-funktion for at løse dataene med succes.

@Injectable({providedIn: 'any'})
export class ProfileResolver implements Resolve<Profile> {
}

vores løsningsfunktion returnerer en observerbar med data, der er i overensstemmelse medProfile interface. Derfor vil vi give Profile interface som det generiske argument til resolver-klassen og resolve() funktion. På denne måde har vi overholdt Vinkelkravene til en resolver.

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<T> | Promise<T> | T {
return;
}

løs implementering giver os to parametre, hvis de er nødvendige,route ogstate . Disse udfyldes automatisk og er tilgængelige fra vores resolve() funktion.

Dernæst skal vi faktisk løse reelle data fra databasen, hvilket vil være vores næste skridt.

hentning af dataene fra databasen

for at hente dataene til vores løsningsfunktion skal vi injicere den service, der leverer dataene; en der interagerer med databasen.

Vi tager det, vi har brug for, for at løse det hurtigt, så brugeren navigerer hurtigt og med succes. Med henblik på denne demo vil vi ikke bekymre os om den underliggende tjeneste, der beskæftiger sig med databasen. Vi vil bare injicere tjenesten ved hjælp af afhængighedsinjektion i konstruktørargumentet for vores ProfileResolver klasse.

da vores data kommer i form af en observerbar datastrøm med flere værdier, der udsender asynkront, skal vi baretake(1)ved hjælp af den rørbare operatørtakeimporteret frarxjs/operator. Ellers ville den observerbare aldrig fuldføre, og resolveren ville aldrig…løse.

Vi har bare brug for en emission/værdi og take fuldender det observerbare for os.

det er så simpelt som at oprette en resolver; vi skal bare returnere den observerbare i resolve() funktion, som angular vil håndtere abonnementet på.

ProfileResolver-klassen

Vi håndterer eventuelle fejl ved at hente dataene ved at omdirigere til en overordnet rute.

Bonus: Udfyld dynamiske SEO-metadata hurtigt, før ruten er indlæst

fordelene ved at udfylde vores <meta> tags har øjeblikkeligt åbenlyse fordele. Jo hurtigere vores SEO-metadata udfyldes, jo hurtigere afspejler vores SEO korrekt og nøjagtigt sideindholdet.

det betyder, at det er nemmere og hurtigere for robotter, som dem, der drives af søgemaskiner som Google og Bing, at gennemgå din hjemmeside og hente indholdet.

Dette er ikke så vigtigt på præ-renderede sider eller dem, der gengives af Angular Universal, fordi al gengivelsen er færdig, før robotterne modtager indholdet.

men hvis du stoler på den (ofte tvivlsomme) evne til google-robotter til at analysere javascript til din SEO, eller du har en On-demand løsning som puppeteer, der har brug for sikkerhed for, at SEO vil være korrekt, før du returnerer den gengivne DOM, skal en resolver, der inkluderer SEO, hjælpe. Så det hjælper, når larven er tidsbegrænset.

det adskiller også bekymringer fra komponenten, så komponenten ikke behøver at beskæftige sig med noget SEO-relateret. En af hovedårsagerne til, at jeg kan lide resolvers.

Trin 2: indsprøjt resolveren i routingmodulet

ProfileRoutingModule, hvor vi leverer vores resolver, er et dovent indlæst modul. Derfor vil vores rodsti være tom med parametertokenet userSlug, som vi bliver nødt til at hente de korrekte profildata.

for at give vores resolver giver vi bare et objekt med navnet på vores data som nøglen og den specifikke resolver som den værdi, der er ansvarlig for at løse disse data.

Du kan navngive nøglen alt hvad du vil, men vi kalder det bare data.

vores ProfileRoutingModule

det er alt, hvad der kræves i routingmodulet for os at bruge vores resolver.

Dernæst skal vi hente og bruge vores data i komponenten.

Trin 3: Initialiser komponenten med løst data

nu hvor vi har løst vores data om ruteaktivering, er dataene tilgængelige via ActivatedRoute Service. Da vi har at gøre med observerbare, vil vi i hele applikationen oprette en strøm, der binder til data ejendom, som vil være vores løste data.

først injicerer vi ActivatedRoute i konstruktøren af vores ProfileComponent . Dernæst tildeler vi this.route.datatil profile$ observerbar. Vi vil også gerne skifte til at bruge en observerbar, når opdaterede data ankommer fra databasen, så vi har nye data, når vi interagerer med appen.

til dette bruger vistartWithså vi starter vores strøm med den værdi, der er let tilgængelig frathis.route.snapshot.data. Vi får derefter adgang tildata ejendom somthis.route.snapshot.datastartWith angiver en værdi til at begynde med, som den første emission af vores strøm.

vores Profilkomponent

hvad umiddelbart tilgængelige data gør for komponenten

umiddelbart tilgængelige data reducerer den tid, der bruges på at indlæse de enkelte dele af den side, som observeres af brugeren. Resultatet af ikke at bruge en resolver som denne er, at siden kan synes at indlæse på en fragmenteret måde, hvilket ikke er visuelt behageligt.

derfor skal du være opmærksom på, hvilke elementer i dine HTML-skabeloner der er afhængige af hvilke data. Du skal derefter skrive din resolver for at understøtte disse elementer og den samlede effekt på sideindlæsning.

der er flere måder, hvorpå komponenten kan indlæse fragmenteret

  • en af disse er, hvis du har en ngIf i flere dele af din HTML-skabelon.
  • en anden erngFor .

det er bedste praksis at begrænse mængden af individuellengIf ‘s du skriver med det formål at begrænse mængden af ændring af størrelse, som bro.sereren skal gøre.

indlæsning af siden, før dataene hentes, kan medføre, at dele af din side springer, halter og ændrer størrelse konstant, hvilket får den til at lide.

implementering af en resolver kan være forskellen mellem brugeren, der oplever 3-5 sekunders spring og ændring af størrelse vs. 0.5 sekunder, hvilket ofte er for hurtigt til at være skadeligt for det samlede antal.

det er det! Vi har en resolver med en forbedret hastighed på sideindlæsning.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.