WordPress afbeeldingsoptimalisatie: WebP, compressie en lazy loading

Als PageSpeed Insights een WordPress-site afbrandt op trage afbeeldingen, dan is de oplossing zelden één instelling in één plugin. Het is een klein stapeltje keuzes: in welk formaat upload je, hoe agressief comprimeer je, wat lazy-load je wel en wat absoluut niet, en hoe wordt de LCP-afbeelding geprioriteerd. Dit artikel loopt dat stapeltje langs en laat zien wat WordPress core in 2026 al vanzelf voor je doet.

Afbeeldingen zijn meestal het zwaarste op een WordPress-pagina, en ze zijn ook de hefboom die PageSpeed-scores het meest verzet voor de minste moeite. Het mechanisme is simpel: bytes die naar de browser gaan kosten tijd, en de grootste byte payload op de meeste WordPress-pagina's is een van de afbeeldingen in de layout. Die hero foto bovenaan een homepage is in de meeste thema's ook nog eens het Largest Contentful Paint element. Krijg je het formaat, de compressie en de loading-attributen op die ene afbeelding goed, dan beweegt de score. Krijg je ze fout, dan doet niets anders op die pagina er eigenlijk meer toe.

Waarom afbeeldingen de grootste hefboom zijn

Drie aparte mechanismen bepalen wat een afbeelding de browser kost. Het eerste is byte size: een 2 MB JPEG rechtstreeks uit een camera is grofweg twintig keer de byte payload van dezelfde foto opgeslagen als een netjes gecomprimeerde WebP op kwaliteit 80. Het tweede is render blocking: een hero-afbeelding waarvan de browser niet weet dat dit de LCP-kandidaat is, komt achter in de wachtrij en dat duwt de eerste paint naar achteren. Het derde is layout shift: een afbeelding zonder width en height belandt op de pagina nadat de tekst eromheen al is gestroomd, de browser herberekent de hele layout, en de bezoeker ziet een sprong.

WordPress core heeft hier al jaren kleine fixes voor opgepakt. Responsive sizing met srcset en sizes kwam in 4.4. Native lazy loading op <img> kwam in 5.5. WebP-upload in 5.8. Native fetchpriority voor de LCP-kandidaat in 6.3. AVIF-upload in 6.5. Geen van deze is op zichzelf een complete oplossing, maar samen zorgen ze ervoor dat een standaard WordPress 6.5 installatie de meeste dingen goed doet, zolang je maar zinnig grote bestanden in een zinnig formaat uploadt en de defaults niet actief stuk maakt.

Voor een breder beeld van wat "traag" eigenlijk betekent en waar afbeeldingswerk in dat grotere geheel past, zie waarom een WordPress-site traag voelt.

WebP vs JPEG vs PNG vs AVIF: welk formaat en wanneer

De keuze voor een formaat volgt redelijk netjes uit het gebruik. AVIF geeft de beste compressie van de vier, grofweg 50% kleiner dan een JPEG bij gelijke gepercipieerde kwaliteit, en wordt vanaf 2024 in alle moderne browsers ondersteund. WebP geeft grofweg 25 tot 35% betere compressie dan JPEG en is sinds Safari 14 universeel ondersteund. JPEG blijft de veilige basislijn voor foto's als je server-side support voor de nieuwere formaten niet kunt garanderen. PNG is alleen het juiste antwoord voor graphics met harde transparantie waar WebP en AVIF geen optie zijn, en dat is in 2026 een kleine hoek van de gebruiksgevallen.

In de praktijk doen de meeste WordPress-sites er goed aan om te standaardiseren op WebP voor foto's, en AVIF erbij te pakken als de host het ondersteunt en de pagina-grootte het tweede formaat rechtvaardigt. De reden is niet technische superioriteit, maar operationele eenvoud. Alleen WebP serveren is één formaat en één fallback. AVIF goed serveren betekent dat je AVIF, WebP en JPEG genereert, en die in een <picture> element met <source> tags wikkelt zodat browsers zonder AVIF-support netjes terugvallen. WordPress core maakt out of the box geen <picture> elementen aan. Wil je formaat-onderhandeling via <picture>, dan heb je een plugin nodig (Modern Image Formats van het Performance Lab team, of een van de zwaardere optimalisatieplugins) of een CDN dat het voor je doet.

