The playground

More information here

Jevnere UX På Sidebelastning med Vinkeloppløsere

som utvikler er du alltid ute etter å optimalisere koden din. Dette inkluderer hastigheten som du presentere brukeren med fullastet UI, som ofte er avhengig av data som kommer fra en database. Uunngåelig, du begynner å lete etter måter å løse data umiddelbart etter navigasjon til en ny side / område av søknaden din, uten […]

som utvikler er du alltid ute etter å optimalisere koden din. Dette inkluderer hastigheten som du presentere brukeren med fullastet UI, som ofte er avhengig av data som kommer fra en database.

Uunngåelig, du begynner å lete etter måter å løse data umiddelbart etter navigasjon til en ny side / område av søknaden din, uten at brukeren møter det som kalles page JANK.

dette er når siden beveger seg opp og ned mens du laster inn bestemte komponenter. DET kan påvirke UX betydelig til det punktet der det ser ‘buggy’ut.

Angular gir en intuitiv tilnærming til forhåndshenting av data før ruten lastes; før den navigerte ruten løses.

Det kalles En Vinkel Resolver.

En Vinkel Resolver er i hovedsak En Vinkel Tjeneste. En injiserbar klasse som du oppgir til en rutemodul i rutekonfigurasjonen. Denne spesielle typen tjeneste injiseres og utføres når den inneholdende ruten navigeres til.

Resolveren løser deretter dataene før sidebelastningen, som blir tilgjengelig viaActivatedRoute – tjenesten. Dette gir en enkel og effektiv måte å sikre at brukeren har dataene så raskt som mulig før en komponent som er viktig for den første sidebelastningen, trenger den.En Annen måte å bruke En Vinkel Resolver er ved å bruke den som en metode for å fylle SEO metadata umiddelbart.

med en resolver gir du en garanti for at data vil eksistere før siden lastes, slik at alt har det som trengs ved initialisering.

la oss bryte Ned Vinkel Resolver

En Vinkel resolver er en klasse som implementererResolve grensesnitt. GrensesnittetResolve krever at du implementerer en funksjon i klassen kalt resolve.

Her Er Løs grensesnitt signatur…

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

som vi kan se fra grensesnittet signatur, krever det et generisk argumentT som vil være typen av våre løste data.

løs-funksjonen returnerer enObservablePromise eller bare dataene av typenT . Derfor er det et forslag om at dette skal håndteres asynkront, spesielt hvis du henter dataene fra databasen.

hovedformålet med løsefunksjonen er at den må fullføres. Dette faktum må huskes når du henter data i observerbare data. Det observerbare må fullføres. Tross alt er det en resolver.

hvis den observerbare ikke fullfører, vil dataene aldri løse, og siden vil aldri lastes inn. Derfor må du definere punktet der du ikke trenger å ta flere verdier, og dataene kan løse, da du har alt du trenger fra databasen. Når du bruker asynkrone datastrømmer som observables, er dette et brukstilfelle for rørbare operatører FRA RXJS.

de pipeable operatørene som dukker opp når du tenker på å fullføre en datastrøm basert på en tilstand, er en kombinasjon av filtertakefirst . Med denne kombinasjonen kan du filtrere alle verdier du ikke vil ta, for eksempel null eller undefined eller en tom matrise , deretter take den første gyldige verdien med take(1).

Operatorer som kan være nødvendige for å fullføre en observerbar tidlig når det oppstår problemer eller feil, der du vil returnere null eller omdirigere, er catchError og timeout . En kombinasjon av timeout og catchError er nyttig hvis dataene dine tar for lang tid, og du vil returnere null slik at du kan prøve igjen inne i komponenten, eller du vil omdirigere.

hvis dataene dine ikke løses raskt, er basert på komplisert filtrering, logikk, store mengder databaseanrop, vil du sannsynligvis oppleve problemer fra tid til annen.

det er best å bestemme minst mulig databaseanrop og minimumsdata som trengs for å kunne laste siden vellykket og grasiøst.

Derfor kan du ha nytte av å bruke litt tid, før du implementerer resolveren din, for å fokusere på å skille ‘over fold’ – innholdet fra data som kan lastes inn når siden initialiseres.

derfor kan du dele dataene som er nødvendige for en jevn UX, fra resten av dataene som kan kalles fra komponenten, i stedet for resolveren.

du kan da utelukkende håndtere det minimale, over brettet, innholdet gjennom resolveren.

denne dynamiske tilnærmingen til sideinnlasting kan assisteres ved bruk av skjeletter. Slik at hvis brukeren ruller ned umiddelbart, kan du gi brukeren indikasjonen på at innholdet lastes, og deretter forbedre UX.

Trinn 1: Opprette Resolveren

Vi må opprette Vinkeloppløsningen. Det er imidlertid ikke En Vinkel CLI-kommando som genererer en resolver. Derfor må vi skrive dekoratøren (resolver metadata) oss selv.Heldigvis er Det Bare noen få linjer med kode som danner boilerplate for en resolver, og vi kan ta injiserbar dekoratør fra en eksisterende tjeneste hvis du sliter med å huske det.

Merk Profiloppløserklassen med en injiserbar dekoratør

Først gir vi injiserbar dekoratør med providedIn: any i konfigurasjonen.

@Injectable({ providedIn: 'any'})

vi vil da nevne vår resolver ved å legge til konvensjonen Resolver. For dette eksemplet vil vi løse profildata (brukerdata), så vi vil kalle det ProfileResolver .

Som det er en resolver, og Angular gjenkjenner funksjonen til resolvere, kan vi implementereResolve – klassen, som vil gi signaturen som vi må implementere i vår løsefunksjon for å kunne løse dataene.

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

