The playground

More information here

vloeiender UX bij het laden van pagina ‘ s met hoek Resolvers

als ontwikkelaar bent u altijd op zoek naar het optimaliseren van uw code. Dit omvat de snelheid waarmee u de gebruiker met de volledig geladen UI, die vaak afhankelijk is van gegevens afkomstig uit een database. onvermijdelijk begint u te zoeken naar manieren om gegevens onmiddellijk op te lossen na het navigeren naar een nieuwe […]

als ontwikkelaar bent u altijd op zoek naar het optimaliseren van uw code. Dit omvat de snelheid waarmee u de gebruiker met de volledig geladen UI, die vaak afhankelijk is van gegevens afkomstig uit een database.

onvermijdelijk begint u te zoeken naar manieren om gegevens onmiddellijk op te lossen na het navigeren naar een nieuwe pagina/gebied van uw toepassing, zonder dat de gebruiker geconfronteerd wordt met wat bekend staat als page JANK.

Dit is wanneer de pagina op en neer beweegt tijdens het laden van bepaalde componenten. Het kan een aanzienlijke invloed op de UX tot het punt waar het lijkt ‘buggy’.

Angular biedt een intuïtieve benadering voor het vooraf ophalen van gegevens voordat de route wordt geladen; voordat de navigatieroute wordt opgelost.

het wordt een hoekresolutie genoemd.

een Angular Resolver is in wezen een Angular Service. Een injecteerbare klasse die u verstrekt aan een routing module in de routeconfiguratie. Dit speciale type dienst wordt geïnjecteerd en uitgevoerd wanneer de bevattende route wordt genavigeerd naar.

de Resolver Lost vervolgens de gegevens op voordat de pagina wordt geladen, die beschikbaar komt via de ActivatedRoute service. Dit biedt een eenvoudige en efficiënte manier om ervoor te zorgen dat uw gebruiker de gegevens zo snel mogelijk voordat een component die belangrijk is voor de eerste pagina belasting zou het nodig hebben.

een andere manier om een hoekige Resolver te gebruiken is door het te gebruiken als een methode om de SEO metadata direct te vullen.

met een resolver geeft u de garantie dat de gegevens bestaan voordat de pagina is geladen, zodat alles heeft wat het nodig heeft bij initialisatie.

Let ‘ s breakdown de hoek Resolver

een hoek resolver is een klasse die de Resolve interface implementeert. De interface Resolve vereist dat u een functie implementeert binnen de klasse genaamd resolve.

Hier is de Resolve interface signature …

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

zoals we kunnen zien aan de interface signature, vereist het een generiek argument T wat het type van onze opgeloste gegevens zal zijn.

De resolve functie geeft een ObservablePromise of alleen de gegevens van het type T . Daarom is er een suggestie dat dit asynchroon moet worden behandeld, vooral bij het ophalen van de gegevens uit de database.

het belangrijkste doel van de resolve-functie is dat deze moet worden voltooid. Dit feit moet worden onthouden bij het ophalen van gegevens in observables. De waarneembare moet voltooien. Het is immers een oplosser.

als de waarneembare niet voltooid is, zullen de gegevens nooit worden opgelost en zal de pagina nooit worden geladen. Daarom moet u het punt definiëren waarop u niet meer waarden hoeft te nemen en de gegevens kunnen oplossen, omdat u alles hebt wat u nodig hebt uit de database. Bij het gebruik van asynchrone datastromen zoals observables, is dit een use case voor pipeable operators van RXJS.

De pipeable operators die te binnen schieten bij het invullen van een datastroom op basis van een voorwaarde, zijn een combinatie van filtertakefirst . Met deze combinatie kunt u alle waarden filteren die u niet wilt nemen, zoals null of undefined of een lege array , dan take de eerste geldige waarde met take(1).

Operators die nodig kunnen zijn om een observable early te voltooien bij problemen of fouten, waarbij u null Of redirect wilt retourneren, zijncatchError entimeout . Een combinatie van timeout en catchError is nuttig als uw gegevens te lang duren en u null wilt retourneren zodat u het opnieuw kunt proberen binnen de component, of u wilt omleiden.

als uw gegevens niet snel worden opgelost, gebaseerd zijn op complexe filtering, logica, enorme hoeveelheden databaseaanroepen, zult u waarschijnlijk van tijd tot tijd problemen ondervinden.