Een vuistregel: zit de site op een managed host met Imagick en libavif, en heeft de homepage een hero-foto groter dan 200 KB, dan is AVIF de extra plugin waard. Zit de site op shared hosting met alleen LibGD, blijf dan bij WebP met een enkele JPEG-fallback.

WordPress 5.8 native WebP is upload-acceptatie, geen automatische conversie

Dit is het punt waar de meeste artikelen het mis hebben, dus laat me precies zijn. WordPress 5.8 voegde WebP toe aan de lijst met toegestane upload-MIME types. Dat is wat "native WebP support" in de WordPress changelog betekent. Het betekent dat je een .webp bestand in de mediabibliotheek kunt slepen en dat WordPress het accepteert, de gebruikelijke sub-sizes genereert, ze in srcset opneemt, en het bestand als een eersteklas afbeelding behandelt.

Wat 5.8 niet doet, en wat geen enkele versie van WordPress core vandaag doet, is je bestaande JPEG- en PNG-uploads automatisch naar WebP omzetten. Upload je vakantie.jpg, dan slaat WordPress vakantie.jpg op. Het maakt niet ook een vakantie.webp aan. Het wikkelt de output niet in een <picture> element met een WebP-source. De bytes die de browser downloadt zijn precies de JPEG-bytes die jij hebt geüpload.

Er zijn drie manieren om dat gat te dichten. De eerste is dat je je afbeeldingen zelf naar WebP omzet voor de upload, met Squoosh, sharp, of een willekeurige image editor die WebP exporteert op kwaliteit 75 tot 85. De tweede is dat je de Modern Image Formats plugin installeert (voorheen de WebP Uploads-module van de WordPress Performance Group), die bij upload automatisch WebP-versies genereert en de output herschrijft om die te gebruiken. De derde is een third-party optimalisatieplugin als ShortPixel, Imagify of EWWW Image Optimizer, die hetzelfde doet plus wat extra's zoals batch-conversie van de bestaande mediabibliotheek.

Voor developers die het aantal plugins laag willen houden is er een vierde optie: een filter van één regel die WordPress vertelt om WebP te gebruiken als output-formaat voor alle sub-size generatie.

// Vertel WordPress om WebP sub-sizes te genereren voor JPEG-uploads.
// WordPress 6.5+.
add_filter( 'image_editor_output_format', function( $formats ) {
    $formats['image/jpeg'] = 'image/webp';
    return $formats;
} );

Dit filter raakt alleen nieuwe uploads en alleen de geresizede sub-sizes, niet het origineel. Het origineel in JPEG blijft bewaard. Het is de lichtst mogelijke WebP on-ramp en een prima startpunt als je niet voor formaatconversie alleen al een plugin wilt toevoegen.

WordPress 6.5 voegde AVIF toe

WordPress 6.5, uitgebracht in april 2024, voegde AVIF toe aan de toegestane upload-MIME types en haakte het in dezelfde image-pipeline als WebP. Dezelfde scope-regels gelden. Core accepteert AVIF-uploads, het genereert AVIF sub-sizes als de Imagick of LibGD op de server het formaat ondersteunt, en het neemt AVIF-bestanden mee in srcset. Het zet je bestaande JPEG- of PNG-uploads niet automatisch om naar AVIF, en het wikkelt de output niet in <picture> elementen met AVIF-sources.

De server-eis is hier de gotcha. AVIF-support in PHP hangt ervan af of de onderliggende image library is gecompileerd met libavif, en dat is niet universeel. Wil je weten of je host AVIF ondersteunt, ga dan naar Gereedschap, Sitediagnose, Info, Mediabehandeling en kijk of AVIF in de lijst met ondersteunde formaten staat. Staat het er niet, dan worden AVIF-uploads geweigerd en kun je de rest van deze sectie overslaan.

Voor sites die wel AVIF ondersteunen gelden dezelfde drie upgrade-routes uit de WebP-sectie: omzetten voor de upload, Modern Image Formats van Performance Lab installeren, of een third-party optimalisatieplugin gebruiken die AVIF-generatie afhandelt.

Comprimeren bij upload

Bij compressie zit het meeste bytes-voordeel. Een telefoonfoto is doorgaans 2 tot 5 MB JPEG rechtstreeks uit de camera, en 200 tot 400 KB WebP op kwaliteit 80, en voor een bezoeker is dat dezelfde foto. De twee comprimeer-voor-upload opties die voor niet-developers goed werken zijn Squoosh voor losse afbeeldingen in een browsertab, en een plugin die bij upload comprimeert voor de gestage stroom redactionele uploads.

Het pluginlandschap is grofweg:

  • ShortPixel. Cloudgebaseerd, betalen per afbeelding boven een gratis maandlimiet. Genereert WebP en AVIF. Vervangt of behoudt originelen op verzoek. Solide keuze bij hoge upload-volumes.
  • Imagify. Cloudgebaseerd, vergelijkbaar prijsmodel. Van het WP Rocket-team.
  • EWWW Image Optimizer. Server-based by default (lokale binaries), met een optionele cloud-tier. Handig als je niet wilt dat uploads de server verlaten.
  • Smush. Server-based met een gratis tier. De gratis variant is alleen lossless, en dat is voor foto's zelden de juiste keuze.
  • Performance Lab + Modern Image Formats. Van de WordPress Performance Group. Gratis, officieel, gericht. Doet WebP- en AVIF-generatie maar geen agressieve JPEG-compressie zelf, dus combineer het met handmatige compressie van het origineel.

Het belangrijkste compressiegetal is de quality-instelling. Kwaliteit 75 tot 85 is voor foto's op schermresoluties de visueel niet te onderscheiden zone. Onder de 75 zie je banding in luchten en zachtheid in detail. Boven de 85 groeit het bestand snel zonder zichtbare winst. Welke plugin je ook kiest, zet de quality op 80 tenzij je een reden hebt om dat niet te doen.

Een misverstand dat het noemen waard is: "kleinere afbeeldingen uploaden ziet er altijd slechter uit". Dat klopt niet. Wat er slecht uitziet, is uploaden in de verkeerde dimensies voor de container waarin de foto wordt getoond. Een afbeelding van 3000 pixels breed in een container van 400 pixels breed is verspilde bandbreedte, hoe agressief je ook comprimeert. De betere hefboom dan compressie is in veel gevallen uploaden op een verstandige bronresolutie en WordPress de sub-sizes vandaaruit laten genereren. Twee keer de displaybreedte is een redelijk doel voor retina schermen.

Lazy loading: WordPress 5.5 voor img, 5.7 voor iframe

WordPress 5.5 voegde standaard loading="lazy" toe aan image-tags. Het attribuut vertelt de browser om de download van de afbeelding uit te stellen tot hij in de buurt van de viewport komt, en op een lange pagina kan dat megabytes besparen waar de bezoeker nooit naartoe scrollt. WordPress 5.5 deed dit alleen voor <img> elementen. WordPress 5.7 trok het door naar <iframe> elementen zodat ingebedde YouTube-video's en vergelijkbare iframes dezelfde behandeling krijgen.

Browser-support is inmiddels bijna universeel: Chrome 77 en hoger, Edge 79 en hoger, Firefox 75 en hoger, Safari 15.4 en hoger. Browsers zonder support negeren het attribuut gewoon en laden de afbeelding op de normale manier, dus toevoegen is veilig.

Belangrijke nuance: lazy-loaden van elke afbeelding maakt je site niet sneller. Voor afbeeldingen above the fold maakt het juist trager, en dat is meteen de volgende sectie.

De uitzondering voor de LCP-afbeelding

De ene grootste fout in WordPress-afbeeldingsperformance is je LCP-afbeelding lazy laden. Zodra de browser loading="lazy" ziet, zet hij de fetch achteraan in de wachtrij en wacht hij of de afbeelding daadwerkelijk de viewport in komt. Is die afbeelding ook nog eens het LCP-element, dan meet de metric vanaf het begin van de navigatie tot het moment dat de afbeelding rendert, en duwt het lazy-attribuut die render honderden milliseconden of meer naar achteren. PageSpeed Insights wijst hier expliciet op met de melding "Largest Contentful Paint image was lazily loaded".

