Core Web Vitals-gids voor resourceprioritering
Bepaal welke resources als eerste laden en welke wachten.
Core Web Vitals-gids voor de prioritering van resources
De standaard prioriteringsengine van de browser werkt op basis van heuristieken: imperfecte aannames op basis van bestandstypen en documentlocatie. Resources worden in de wachtrij geplaatst zodra de preload scanner of de DOM-parser ze ontdekt.
Laatst beoordeeld door Arjen Karel in februari 2026

Dat kan een probleem worden als je bedenkt dat netwerkbandbreedte en CPU geen onbeperkte resources zijn. Bijvoorbeeld: elke byte die gelijktijdig wordt gedownload voor een trackingscript met lage prioriteit, concurreert direct met de bytes die nodig zijn voor je Largest Contentful Paint (LCP).
Dit is niet de schuld van de browser. In de HTML in ons voorbeeld kon de browser onmogelijk weten dat hij de verkeerde assets prioriteit gaf, waardoor kritieke rendering vertraging opliep.
Jij bent degene die weet wat belangrijk is en jij beheert deze planning via twee mechanismen: prioritering (kritieke signalen een boost geven) en deprioritering (niet-kritieke resources inplannen op een moment dat ze minder storend zijn).
Table of Contents!
Beperkingen van browserheuristieken
Browsers kennen prioriteit toe op basis van een berekende prioriteitsscore. Deze score is afgeleid van het asset-type (CSS, script, afbeelding) en de positie in de HTML/DOM. Dit systeem is over het algemeen effectief voor eenvoudige documenten. Het faalt echter wanneer resources niet vroegtijdig worden herkend (door de preload scanner) of wanneer de verkeerde resources te vroeg worden gedownload.
Standaard prioriteitsniveaus van Chrome
Chrome gebruikt vijf interne prioriteitsniveaus: Highest, High, Medium, Low en Lowest. Zo deelt Chrome ze standaard in:
| Resource | Standaardprioriteit | Met fetchpriority="high" | Met fetchpriority="low" |
|---|---|---|---|
CSS (in <head>) | Highest | (al maximaal) | High |
Script (blokkerend, in <head>) | Highest | (al maximaal) | Low |
| Script (async / defer) | Low | High | Lowest |
| Font (via preload) | Highest | (al maximaal) | n.v.t. |
| Font (in CSS) | High | n.v.t. | n.v.t. |
| Afbeelding (standaard) | Low | High | Lowest |
| Afbeelding (eerste 5 groot) | Medium | High | Low |
| Afbeelding (in viewport, na layout) | High | (al High) | n.v.t. |
Het fetchpriority-attribuut wordt ondersteund op <img>-, <link>- en <script>-elementen. Het heeft 93% wereldwijde browserondersteuning (Chrome 102+, Firefox 132+, Safari 17.2+, Edge 102+) en werkt als progressive enhancement: browsers die het niet ondersteunen, negeren het gewoon. Volgens de Web Almanac van 2025 gebruikt 17% van de mobiele pagina's inmiddels fetchpriority="high", maar gebruikt slechts 0,3% fetchpriority="low". Dat betekent dat deprioritering een massaal onderbenutte optimalisatie is.
De beperking van de preload scanner
Om resources sneller te ontdekken, gebruiken browsers een "preload scanner". Dit is een lichtgewicht parser die vooruitloopt op de HTML-hoofdparser om resource-URL's te vinden. Deze scanner heeft beperkingen (die hem snel en effectief maken). Hij parst alleen HTML. Hij kan niet in CSS-bestanden kijken, hij voert geen JavaScript uit en hij rendert niet. Hierdoor kan hij niet bepalen of resources zichtbaar zijn in de viewport.
Als gevolg hiervan wordt elke resource waarnaar een stylesheet verwijst (zoals een achtergrondafbeelding of webfont), die door een script wordt geïnjecteerd of via lazy loading wordt geladen, overgeslagen. Dit duurt totdat de hoofdparser de hele webpagina downloadt en verwerkt. Dit creëert een "discovery delay". De browser is er feitelijk niet van op de hoogte dat deze kritieke assets bestaan.
Concurrentie om resources
Wanneer de browser assets ontdekt, probeert hij deze vaak tegelijk met andere openstaande aanvragen te downloaden. Als een belangrijke LCP-afbeelding concurreert met een script met medium prioriteit of onbelangrijke afbeeldingen (zoals social media-iconen in de footer), verdelen ze de beschikbare bandbreedte. Deze concurrentiestrijd verlengt de laadtijd voor beide. Dit duwt de LCP-meting de zone "Needs Improvement" in.
Handmatige prioriteringsstrategieën
Om een snel renderingpad te bouwen, moet je handmatig ingrijpen. Het doel is de bandbreedte voor de LCP te maximaliseren en voor al het andere te minimaliseren. Op sites gemonitord door CoreDash behaalt 82% van de sites die fetchpriority="high" op hun LCP-afbeelding gebruiken een goede LCP. Bij sites die dit niet doen, is dit 61%.
1. Los de ontdekking op met preloading
Je moet verborgen assets handmatig blootleggen aan de preload scanner. Verplaats kritieke resources naar de HTML <head> met rel="preload". Hiermee dwing je de browser om ze direct te herkennen en elimineer je de discovery delay. Zie onze gids voor het preloaden van de LCP-afbeelding voor een complete walkthrough.
De implementatie:
<!-- Stel het font direct bloot aan de scanner -->
<link rel="preload" as="font" type="font/woff2" href="/fonts/inter-bold.woff2" crossorigin>
<!-- Stel de LCP-achtergrondafbeelding direct bloot -->
<link rel="preload" as="image" href="/images/hero-banner.jpg" fetchpriority="high">
Voor een nog vroegere ontdekking kun je 103 Early Hints overwegen. Dit stuurt preloads-signalen naar de browser nog voordat de HTML-response aankomt.
2. Overschrijf LCP-heuristieken
Browsers wijzen afbeeldingen vaak de prioriteit "Low" of "Medium" toe. Ze kennen de uiteindelijke layoutafmetingen namelijk nog niet tijdens de initiële fetch. De browser kan pas na het opbouwen van de render tree bepalen of een afbeelding de LCP is. Dat is te laat.
De implementatie:
Forceer de "High"-prioriteitsstatus op het LCP-element via fetchpriority="high". Dit omzeilt interne heuristieken en plaatst de afbeelding vooraan in de downloadwachtrij. Google Flights verbeterde zijn LCP van 2,6 seconden naar 1,9 seconden (een winst van 0,7 seconden) door dit ene attribuut toe te voegen.
<!-- Forceer direct een high-priority fetch -->
<img src="hero.jpg" alt="Hero Product" fetchpriority="high">
De ergste fout hier is lazy loading toepassen op de LCP-afbeelding. Hiermee deprioriteer je actief het belangrijkste element op de pagina.
3. Deprioriteer onbelangrijke afbeeldingen
Bandbreedte vrijmaken is vaak effectiever dan prioriteit verhogen. Je moet niet-essentiële assets expliciet uitstellen om de netwerkverbinding vrij te maken voor kritieke resources.
De implementatie:
- Onder de vouw (below the fold): Gebruik
loading="lazy"om offscreen afbeeldingen uit te stellen totdat de bezoeker scrollt. - Boven de vouw, secundair: Gebruik
fetchpriority="low"voor carrousel-slides of secundaire visuals die initieel renderen, maar minder belangrijk zijn dan de LCP. - Boven de vouw, visueel onbelangrijk: Omzeil de preload scanner met
loading="lazy"en wijs een lage bandbreedteprioriteit toe. Dit is handig voor kleine afbeeldingen zoals vlaggetjes of iconen. Deze vallen niet op tijdens de eerste render, maar kunnen wel veel vroege bandbreedte-aanvragen veroorzaken.
<!-- LCP-afbeelding: hoogste prioriteit -->
<img src="slide-1.jpg" fetchpriority="high">
<!-- Secundaire carrousel-afbeelding: directe fetch, laag bandbreedtegebruik -->
<img src="slide-2.jpg" fetchpriority="low">
<!-- Vertaalvlaggen: verberg ze voor de preload scanner, ook al staan ze in de viewport -->
<img src="dutch-flag.jpg" loading="lazy" fetchpriority="low">
<!-- Off-screen afbeelding: uitgestelde fetch -->
<img src="footer-promo.jpg" loading="lazy"> 4. Beheer script-executie
JavaScript blokkeert de DOM-parser. Als je standaard <script>-tags gebruikt, stopt de browser met het parsen van HTML om het bestand te downloaden en uit te voeren. Ongecontroleerde script-executie schaadt bovendien direct de Interaction to Next Paint (INP) doordat de main thread wordt geblokkeerd.
De implementatie:
- defer: Gebruik dit voor applicatielogica. Het downloadt parallel (Low prioriteit) en wordt pas uitgevoerd nadat de HTML volledig is geparst. De uitvoeringsvolgorde blijft behouden.
- async: Gebruik dit voor onafhankelijke third-party scripts (zoals analytics). Het downloadt parallel en wordt direct na voltooiing uitgevoerd, ongeacht de volgorde.
- async + fetchpriority="high": Gebruik dit voor kritieke async-scripts (zoals A/B-testen) die een snelle download nodig hebben zonder het parsen te blokkeren. Dit verhoogt de downloadprioriteit van Low naar High. De uitvoering blijft niet-blokkerend.
- Inject: Omzeilt de preload scanner zodat het script niet concurreert om vroege bandbreedte. Geïnjecteerde scripts worden behandeld als async.
- Schedule + Inject: Injecteer scripts op een later moment, bijvoorbeeld nadat het load-event is afgevuurd.
<!-- Applicatielogica: niet-blokkerend, behoudt uitvoeringsvolgorde -->
<script src="app.js" defer></script>
<!-- Third-party consent: niet-blokkerend, onafhankelijke uitvoering -->
<script src="consent.js" async></script>
<!-- Kritiek async: snelle download, niet-blokkerende uitvoering -->
<script src="ab-test.js" async fetchpriority="high"></script>
<script>
/* Injecteer analytics (voorbeeld) */
const script = document.createElement('script');
script.src = 'analytics.js';
script.async = true;
document.head.appendChild(script);
/* Voorbeeld van inject + schedule voor chat */
window.addEventListener('load', () => {
const chatScript = document.createElement('script');
chatScript.src = 'chat-widget.js';
document.head.appendChild(chatScript);
});
</script>
Zie voor een uitgebreid overzicht van alle beschikbare technieken 16 methoden om JavaScript uit te stellen en async versus defer JavaScript. Voor advies over het categoriseren van scripts op belangrijkheid, bekijk JavaScript-prioriteitsniveaus.
5. Deblokkeer CSS-rendering
CSS is van nature render blocking. Zonder CSS weet de browser niet hoe de pagina eruitziet. Daarom downloadt en parst de browser de stylesheets als eerste.
Optimalisatiestrategieën:
- Vermijd @import: Dit creëert sequentiële afhankelijkheden die de performance verwoesten.
- Optimaliseer de bundelgrootte: Vermijd CSS-bestanden kleiner dan 3kB (overhead) en groter dan 20kB (blokkerend). Richt je idealiter op bestanden van zo'n 15kB.
- Async laden: Laad off-screen stijlen asynchroon om het kritieke pad te deblokkeren.
- Afweging bij Critical CSS: Inlining van Critical CSS verbetert de eerste pageview. Het omzeilt echter de browsercache, wat volgende pageviews kan vertragen.
De implementatie:
Schrap @import volledig. Gebruik <link>-tags voor parallel laden. Gebruik voor niet-kritieke CSS (zoals printstijlen) het media-attribuut om de main thread te deblokkeren. Zie ongebruikte CSS verwijderen voor meer over CSS-optimalisatie.
<!-- Kritieke CSS: blokkeert rendering (correct) -->
<link rel="stylesheet" href="main.css">
<!-- Print CSS: niet-blokkerend tot een print-event plaatsvindt -->
<link rel="stylesheet" href="print.css" media="print">
<!-- Async patroon: laadt met lage prioriteit, wordt toegepast na het laden -->
<link rel="stylesheet" href="non-critical.css" media="print" onload="this.media='all'"> 6. Stabiliseer font-rendering
Fonts zijn zware, blokkerende resources. Effectieve prioritering vereist strikte limieten op wat je downloadt, en controle over hoe het rendert.
Optimalisatiestrategieën:
- Strikte preload-limieten: Preload alleen de 1 à 2 belangrijkste font-bestanden (meestal LCP-tekst). Het preloaden van 5 of meer fonts verstopt de bandbreedte.
- Zelf hosten: Host je webfonts zelf in plaats van ze via een externe CDN te laden. Dit bespaart de extra verbindingstijd.
- Verklein de payload: Gebruik Variable Fonts (één bestand voor alle gewichten) en subsetting (verwijder ongebruikte tekens) om de bestandsgrootte te minimaliseren.
- Renderingstrategie:
- Gebruik
swapvoor snelle rendering (voorkomt onzichtbare tekst). Zie zorgen dat tekst zichtbaar blijft tijdens webfont-load. - Gebruik
optionalom CLS te voorkomen (vermijdt layout shifts op trage netwerken).
- Gebruik
De implementatie:
<!-- Preload ALLEEN de kritieke subset (bijv. header + body) -->
<link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>
<style>
@font-face {
font-family: 'Inter Variable';
src: url('/fonts/inter-var.woff2') format('woff2-variations');
/* Kies op basis van stabiliteitsvereisten: */
font-display: optional; /* Geen layout shift, maar het font kan een fallback blijven */
/* font-display: swap; Snelste tekstzichtbaarheid, maar risico op layout shift */
}
</style> 7. Versnel verbindingen
Voordat een browser een resource van een third-party origin kan downloaden, moet hij een DNS-lookup uitvoeren, een TCP-verbinding opzetten en TLS-encryptie regelen. Dit kost tijd. Je voorkomt deze vertraging door de browser de opdracht te geven om al vroeg verbindingen op te zetten.
De implementatie:
- preconnect: Gebruik dit voor kritieke third-party origins waarvan je zeker weet dat de browser ze nodig heeft. Het voert de volledige handshake (DNS + TCP + TLS) vooraf uit.
- dns-prefetch: Gebruik dit voor minder kritieke origins. Het voert uitsluitend de DNS-resolutie uit. Dit is lichter, maar bespaart alsnog 20 tot 120 ms.
<!-- Kritieke third-party: volledige vroege verbinding -->
<link rel="preconnect" href="https://cdn.example.com">
<!-- Fallback voor oudere browsers -->
<link rel="dns-prefetch" href="https://cdn.example.com">
Beperk preconnect tot 2 à 4 origins. Elke verbinding verbruikt CPU en bandbreedte. Te veel preconnects concurreren met daadwerkelijke resource-downloads. Dit schaadt de performance in plaats van dat het helpt. Volgens de Web Almanac van 2025 gebruikt 22% van de pagina's preconnect en 24% dns-prefetch. Plaats beide zo vroeg mogelijk in de <head>, vóór eventuele blokkerende resources.
Zoek uit wat echt traag is.
Ik leg je critical rendering path bloot met echte data. Je krijgt een fix-lijst op prioriteit, geen Lighthouse-rapport.
Boek een audit