INDIVIRTUAL - TECHNISCH PARTNER IN DIGITALE DIENSTVERLENING

HTTP/2 voor Front-end Applicaties

January 13, 2019

HTTP/2 voor Front-end Applicaties

We kunnen er niet meer omheen; op de tweede dag van Januari 2019 gebruikt bijna 33% van alle websites een vorm van het HTTP/2 (of het onderliggende SPDY) protocol en het grootste deel van de moderne browsers geeft ondersteuning.
Maar wat betekent HTTP/2 voor front-end applicaties? In dit artikel wil ik een aantal mogelijkheden en uitdagingen op een rijtje zetten en hoe front-end applicaties hiervan zouden kunnen profiteren.

Ben je nog niet helemaal bij met wat HTTP/2 is, of wat de veranderingen zijn ten opzichte van HTTP/1? Om een beter idee te krijgen verwijs ik graag door naar een reeds verschenen artikel van mijn collega Kah Tang; hij gaat hier uitgebreid op in en legt een gedegen basis voor dit artikel.

Welke optimalisatietechnieken worden overbodig?

Om de veeleisendheid van moderne webapplicaties tegemoet te komen en de beperkingen van HTTP/1 - naast te te omarmen - ook te blijven uitdagen, zijn we als Front-enders gedrild als het gaat om het toepassen van verschillende optimalisatietechnieken; vooral om zo de laadsnelheid van een site te optimaliseren.
Met HTTP/2 wordt deze strategie redelijk anders, hoewel in mijn optiek de denkwijze onveranderd blijft.

Samenvoegen van assets
Een van de meest toegepaste optimalisatietechnieken is het samenvoegen van assets zoals JavaScript, en/of CSS in een enkel bestand, of plaatjes of SVGs samenvoegen in een sprite.
In het geval van HTTP/2, waar we meerdere items over dezelfde verbinding kunnen versturen/ontvangen - oftewel multiplexing - is dit niet vanzelfsprekend meer.
Dit betekent niet dat we een ongelimiteerd aantal assets kunnen versturen. Het aantal streams binnen een request/response mag dan onbeperkt lijken; een stream heeft wel een beperkte bandbreedte en de afhandeling van prioriteit van elke stream kan weer verschillen per ontvanger.
Wat ook een grote rol kan spelen is dat compressie van bijvoorbeeld een sprite met iconen veel voordeliger kan uitpakken dan de compressie van elk icoon als apart bestand. In dit geval is een sprite wel degelijk de betere optie met het oog op browser caching en backwards-compatibility met HTTP/1. Daarnaast zijn iconen meestal ontworpen met een bepaald thema, dus áls er iets aangepast wordt, heeft dat meestal invloed op de rest van het design, en dus je hele sprite.

Domain-sharding
Met HTTP/1 heeft een browser een limiet op het aantal aanvragen per domein wat tegelijkertijd mag worden uitgevoerd. Standaard zijn dat er maximaal 2, maar bijvoorbeeld Chrome heeft er 6.
Om dit proces te versnellen, is het gebruikelijk deze assets te verdelen over verschillende domeinen; ook wel domain sharding genoemd.
Echter, als je deze techniek toepast met HTTP/2, zou je juist een kleine vertraging kunnen introduceren aangezien je o.a. meerdere TCP connecties aan het introduceren bent.
Daarnaast sla je de plank mis omdat je alle reeds bestaande header-compressie voor het oorspronkelijke domein verliest.

Gaat dan echt alles op de schop?
Natuurlijk zijn er optimalisatietechnieken die er wel degelijk toe blijven doen, hier de twee belangrijkste:

  • Gzip FTW
  • Minifying van assets

HTTP/2 Push

HTTP/2 biedt op veel manieren enorme prestatieverbeteringen ten opzichte van HTTP/1, en server-push is een hele belangrijke.

Nog even op een rijtje wat betreft een HTTP/1-request:

  1. De browser vraagt om een HTML-document
  2. De server verwerkt het request en genereert/verzendt het HTML-document
  3. De browser krijgt response en parsed het HTML-document
  4. De browser identificeert StyleSheets, afbeeldingen, JavaScript-bestanden, enz., kijkt in de cache en stuurt zo nodig voor elke source een nieuw request
  5. De server reageert op elk request met de bijbehorende resource
  6. De browser geeft de pagina weer met behulp van het HTML-document en bijbehorende resources

Kortom: meerdere request binnen een loop zijn nodig om één HTML-document weer te geven.

In HTTP/2 kan de server proactief bijbehorende resources pushen samen met het oorspronkelijke request. Zodra de browser deze assets nodig heeft haalt ‘ie ze uit de lokale cache, en zijn extra requests dus overbodig.
Dit klinkt tot nu toe iets te goed. Waar zit hier de uitdaging? Het is voor een server namelijk niet eenvoudig om te weten welke assets kunnen worden mee-gepusht met een origineel request.
We kunnen die beslissing verplaatsen naar de applicatielaag en de ontwikkelaar laten beslissen, wat totaal niet eenvoudig is. Een andere optie zou zijn om binnen je Continuous Deployment een extra job te introduceren die dat automatisch voor je doet… Maar ga je daarmee alle edge cases afvangen?
Een andere uitdaging vormt browser cache. Browsers cachen assets die eerder zijn opgehaald en zal deze eerder gebruiken als een asset aan de serverkant niet is aangepast. De server moet op de een of andere manier weten of een bron al in de cache van de browser staat.

Er zijn nog veel meer vragen en uitdagingen die komen kijken bij de introductie van HTTP/2 push. Dit document van een aantal engineers bij Chromium gaat daar lekker diep op in.

Conclusie

Gaat nu alles stuk?
Nee. HTTP/2 is backwards-compatible met HTTP/1. Hoewel eerder genoemde optimalisatietechnieken je site zullen vertragen, blijft alles gewoon werken. Het komt er op neer dat de meeste optimalisaties die we hebben toegepast voor HTTP/1 slechte invloed hebben op de performance met HTTP/2.
HTTP/2 gaat er dus voor zorgen dat de manier waarop we (de front-end) ontwikkelen zullen moeten aanpassen.

Voor de overgang
Deze tool test je site’s performance voor HTTP/2.
En met deze tool kan je het verschil tussen HTTP/1 en HTTP/2 testen.

HTTP/3
Of gaan we meteen door naar HTTP/3? Helaas, nog even niet

Tom Cool

Tom Cool

Front-end Developer