WordPress 5.9 loste dit deels op door de eerste content-afbeelding uit te sluiten van automatische lazy loading. WordPress 6.3 ging een stap verder en introduceerde wp_get_loading_optimization_attributes(), een functie die niet alleen lazy loading overslaat op de waarschijnlijke LCP-afbeelding maar er ook fetchpriority="high" aan toevoegt. De functie geldt voor afbeeldingen die via wp_get_attachment_image(), get_avatar(), get_header_image_tag() en de andere core image-helpers worden gerenderd, en hij slaat alleen aan als de afbeelding groot genoeg is om plausibel het LCP te zijn (de standaarddrempel is 50.000 vierkante pixels, instelbaar via het wp_min_priority_img_pixels filter).

De catch is dat "de eerste content-afbeelding" alleen werkt als WordPress hem kan herkennen. Afbeeldingen die door een thema of pagebuilder worden uitgespuugd via een eigen <img> tag in plaats van via wp_get_attachment_image(), omzeilen de optimalisatie. Wordt je hero-afbeelding gerenderd door een custom theme template met een handgeschreven <img> tag, dan moet je de attributen zelf zetten.

// Forceer loading=eager en fetchpriority=high op een specifieke image size.
// Handig als een thema wp_get_attachment_image() gebruikt maar je expliciet
// wilt zijn over de hero-behandeling.
// WordPress 6.5+.
add_filter( 'wp_get_attachment_image_attributes', function( $attr, $attachment, $size ) {
    if ( $size === 'hero-banner' ) {
        $attr['loading']       = 'eager';
        $attr['fetchpriority'] = 'high';
    }
    return $attr;
}, 10, 3 );

Spuugt je thema rauwe <img> tags voor de hero, dan zit de fix in het theme template zelf. Voeg loading="eager" en fetchpriority="high" direct aan de <img> tag toe, en verwijder de loading="lazy" die je code of een plugin er eerder in zette.

Een laatste detail uit Google's web.dev richtlijn over lazy loading: combineer nooit loading="lazy" en fetchpriority="high" op dezelfde afbeelding. Ze spreken elkaar tegen. De browser geeft afbeeldingen die op het punt staan in de viewport te komen al voorrang, dus de combinatie levert niets op en geeft de browser het signaal dat je zelf eigenlijk niet weet welke afbeelding de LCP-kandidaat is.

Zet altijd width en height attributen

Dit is de kleinste fix in de lijst en hij stopt een van de meest zichtbare PageSpeed-waarschuwingen. Elke <img> hoort expliciete width en height attributen te hebben. De waarden zijn de intrinsieke pixel-afmetingen van het bronbestand. De browser gebruikt ze om ruimte in de layout te reserveren voordat de afbeelding geladen is, en dat voorkomt de layout shift die de bezoeker als springende pagina ervaart wanneer afbeeldingen binnenkomen.

wp_get_attachment_image() zet deze attributen automatisch. Theme-code die handmatig <img> tags bouwt vaak niet. Onderhoud je een thema, voeg de attributen dan toe. Kun je het thema niet bewerken, dan zet het wp_img_tag_add_width_and_height_attr filter en de wp_filter_content_tags pipeline die het aanroept ze voor je in afbeeldingen in postcontent, en die staan sinds 5.5 standaard aan.

Thumbnails opnieuw genereren na wijziging van image sizes

Wijzig je de geregistreerde image sizes in je thema, of stap je over naar een nieuw thema dat een andere medium_large breedte gebruikt, dan staan de oude sub-sizes nog op disk voor bestaande uploads. Nieuwe uploads gebruiken de nieuwe sizes, maar de back-catalog is verouderd. Voor de GUI-route is er de Regenerate Thumbnails plugin en voor de CLI-route het commando wp media regenerate van WP-CLI.

# Genereer alle sub-sizes opnieuw voor elke attachment.
# Gebruik --yes om de bevestigingsprompt over te slaan bij een grote bibliotheek.
# WP-CLI 2.10+, WordPress 6.5+.
wp media regenerate --yes