vår løsefunksjon vil returnere En Observerbar med data som samsvarer medProfile – grensesnittet. Derfor vil vi giProfile – grensesnittet som det generiske argumentet til resolver-klassen ogresolve() – funksjonen. På denne måten har vi tilpasset Vinkelkrav for en resolver.

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

løs implementering gir oss to parametere hvis de trengs, routeogstate. Disse fylles automatisk ut og er tilgjengelige fra vår resolve() – funksjon.

Neste må vi faktisk løse ekte data fra databasen, som blir vårt neste skritt.

Henter dataene fra databasen

for å hente dataene for vår løsefunksjon må vi injisere tjenesten som gir dataene; en som samhandler med databasen.

vi tar det vi trenger fra det for å løse raskt slik at brukeren navigerer raskt og vellykket. I forbindelse med denne demoen vil vi ikke bekymre oss for den underliggende tjenesten som omhandler databasen. Vi vil bare injisere tjenesten ved hjelp av avhengighetsinjeksjon i konstruktørargumentet for vår ProfileResolver klasse.

som våre data kommer i form av En Observerbar datastrøm med flere verdier som sender asynkront, trenger vi bare åtake(1) ved hjelp av rørbar operatørtake importert frarxjs/operator . Ellers ville det observerbare aldri fullføre, og resolveren ville aldri…løse.

Vi trenger bare en emisjon/verdi ogtake fullfører det observerbare for oss.

det er så enkelt som å lage en resolver; vi trenger bare å returnere den observerbare iresolve() funksjonen som angular vil håndtere abonnementet på.

ProfileResolver-Klassen

vi håndterer eventuelle feil ved å hente dataene ved å omdirigere til en overordnet rute.

Bonus: Fylle Dynamisk SEO metadata raskt før ruten har lastet

fordelene ved å fylle vår <meta> tags umiddelbart har åpenbare fordeler. Jo raskere VÅRE SEO metadata er befolket, jo raskere VÅR SEO riktig og nøyaktig gjenspeiler sideinnholdet.

dette betyr at det er enklere og raskere for roboter, som de som drives Av søkemotorer Som Google og Bing, å gjennomgå nettstedet ditt og hente innholdet.

Dette er ikke så viktig på pre-rendret sider eller de som er gjengitt Av Angular Universal, fordi alle gjengivelsen er fullført før robotene mottar innholdet.

men hvis du er avhengig av (ofte tvilsom) evne for google robots å analysere javascript FOR SEO, eller du har en on-demand løsning som puppeteer som trenger forsikring OM AT SEO vil være riktig før du returnerer gjengitt DOM, så en resolver som inkluderer SEO bør hjelpe. Så det hjelper når crawleren er tidsbegrenset.

det skiller også bekymringer fra komponenten, slik at komponenten ikke trenger å håndtere NOE SEO relatert. En av de viktigste grunnene til at jeg liker resolvers.

Trinn 2: Injiser resolveren i rutemodulen

ProfileRoutingModule hvor Vi skal gi vår resolver er en lat lastet modul. Derfor vil vår rotbane være tom med parameteren token userSlug, som vi må hente de riktige profildataene.

for å gi vår resolver, gir vi bare et objekt med navnet på våre data som nøkkel og den spesifikke resolveren som verdien som vil være ansvarlig for å løse disse dataene.

du kan navngi nøkkelen alt du liker, men vi kaller det bare data.

Vår ProfileRoutingModule

det er alt som kreves i rutemodulen for at vi skal kunne bruke vår resolver.

Deretter må vi hente og bruke dataene våre i komponenten.

Trinn 3: Initialiser komponenten med løst data

Nå som vi har løst dataene våre på ruteaktivering, er dataene tilgjengelige via ActivatedRoute – Tjenesten. Som vi har å gjøre med observables, gjennom hele programmet, vil vi lage en strøm som binder seg tildata eiendom som vil være vår løst data.

først injiserer viActivatedRoute i konstruktøren av vår ProfileComponent. Deretter tilordner vithis.route.data tilprofile$ observerbar. Vi vil også bytte til å bruke en observerbar når oppdaterte data kommer fra databasen, slik at vi har ferske data når vi samhandler med appen.

for dette bruker vi startWith slik at vi starter strømmen med verdien som er lett tilgjengelig fra this.route.snapshot.data. Vi får da tilgang tildata eiendom som this.route.snapshot.datastartWith indikerer en verdi til å begynne med, som den første utslipp av strømmen vår.

Vår Profilkomponent

Hva umiddelbart tilgjengelige data gjør for komponenten

Umiddelbart tilgjengelige data reduserer tid brukt på å laste de enkelte delene av den siden, som observeres av brukeren. Resultatet av ikke å bruke en resolver som dette er at siden kan synes å laste i en fragmentert måte, som ikke er visuelt tiltalende.

Derfor må du være oppmerksom på hvilke elementer I HTML-malene dine som er avhengige av hvilke data. Du bør da skrive din resolver for å støtte disse elementene og den samlede effekten på siden laster UX.

det er flere måter at komponenten kan laste fragmentert

  • En av disse er hvis du har en ngIf i flere deler AV HTML-malen.
  • En annen er ngFor .

det er best praksis å begrense mengden av individuelle ngIf ‘ s du skriver i den hensikt å begrense mengden av resizing nettleseren har å gjøre.

Lasting av siden før du får dataene, kan føre til at deler av siden din hopper, lagrer og endrer størrelse hele tiden, noe SOM får UX til å lide.Implementering av en resolver kan være forskjellen mellom brukeren opplever 3-5 sekunder med hopping og resizing vs. 0.5 sekunder, som ofte er for rask til å være skadelig for den generelle UX.

Det er det! Vi har en resolver med en forbedret UX på sidebelastning.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert.