"Avoid Chaining Critical Requests" In Lighthouse oplossen.

Arjen Karel Core Web Vitals Consultant
Arjen Karel
linkedin

"Avoid Chaining Critical Requests" in het kort

Critical requests zijn netwerk verzoeken die door de browser met hoge prioriteit worden gedownload. 

Wanneer een pagina of een Script ervoor zorgt dat er meerdere elementen moeten worden gedownload met hoge prioriteit spreken we van een chain of critical requests. 

Een browser zal pas (volledig) beginnen met het laten zien van de pagina als all deze kritieke bronnen zijn gedownload. Elke kritieke bron kan dus de eerste weergave van een pagina kan blokkeren. Hoe groter of hoe zwaarder de Critical Request Chain wordt, hoe meer invloed de Critical Request Chain heeft op de laadtijd van de pagina volgens lighthouse.

Critical request chain example

Hoe wordt de download prioriteit bepaald

Critical requests zijn dus de bronnen die tijdens het laden met hoge prioriteit worden gedownload. Hoe wordt deze prioriteit bepaald?

De download prioriteit wordt in principe door de browser zelf bepaald. Welke elementen uiteindelijk de hoogste prioriteit krijgen, hangt af van de opbouw van de pagina. De elementen waarvan jouw browser denkt dat ze nodige zijn voor de eerste weergave van de pagina krijgen de hoogste prioriteit.

Jouw browser maakt aan het begin van het laden een gok welke elementen het meest belangrijk zijn. Door de bank genomen werkt de download prioriteit als volgt: HTML krijgt altijd de hoogste prioriteit, daarna Style-sheets, synchrone JavaScript, Fonts, Ajax Requests, afbeeldingen bovenaan de pagina, afbeeldingen later op de pagina en daarna asynchrone JavaScripts.

Je kunt zelf kijken welke bronnen op jouw pagina een hoge prioriteit krijgen. Dat doe je door de devconsole te openen met Ctrl + Shift + J. Navigeer naar de netwerk tab, klik met de rechtermuisknop op de column namen en selecteer 'Priority'

Dev Console Resouce Priority

Waarom is een critical Request Chain slecht voor de laadtijd van de pagina?

Tijdens het laden van een pagina start een browser in 'weergave blokkerende' mode. In deze mode worden de bronnen met hoge prioriteit gedownload. Dat zijn de kritieke bronnen.

Een browser zal pas (volledig) beginnen met het laten zien van de pagina als alle kritieke bronnen zijn gedownload. Elke kritieke bron kan dus de eerste weergave van een pagina kan blokkeren.

Hoe minder van dit soort bronnen een pagina heeft, hoe minder werk de browser moet verrichten om de eerste inhoud op het scherm te krijgen en hoe minder concurrentie er is voor de CPU en andere bronnen.

Hoe los je de "Avoid Chaining Critical Requests" melding op?

Je kunt de invloed van critical requests op drie manieren verminder:

  1. Het aantal kritieke bronnen verminderen. Je kunt door slim gebruik te maken van de mogelijkheden die ervoor zorgen dat bronnen niet meer kritiek zijn.
  2. Het aantal kritieke bytes verminderen. Het is misschien een open deur maar je kunt de invloed van het kritieke pad verminderen door ervoor te zorgen dat de kritieke elementen sneller worden gedownload. Bijvoorbeeld door gzip compressie, javascript tree shaking, afbeeldings-optimalisatie, font subsetting.
  3. De download volgorde van het kritieke pad verbeteren. Je kunt er door middel van 'resource hints' zoals preloading voor zorgen dat de kritieke bronnen zo snel mogelijk worden gedownload zodat de browser na het downloaden meteen kan beginnen met het opbouwen van de pagina.

Wat je precies kunt doen hangt af van het bestandstype dat je probeert te downloaden. Daarom bespreken we nu de belangrijkste bestandstypes:

1. HTML

De HTML, dus eigenlijk de pagina die je bezoekt, wordt altijd met de allerhoogste prioriteit gedownload. De pagina zelf is dus altijd onderdeel van de ciritcal request chain. Daarom begin je altijd met het met het optimaliseren van de pagina zelf.