Het is het beste om het minste aantal databaseaanroepen te bepalen, en minimale gegevens die nodig zijn om de pagina succesvol en sierlijk te laden.

daarom kunt u er baat bij hebben om, voordat u uw resolver implementeert, enige tijd te besteden aan het scheiden van de ‘boven de vouw’ – inhoud van gegevens die kunnen worden geladen wanneer de pagina wordt geïnitialiseerd.

daarom kunt u de gegevens die nodig zijn voor een vloeiende UX, scheiden van de rest van de gegevens die kunnen worden aangeroepen vanuit de component, in plaats van de resolver.

u kunt dan uitsluitend omgaan met de minimale, boven de vouw, inhoud via de resolver.

deze dynamische benadering van het laden van pagina ‘ s kan worden ondersteund met het gebruik van skeletten. Zodat als de gebruiker direct naar beneden scrolt, u de gebruiker de indicatie kunt geven dat de inhoud wordt geladen, waarna UX wordt verbeterd.

Stap 1: Het maken van de Resolver

We moeten de hoekige Resolver maken. Er is echter geen hoekige CLI-opdracht die een resolver genereert. Daarom zullen we de decorateur (resolver metadata) zelf moeten schrijven.

gelukkig zijn het slechts een paar regels code die de standaardtekst voor een resolver vormen, en we kunnen de injecteerbare decorator van een bestaande service nemen als je moeite hebt om het te onthouden.

annoteer de Profile Resolver class met een injecteerbare decorateur

eerst bieden we de injecteerbare decorateur met providedIn: any in de configuratie.

@Injectable({ providedIn: 'any'})

We zullen dan onze resolver een naam geven door de conventie toe te voegen Resolver . In dit voorbeeld zullen we profielgegevens (gebruikersgegevens) oplossen, dus noemen we het ProfileResolver .

aangezien het een resolver is, en Angular de functie van resolvers herkent, kunnen we de klasse Resolve implementeren, die de handtekening zal leveren die we moeten implementeren in onze resolve-functie om de gegevens succesvol op te lossen.

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

onze resolve functie retourneert een waarneembare met gegevens conform de Profile interface. Daarom zullen we de Profile interface als het algemene argument voor de resolver klasse en de resolve() functie. Op deze manier hebben we voldaan aan de Hoekvereisten voor een resolver.

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

De resolve-implementatie geeft ons twee parameters als ze nodig zijn, route en state . Deze worden automatisch ingevuld en zijn toegankelijk vanuit onze resolve() functie.

vervolgens moeten we echte gegevens uit de database oplossen, wat onze volgende stap zal zijn.

de gegevens uit de database ophalen

om de gegevens voor onze resolve-functie op te halen, moeten we de service injecteren die de gegevens levert; een die interageert met de database.

We nemen wat we nodig hebben om snel op te lossen, zodat de gebruiker snel en succesvol navigeert. In het kader van deze demo, zullen we ons geen zorgen maken over de onderliggende dienst die zich bezighoudt met de database. We zullen de service gewoon injecteren met dependency injection in het constructor argument voor onze ProfileResolver klasse.

aangezien onze gegevens in de vorm van een waarneembare datastroom komen met meerdere waarden die asynchroon uitzenden, hoeven we alleen maar take(1) te gebruiken met behulp van de pipeable operator take geïmporteerd uit rxjs/operator . Anders zou het waarneembare nooit compleet zijn, en de resolver zou nooit…oplossen.

we hebben slechts één emissie/waarde nodig en take voltooit de waarneembare waarde voor ons.

het is zo eenvoudig om een resolver aan te maken; we hoeven alleen de waarneembare terug te geven in de resolve() functie die angular het abonnement van afhandelt.

de ProfileResolver Class

We behandelen eventuele fouten bij het ophalen van de gegevens door om te leiden naar een bovenliggende route.

Bonus: Dynamische SEO-metadata snel invullen voordat de route

geladen heeft de voordelen van het invullen van onze <meta> tags hebben direct duidelijke voordelen. Hoe sneller onze SEO metadata wordt ingevuld, hoe sneller onze SEO correct en nauwkeurig de inhoud van de pagina weergeeft.