Draai dit één keer na het wijzigen van theme image sizes, na het overstappen op een nieuw thema, of na het installeren van een plugin die nieuwe image sizes registreert (de meeste cache-plugins, AMP en de grote pagebuilders doen dat allemaal).

Afbeeldingen via een CDN

Een CDN brengt de bytes van een afbeelding fysiek dichter bij de bezoeker. Voor een Nederlands publiek dat een server in Amsterdam aanroept is die winst klein. Voor een wereldwijd publiek kan het honderden milliseconden van de fetch-tijd halen. Voor sites waar afbeeldingsperformance de bottleneck is en het publiek geografisch verspreid zit, is een image-aware CDN als Cloudflare Images, BunnyCDN, KeyCDN of Imgix het overwegen waard. Ze combineren doorgaans het CDN met on-the-fly formaat-onderhandeling: het CDN serveert AVIF aan browsers die dat accepteren, WebP aan de rest, en JPEG als laatste fallback, zonder dat je zelf meerdere bestanden genereert.

De trade-off is één bewegend deel meer in de stack en één rekening meer. Voor een single-region WordPress-site onder 50.000 bezoekers per maand is een goed geconfigureerde WebP-setup vanaf de origin meestal snel genoeg dat een CDN niet de eerstvolgende stap met de meeste hefboom is. Voor meer over die afweging, zie het artikel over Cloudflare-configuratie.

Wanneer een optimalisatieplugin niet het hele antwoord is

Een misverstand dat correctie verdient: "een optimalisatieplugin regelt alles". Dat klopt niet. Wat plugins goed regelen is formaatconversie, compressie, sub-size generatie en <picture> element-output. Wat plugins niet regelen is ontbrekende width en height in custom theme templates, ten onrechte eager-geladen afbeeldingen die in werkelijkheid niet de LCP zijn, en thema's die enorme decoratieve achtergronden via CSS laden waar lazy loading helemaal niet op slaat. De plugin is een nuttig stuk gereedschap. Het is geen vervanging voor begrijpen wat de pagina daadwerkelijk verstuurt.

Is je PageSpeed-score na het installeren van een optimalisatieplugin nog steeds slecht, draai de pagina dan door PageSpeed Insights en lees de Opportunities en Diagnostics secties. De diagnostics vertellen je precies welke afbeelding de LCP is, of hij lazy is geladen, hoe groot hij in bytes was, en hoeveel je kunt besparen met een ander formaat of een andere kwaliteit. Dat rapport is de meest bruikbare feedback die je kunt krijgen, en hij is gratis.

Wat je daadwerkelijk moet doen, op volgorde

  1. Audit de homepage en een typische contentpagina in PageSpeed Insights en noteer welke afbeelding de LCP is en hoe groot hij is.
  2. Zit de site op WordPress 6.5 of hoger en ondersteunt de host het, installeer dan Modern Image Formats van Performance Lab en laat het bij nieuwe uploads WebP (en AVIF als beschikbaar) genereren.
  3. Zet de quality van de optimalisatieplugin op 80 voor foto's.
  4. Bevestig voor de hero-afbeelding specifiek dat loading="eager" en fetchpriority="high" in de gerenderde HTML staan. Zo niet, voeg ze toe via het theme template of via het wp_get_attachment_image_attributes filter.
  5. Bevestig dat elke <img> expliciete width en height heeft.
  6. Genereer thumbnails één keer opnieuw nadat de plugin is geïnstalleerd, zodat bestaande uploads het nieuwe formaat oppikken.
  7. Draai PageSpeed Insights opnieuw en controleer of de LCP-afbeelding niet meer wordt aangemerkt.

Doe dit op deze volgorde en de score gaat bewegen. Het werk is grotendeels mechanisch zodra je weet welke afbeelding de LCP is en op welke versie van WordPress je zit.

Klaar met terugkerende traagheid?

Traagheid komt vaak terug na snelle fixes. Professioneel onderhoud houdt updates, caching en limieten consequent op orde.

Bekijk WordPress onderhoud

Doorzoek deze site

Begin met typen om te zoeken, of blader door de kennisbank en blog.