Content uitgesteld laden: Veel grote sites, zoals Google zelf gebruiken deze techniek om de critical request chain te verkleinen. Op de zoekresultaten pagina bijvoorbeeld worden delen van de content, die niet direct nodig zijn, pas later geladen via een AJAX request.

Verkleinen: Kleiner is altijd sneller, gebruik html minificatie om comments, spaties en witregels uit de pagina te verwijderen.

Compressie: Als laatste is het belangrijk dat je stylesheets goed comprimeert met Brotli of GZIP compressie

2. Stylesheets

Stylesheets in de head van de pagina zijn eigenlijk altijd kritiek. Zonder styles weet een browser niet hoe de pagina er uit gaat zien. Stylesheets zijn dus standaard onderdeel van de critical request chain in lighthouse.

Critical CSS: Stylesheets kun je niet-kritiek maken met een eenvoudig trucje waarbij je de stylehseet 'preload' als resource hint en pas na het laden toevoegd als stylesheet. Plaats de volgende code op de pagina. Jouw browser zal dan beginnen met renderen zonder te wachten op de CSS.

<link rel="preload"
      href="css.css"
      type="text/css"
      as="style"
      onload="this.onload=null;this.rel='stylesheet';"/>

Alleen gebeurt er nu iets raars op de pagina. Eerst wordt de pagina getoond en pas na het laden van de CSS worden de styling toegepast. Alle content verspringt nu.  Daarom plaats je bij deze methode de kritieke CSS in de head van de pagina.
Kritieke CSS  is een verzameling van alle CSS regels die je nodig hebt voor het zichtbare gedeelte van de pagina. Je kunt kritieke CSS zelf  genereren via NodeJS of via een aantal online tools

Media queries: Laad alleen de styles voor jouw device. Vaak wordt jouw pagina bezocht op mobiel. Je hoeft dus de styles voor Desktop en Print eigenlijk niet te downloaden. Dat scheelt tijd en maakt daarmee de critical request chain in lighthouse korter.

Je kunt ook gebruik maken van het media attribuut. Het media attribuut zorgt ervoor dat een stage pas gedownload wordt als het media van het thuis niet overeenkomt met het media dat jij op dit moment gebruikt.

<link href="all.css" rel="stylesheet" media="all">
<link href="print.css" rel="stylesheet" media="print">
<link href="desktop.css" rel="stylesheet" media="screen and (min-device-width: 1024px)">

Verkleinen: Verwijder niet gebruikte CSS. Veel sites gebruiken CSS libraries zoals bootstrap. Deze libraries zijn vaak overcompleet en je gebruikt meestal lang niet alles.
Je kunt deze libraries gemakkelijk via een CSS preprocessor (zoals SASS) aanpassen aan jouw wensen en daarmee een stuk kleiner maken. Deze preprocessors geven je bovendien de optie om jouw CSS te verkleinen door alle spaties en enters weg te halen.

Compressie: Als laatste is het belangrijk dat je stylesheets goed comprimeert met Brotli of GZIP compressie

3. JavaScript

JavaScript bestanden in de head van de pagina worden standaard met een hoge prioriteit gedownload en blokkeren de pagina terwijl ze worden gedownload en worden uitgevoerd. JavaScript is dus standaard onderdeel van de critical request chain.

Defer en Async: Je kunt de prioriteit van deze download aanpassen door deze JavaScript bestanden asynchroon te laden via het async of defer attribuut. asynchrone Script bestanden worden parallel gedownload. Als je het defer attribuut gebruikt wordt het uitvoeren van het JavaScript bestand zelfs uitgesteld zodat het uitvoeren van JavaScript het laden van de pagina zelfs helemaal niet meer blokkeert.

// blokkeert het laden en het uitvoeren
<script src="normalscript.js">
// async blokkeert niet het laden, wel het uitvoeren
<script async src="asyncscript.js">
// defer blokkeert zowel het laden als het uitvoeren niet
<script defer src="deferscript.js">

Code splitting en preloading: Als je JavaScript niet asynchroon uit kunt voeren dan kan het slim zijn om JavaScript op te splitsen. Zet het deel van de JavaScript dat je echt niet kunt missen tijdens het laden in een klein bestand en preload dit bestand. Zet het niet kritieke gedeelte van het javascript in een ander bestand en laat dit wel deferred  of async laden en uitvoeren.