Dit betekent dat het gemakkelijker en sneller is voor robots, zoals die worden bediend door zoekmachines zoals Google en Bing, om uw site te doorzoeken en de inhoud op te halen.

Dit is niet zo belangrijk op vooraf gerenderde pagina ’s of pagina’ s die door Angular Universal worden gerenderd, omdat alle rendering voltooid is voordat de robots de inhoud ontvangen.

echter, als je vertrouwt op de (vaak twijfelachtige) mogelijkheid voor google robots om javascript te ontleden voor uw SEO, of je hebt een on-demand oplossing zoals puppeteer die de zekerheid nodig heeft dat de SEO correct zal zijn voordat u de gerenderde DOM retourneert, dan moet een resolver die SEO bevat helpen. Dus het helpt als de crawler in de tijd beperkt is.

het scheidt ook zorgen van de component, zodat de component niet te maken heeft met iets SEO gerelateerd. Een van de belangrijkste redenen waarom ik graag resolvers.

Stap 2: injecteer de resolver in de routeringsmodule

De ProfileRoutingModule waarin we onze resolver aanbieden is een lazy loaded module. Daarom zal ons rootpad leeg zijn met de parameter token userSlug , die we nodig hebben om de juiste profielgegevens op te halen.

om onze resolver aan te bieden, geven we alleen een object met de naam van onze gegevens als sleutel en de specifieke resolver als de waarde die verantwoordelijk is voor het oplossen van die gegevens.

u kunt de sleutel alles noemen wat u wilt, maar we noemen het gewoon data.

onze ProfileRoutingModule

dat is alles wat nodig is in de routeringsmodule om onze resolver te gebruiken.

vervolgens moeten we onze gegevens ophalen en gebruiken in de component.

Stap 3: Initialiseer de component met opgeloste gegevens

nu we onze gegevens over routeactivering hebben opgelost, zijn de gegevens toegankelijk via de ActivatedRoute Service. Aangezien we te maken hebben met observables, zullen we gedurende de hele toepassing een stream maken die bindt aan de eigenschap data die onze opgeloste gegevens zal zijn.

eerst injecteren we de ActivatedRoute in de constructor van onze ProfileComponent . Vervolgens zullen we this.route.data toewijzen aan de profile$ waarneembaar. We willen ook overschakelen naar het gebruik van een waarneembare wanneer bijgewerkte gegevens uit de database komen, zodat we verse gegevens hebben wanneer we interactie hebben met de app.

hiervoor gebruiken we startWith zodat we onze stream starten met de waarde die gemakkelijk toegankelijk is vanuit this.route.snapshot.data. We benaderen vervolgens de eigenschap data zoals this.route.snapshot.datastartWith geeft een waarde aan om mee te beginnen, als de eerste emissie van onze stroom.

onze Profielcomponent

wat direct toegankelijke data doet voor de component

direct toegankelijke data vermindert de tijd die wordt besteed aan het laden van de afzonderlijke delen van die pagina, die door de gebruiker wordt waargenomen. Het resultaat van het niet gebruiken van een resolver als deze is dat de pagina kan lijken te laden in een gefragmenteerde manier, wat niet visueel aangenaam is.

daarom moet u letten op welke elementen van uw HTML-sjablonen afhankelijk zijn van welke gegevens. Je moet dan je resolver schrijven om deze elementen en het totale effect op het laden van pagina ‘ s UX te ondersteunen.

er zijn meerdere manieren waarop het component gefragmenteerd

  • kan laden een van deze manieren is als u een ngIf in meerdere delen van uw HTML-sjabloon hebt.
  • een andere is ngFor .

Het is het beste om de hoeveelheid individuele ngIf ’s die u schrijft te beperken met het oog op het beperken van de hoeveelheid grootte van de browser moet doen.

Het laden van de pagina voor het verkrijgen van de gegevens kan ertoe leiden dat delen van uw pagina te springen, vertraging en de grootte voortdurend, waardoor de UX te lijden.

het implementeren van een resolver kan het verschil zijn tussen de gebruiker die 3-5 seconden van springen en resizen ervaart vs.0,5 seconden, wat vaak te snel is om schade toe te brengen aan de totale UX.

dat is het! We hebben een resolver met een verbeterde UX op pagina load.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.