Angular Universal In de praktijk – Hoe SEO-vriendelijke Single Page Apps te bouwen met Angular

Er is de laatste maanden veel gepraat over Angular en hoe het te gebruiken om client-apps te bouwen, maar een van de belangrijkste innovaties ervan gebeurt eigenlijk op de server.

Dit is een technologie die zou kunnen helpen een heel nieuw type webapplicaties mogelijk te maken: Angular Universal. Laten we er meer over te weten komen! Laten we de volgende onderwerpen doornemen:

  • Voordelen van single page apps
  • Waarom gebruiken we dan niet overal single page apps?
  • Inzicht in de SEO implicaties van een single page app
  • Wat is Angular Universal, wat maakt het mogelijk?
  • Server-side rendering is echt niet alleen renderen op de server
  • Een demo van een server-side rendered single page app in actie
  • Pre-rendering bij het bouwen – upload pre-rendered apps naar Amazon S3
  • De killer feature van Angular Universal: Dependency Injection
  • Conclusies

Deze post is een introductie tot Angular Universal. Voor een meer gedetailleerde gids over hoe het in de praktijk te gebruiken, bekijk deze post:

Angular Universal: a Complete Practical Guide

Voordelen van Single Page Applications

Single page apps zijn er al een tijdje, en frameworks zoals Angular, React of Ember zijn waarschijnlijk de Javascript bibliotheken die de meeste aandacht krijgen in de Javascript wereld.

De voordelen van SPA’s zijn eigenlijk maar

De voordelen van single page apps zijn potentieel vele:

  • wanneer de gebruiker op de pagina navigeert, worden slechts delen ervan vervangen, wat zorgt voor een meer vloeiende ervaring
  • Na de eerste lading van de pagina gaat alleen data over de draad wanneer de gebruiker door de app navigeert: JSON wordt aan de browser geleverd en rechtstreeks op HTML-sjablonen toegepast
  • dit leidt tot betere prestaties en opent de mogelijkheid om die backend-diensten voor andere dingen te gebruiken, omdat ze alleen gegevens retourneren

We kunnen dit tot slechts één ding terugbrengen:

Single Page Apps kunnen een veel betere gebruikerservaring bieden!

En gebruikerservaring is van cruciaal belang in de openbare internetwereld. Er zijn talloze onderzoeken die onomstotelijk aantonen dat het aantal pagina’s dat niet wordt geladen en het aantal gebruikers dat de pagina verlaat zeer snel toeneemt naarmate de pagina langer wordt geladen.

Als het 200 ms langer duurt voordat een pagina is geladen, heeft dit een potentieel grote impact op het bedrijf en de verkoop (zie dit onderzoek van Google). Dit geldt zelfs nog meer op mobiele apparaten, waar apps de neiging hebben langzamer te zijn.

Waarom dan niet overal SPA’s gebruiken?

Gezien deze statistieken en het feit dat de SPA’s een veel betere gebruikerservaring geven, waarom gebruikt niet iedereen single page apps voor alles?

Ze bestaan al jaren, en elke website met een navigatiesysteem kan er baat bij hebben om op die manier te worden gebouwd.

Inzicht in de SEO-implicaties van een single page app

Er is één belangrijke reden waarom single page apps tot nu toe niet overal worden gebruikt (met twee afzonderlijke oorzaken):

Single page apps presteren niet goed bij zoekmachines

De twee redenen daarvoor zijn:

De zoekmachine moet “raden” wanneer de pagina compleet is

Wanneer een single page wordt opgehaald, zal een zoekmachine maar heel weinig HTML te zien krijgen. Pas wanneer het MVC framework in werking treedt, wordt de pagina volledig gerenderd met behulp van de gegevens die van de server zijn verkregen.

Het probleem is dat de zoekmachine moet gokken wanneer het Javascript framework klaar is met het renderen van de pagina, zodat er een risico bestaat dat onvolledige inhoud wordt geïndexeerd.

De tweede reden waarom SPA’s het niet goed doen bij zoekmachines is:

SPA deep links zijn moeilijk te indexeren