Verkleinen: verklein het aantal bytes dat JavaScript nodig heeft. dit kun je op twee manieren doen. De eerste is door een Javascript Uglyfier tool. Dat is een slimme tool, die Javascript analyseert en zo klein mogelijk maakt. 

Compressie: Daarnaast kun je het aantal buiten verminderen door Javascript te comprimeren via Gzip of Brotli.

4. WebFonts

Webfonts worden meestal als laatste geladen in critical Request chain. Dat komt doordat webfonts pas geladen worden wanneer een browser erachter komt dat ze nodig zijn. Daarvoor moet een browser eerst te HTML analyseren en in de stylesheet opzoeken welk font er wordt gebruikt.

Preloading: Het is slim om, wanneer je zeker weet, dat je een font gaat gebruiken dit font te preloaden. het font wordt dan zo snel mogelijk binnen gehaald waardoor het minder invloed heeft op de critical request chain. Een font preloaden doe je door deze code zo hoog mogelijk in de head van de pagina te zetten

<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
Font strategy: Daarnaast zijn er nog veel andere manieren om vond sneller te maken.
  • Maak altijd gebruik van lokalen webfonts en nooit van Google fonts.
  • Verklein het font via font subsetting
  • Laad niet kritieke fonts via de Javascript <a href="https://developer.mozilla.org/en-US/docs/Web/API/FontFace">fontface interface</a>
  • Gebruik display = swap om het tonen van tekst niet te blokkeren
  • Laat browsers zelf font varianten genereren via font synthesis

Afbeeldingen

Afbeeldingen die groot in beeld komen tijdens het laden kunnen ook een hoge prioriteit krijgen en zo aan het critical path worden toegevoegd. Wanneer je zeker weet dat een afbeelding altijd in het zichtbare gedeelte van de website komt te staan kan het zinnig zijn om ook deze afbeelding te preloaden.

<link rel="preload" as="image" href="important-image.webp">

Voor Alle afbeeldingen die niet direct zichtbaar zijn neem je het zekere voor het onzekere en gebruik je loading="lazy" om het laden van de afbeelding uit te stellen tot net voordat de afbeelding zichtbaar wordt.

<img loading="lazy" src="lazy-image.webp" width="20" height="20" alt="...">

5. AJAX Request

Ajax zoeken voor altijd met een hoge prioriteit uitgevoerd. Stel daarom Ajax verzoeken het liefst uit totdat de pagina klaar is met renderen. Wacht dus totdat de pagina het "load" event heeft gestuurd.

Is het niet mogelijk om het AJAX verzoek uit te stellen dan kun je zorgen dat het Ajax verzoek eerder klaar is door het te preloaden.

window.addEventListener('load', (event)=>{
  console.log('this is a good time for an AJAX request');
});

6. iframes

Iframes worden meestal met een hoge prioriteit gedownload. Omdat een iframe eigenlijk een pagina in een pagina is en je niet weet hoeveel tijd het kost om het iframe te laden kan een iframe voor een heel flink vertraging zorgen. De bronnen die het iframe gebruikt kunnen ook weer met hoge prioriteit worden gedownload en een eigen critical request chain vormen. HGet gebruik van iframes kunnen jouw lighthouse score daarom flink negatief beïnvloeden.

Je kunt het laden van een iframe uitstellen via het loading="lazy" attribuut. Dat scheelt vaak iets wanneer het iframe niet direct zichtbaar is tijdens het laden. Maar vaak is het slimmer om het laten van een iframe te controleren via javascript zodat je zeker weet dat deze niet in de critical request chain terecht komt.

I help teams pass the Core Web Vitals:

lighthouse 100 score

A slow website is likely to miss out on conversions and revenue. Nearly half of internet searchers don't wait three seconds for a page to load before going to another site. Ask yourself: "Is my site fast enough to convert visitors into customers?"

Avoid Chaining Critical Requests in Lighthouse oplossenCore Web Vitals Avoid Chaining Critical Requests in Lighthouse oplossen