Door het ontbreken van HTML5 History ondersteuning in browsers, baseren single page apps hun navigatie URL’s in HTML bookmark anchors (URL’s met #, zoals /home#section1). Deze zijn niet gemakkelijk geïndexeerd als afzonderlijke pagina’s door zoekmachines, er zijn manieren om het te doen, maar het is een pijn en er zullen altijd problemen zijn om dit goed geïndexeerd te krijgen in tegenstelling tot het gebruik van gewoon HTML.

De conclusie zou kunnen zijn dat het geen zin heeft om de meest gemakkelijk navigeerbare site te hebben als de manier waarop het is gebouwd het hebben van goede SEO verhindert.

Nu het goede nieuws

Het goede nieuws is dat geen van deze twee redenen nog 100% accuraat zijn! Google is begonnen om betere single page apps te indexeren.

En de recente deprecation van IE9 betekent dat HTML5 History bijna overal beschikbaar is, waardoor het gebruik van anchor URL’s niet meer nodig is voor SPA’s, we kunnen gewoon gewone URL’s gebruiken (zoals /home/section1).

Dit is geweldig nieuws, maar er zijn andere zoekmachines die significant verkeer genereren. Baidu bijvoorbeeld zorgt voor meer dan de helft van het verkeer in China (op dit moment 1,3 miljard mensen).

Ook is er nog steeds het probleem van de prestaties: een app met één pagina zal langzamer zijn vanwege de grote hoeveelheden Javascript die het nodig heeft en de grote opstarttijd, en zal daarom slechter presteren dan een HTML-gebaseerde oplossing.

En dit betekent pagina drop offs, dit probleem zal niet snel verdwijnen, vooral op mobiel. Is er een manier om het beste van alle werelden te hebben, en zowel directe navigatie, SEO-vriendelijkheid als hoge prestaties op mobiel te krijgen?

Het antwoord is ja, met Angular Universal.

Wat is Angular Universal, wat maakt het mogelijk?

Vereenvoudig gezegd stelt Angular Universal ons in staat apps te bouwen die zowel de prestatie- als de gebruikersbetrokkenheidsvoordelen hebben van apps met één pagina, gecombineerd met de SEO-vriendelijkheid van statische pagina’s.

Server-side rendering is echt niet alleen renderen op de server

Angular Universal heeft verschillende andere functies dan het bieden van een oplossing voor het renderen van HTML op de server. Gebaseerd op de term “server-side rendering”, zouden we kunnen denken dat wat Angular Universal doet vergelijkbaar is met bijvoorbeeld een server-side template taal zoals Jade. Maar er zit veel meer functionaliteit in.

Met Angular Universal krijg je die initiële HTML payload gerenderd op de server, maar je start ook een afgeslankte versie van Angular op de client en van daaruit neemt Angular de pagina over als een single page app, waarbij vanaf daar alle HTML op de client wordt gegenereerd in plaats van op de server.

Dus het eindresultaat dat je krijgt is hetzelfde, het is een draaiende single page applicatie, maar nu omdat je de initiële HTML payload van de server kreeg krijg je een veel betere opstarttijd en ook een volledig SEO indexeerbare app.

Pre-rendering bij het bouwen – upload pre-rendered apps naar Amazon S3

Een andere mogelijkheid die Angular Universal opent is pre-rendering van content die niet vaak verandert bij het bouwen. Dit zal mogelijk zijn met behulp van Grunt, Gulp of Weppack plugins. Dit is hoe een Gulp configuratie eruit zal zien, die de inhoud van onze applicatie pre-rendert naar een bestand:

En dit vervolgens eenvoudig upload naar een Amazon S3 bucket met behulp van de Amazon CLI:

Als we deze bucket koppelen aan een Cloudfront CDN distributie, hebben we een zeer betaalbare en schaalbare website.

Wat als de gebruiker meteen met de pagina aan de slag gaat?

Er is een aanvankelijke vertraging tussen het moment dat de HTML wordt gerenderd en aan de gebruiker wordt gepresenteerd en het moment dat Angular aan de client-kant in werking treedt en het als SPA overneemt.

In dat tijdsbestek kan de gebruiker op iets klikken of zelfs beginnen met typen in een zoekvak. Wat Angular Universal mogelijk maakt via zijn preboot-functionaliteit is om de gebeurtenissen die de gebruiker triggert op te nemen, en ze af te spelen zodra Angular kicks in.

Op deze manier zal Angular in staat zijn om te reageren op die gebeurtenissen, bijvoorbeeld door het tonen van de zoekresultaten op een Typeahead lijst.

Maar hoe ziet dit er op de server uit in termen van code?

Hoe HTML te renderen met Angular in de server

De manier waarop de inhoud wordt gerenderd op de server is door gebruik te maken van de express Angular Universal rendering engine expressEngine :

Er is ook een Hapi engine beschikbaar als je liever Hapi gebruikt in plaats van Express. Er komen ook server rendering engines voor allerlei platforms: C#, Java, PHP, zie deze eerdere post voor meer details.

Hoe te beginnen met Angular Universal?

De beste plek om te beginnen is de officiële starter universal-starter, met de starter krijgen we een draaiende applicatie die een express server bevat met server side rendering die out of the box werkt.

Wat vernieuwend is aan Angular Universal is de eenvoud van het gebruik. Een van de belangrijkste ontwerpkenmerken van Angular Universal is de manier waarop het gebruik maakt van dependency injection.

Server Side Rendering Development is niet zoals coderen voor de client alleen

Meerendeels willen we dat onze applicatie op de server precies hetzelfde doet als op de client, door niet direct afhankelijk te zijn van browser API’s.

De realiteit van server-side rendering ontwikkeling is dat dat niet altijd mogelijk is, en er zijn bepaalde dingen die we anders willen doen op de client en op de server.

Neem bijvoorbeeld het renderen van een grafiek: je wilt waarschijnlijk een third party library aanroepen die SVG gebruikt. Die kunnen we niet op de server aanroepen, dus hoe renderen we die?

Een ander voorbeeld: hoe kunnen we geauthenticeerde pagina’s renderen? Omdat de inhoud afhangt van wie er op dat moment is ingelogd.

Dependency Injection gebruiken om authenticatie te implementeren

Om de authenticatie af te handelen, is dit een manier om het te doen:

  • Op de client willen we dat de identiteit van de gebruiker wordt ontleend aan een token dat beschikbaar is in een cookie of in de lokale opslag van de browser.

  • op de server willen we tijdens het renderen van het verzoek dat de identiteitstoken wordt gelezen uit een HTTP-verzoekheader.

Hoe krijg je dezelfde pagina-uitvoer als je naar die pagina navigeert op de client via een router-transitie vs op de server via een browser-verversing?

Eerst een Service-interface definiëren

De eerste stap is het definiëren van een interface die je service zal bieden, die onafhankelijk is van de runtime:

Dan bieden we twee implementaties voor deze interface, een voor de client en de andere voor de server. Op de server is er bijvoorbeeld geen aanleiding om de login-methode aan te roepen, dus gooien we een foutmelding:

Terwijl we op de client het Auth0 lock screen (een third-party browser only library) gaan triggeren om een sign-in formulier aan te bieden:

We injecteren dan verschillende implementaties van de interface op de server en op de client, voor hetzelfde injectietoken:

En dit is hoe we iets anders kunnen doen op de client en op de server in Angular Universal, door gebruik te maken van de Angular dependency injection container.

In feite is Angular Universal ook gebouwd met behulp van deze notie: bijvoorbeeld de manier waarop HTML wordt gerenderd is door in plaats van het injecteren van een DOM renderer tijdens het bootstrappen van het framework, het injecteert een server renderer die HTML genereert met behulp van de parse5 HTML serialization library.

Conclusies

Zoals elke technologie, zullen de voordelen van server-side rendering in de loop van de tijd evolueren. Maar op dit moment, server-side rendering biedt een groot voordeel voor het bouwen van mobiel-vriendelijke, zoekmachine vriendelijke toepassingen die een hoge betrokkenheid van de gebruiker hebben als gevolg van naadloze onmiddellijke navigatie.

Its gemakkelijker dan ooit vandaag om dit soort apps te bouwen met behulp van Angular Universal en de universele starter.

Met Angular Universal het gebruik van dependency injection maakt het heel eenvoudig om iets anders te doen op de server dan op de client als we dat nodig hebben.

Aan de slag met Angular

Als u meer wilt leren over Angular, kijk dan eens naar de cursus Angular voor beginners:

Andere berichten over Angular

Als u dit bericht leuk vond, hier een aantal andere populaire berichten op onze blog:

  • Angular Router – Hoe bouw je een navigatiemenu met Bootstrap 4 en geneste routes
  • Angular Router – Uitgebreide rondleiding, Veelvoorkomende valkuilen vermijden
  • Angular Components – The Fundamentals
  • Hoe Angular vandaag in productie te draaien
  • Hoe Angular apps te bouwen met Observable Data Services – Te vermijden valkuilen
  • Inleiding tot Angular Forms – Template Driven, Model Driven or In-Between
  • Angular ngFor – Leer alle functies inclusief trackBy, waarom is het niet alleen voor Arrays ?
  • Angular Universal In de praktijk – Hoe bouw je SEO-vriendelijke single page apps met Angular
  • Hoe werkt Angular Change Detection eigenlijk?

Leave a Reply