Website performance optimaliseren deel 1: data reduceren

Marco den Teuling
0

Inhoudsopgave

    Inleiding

    Bezoekers van je website waarderen alle interactieve elementen, fraaie animaties, webfonts, video’s en high-res foto’s natuurlijk, maar een op die manier opgetuigde website laadt vaak wel traag. Het weer vlot trekken van een langzame website is als een meerkamp met uiteenlopende disciplines. In dit eerste deel kijken we wat je vooral kunt doen om je website kunt optimaliseren door de hoeveelheid data die hij omvat te verminderen.

    Een gemiddelde webpagina neemt tegenwoordig zo’n twee megabyte data in beslag, die worden verdeeld over 75 HTTP-requests. De browser moet bijna een halve megabyte aan JavaScript-code verteren. Tegelijkertijd zijn de gebruikers niet meer zo geduldig als in de tijd van het inbelmodem: drie seconden een leeg scherm is voor sommige bezoekers al te veel. Een website die na tien seconden nog niets laat zien, is het merendeel van zijn bezoekers kwijt.

    Er zijn veel verschillende maatregelen die je als website-eigenaar kunt nemen om je pagina’s sneller te maken. Dit artikel beschrijft optimalisaties voor het front-end. Het geeft een overzicht van het spectrum aan mogelijkheden en gaat alleen in bepaalde gevallen ook de diepte in. De implementatie in detail hangt daarbij sterk af van de eisen en problemen van de betreffende website.

    Level 0: testmiddelen

    Het eerste wat je moet doen, is uitzoeken waar het probleem zit. Tegenwoordig worden Google Page-Speed Insights (PSI), Webpagetest.org en Lighthouse het meest gebruikt voor tests en tips. PSI is relatief duidelijk en is zeer geschikt voor beginners. Het opensourceproject Webpagetest.org is meer gericht op het presenteren van ruwe gegevens dan op duidelijke instructies waar je iets mee kunt.

    Googles PageSpeed Insights gebruikt een soortgelijke techniek als Lighthouse, maar komt vaak met andere tips en resultaten.

    Lighthouse – ook opensource – komt net als PSI van Google, maar test niet alleen de prestaties van een website, maar ook de SEO en toegankelijkheid. Het zit achter de analysefuncties van PSI, maar beoordeelt anders. Lighthouse is geen webservice, je kunt het vinden bij de Chrome-ontwikkelaarstools, maar je kunt het ook installeren als een Node.js-applicatie.

    De meetresultaten geven enige aanwijzingen, maar je moet ze niet overschatten – ze zijn vaak afhankelijk van toevalligheden en verschillen tussen bijvoorbeeld Lighthouse en PSI. Zelfs voor Googles eigen pagina’s pakt de snelheidsindex soms slecht uit. Nuttiger zijn de adviezen (‘Remove unused JavaScript’, ‘Avoid long main-thread tasks’, enzovoorts), in combinatie met specifieke details over de betrokken bestanden en regels.

    Afgezien van Lighthouse staan er bij de ontwikkelaarstools van de populaire browsers meer hulpmiddelen voor het meten van netwerktoegang, renderprestaties en het gebruik van hulpbronnen. Die registreren grote hoeveelheden data als je ze activeert, die je vervolgens kunt bestuderen om knelpunten in de prestaties op te sporen. Ze zijn echter nauwelijks geschikt voor beginners op het gebied van website-tuning.

    website optimaliseren

    Lighthouse presenteert de meetresultaten fraai en geeft daarbij concrete tips voor verbeteringen.

    Level 1: afslanken

    Met tools voor browserontwikkelaars kun je de datasnelheid beperken, bijvoorbeeld om mobiel gebruik na te bootsen. Als je dat eenmaal hebt geprobeerd, zul je meer gemotiveerd zijn om je website op te schonen en te comprimeren.

    Afbeeldingen hebben meestal de grootste besparingspotentie – geen enkele andere maatregel werkt zo snel als het optimaliseren daarvan. Het is duidelijk dat een afbeelding niet groter mag zijn dan de maximale breedte van het scherm. Wat de zaak nog ingewikkelder maakt, zijn de Retina-schermen die beelden kunnen schalen naar hogere resoluties. Een iPhone geeft met de standaardschaling elke CSS-pixel bijvoorbeeld weer op 2,2 apparaatpixels. Een 500×300 pixels grote afbeelding zal er goed uitzien in een CSS-container van die grootte, maar het apparaat zou ook 1000 × 600 pixels in die ruimte kunnen weergeven – de afbeelding ziet er dan gewoon scherper uit.

    Om met dergelijke gevallen en verschillende beeldformaten om te gaan via een responsive layout, hebben front-end-ontwikkelaars CSS-mediaquery’s en vooral de HTML-attributen srcset en sizes tot hun beschikking. De browser gebruikt die om te bepalen welk afbeeldingsbestand het beste past en downloadt alleen dat bestand, bijvoorbeeld:

    <img alt=“afbeelding” srcset=“standard.jpg 1x, retina.jpg 2x”>

    Een JPEG-kwaliteitsniveau van meer dan 80 of een verliesvrij gecomprimeerde PNG afbeelding is meestal een verspilling van bandbreedte. Het verwijderen van metadata of een efficiëntere compressie zal ook heel wat kilobytes besparen. Dat kun je doen met gewone beeldbewerkings- en weergavesoftware of met console-gereedschappen zoals jpegtran, jpegoptim en optipng. Die hulpmiddelen kunnen grote hoeveelheden afbeeldingen verwerken en kunnen worden geïntegreerd in de build-pipeline. De volgende instructie verkleint sommige foto’s tot een tiende van hun bestandsgrootte (pas op, overschrijft de bronbestanden!):

    jpegoptim -o -m75 –strip-all

    –all-progressive *.jpg

    Voor JPEG’s wordt progressieve rendering aanbevolen, waarbij het beeld vanaf het begin op ware grootte verschijnt en gedetailleerder wordt naarmate het laadt – dat voelt voor een gebruiker sneller aan. Voor pictogrammen worden tegenwoordig vectorafbeeldingen in de vorm van SVG’s of pictogramlettertypes gebruikt. PNG’s zijn vooral interessant voor transparantie.

    Het nieuwe WebP-formaat beslaat slechts ongeveer 80 tot 90 procent van een equivalent JPEG-bestand, maar je hebt eventueel een fall-back nodig voor Internet Explorer. Tot nu toe werkt alleen Chrome met AVIF, dat zijn sterke punten uitspeelt bij hoge compressieverhoudingen en GIF-achtige animaties mogelijk maakt.

    Voor video doen veel sites een beroep op externe dienstverleners die bij het streamen de afspeelkwaliteit aanpassen aan de bandbreedte. Maar waar een <video> of <audio> wordt gebruikt die een mediabestand opvraagt, kan een goede compressie megabytes aan data besparen. Tools zoals ffmpeg doen dat werk betrouwbaar. Helaas is er geen equivalent voor srcset voor gestreamde media.

    Je moet ook websitecode comprimeren. Codereductietools bestaan voor CSS en HTML, maar dat levert meer op bij JavaScript. Het populairste hulpmiddel daarvoor heet Uglify – de uitvoer ervan is nauwelijks leesbaar voor mensen, maar voor de computer maakt dat niet uit.

    Het is moeilijker, maar lonender, om overbodige code er helemaal uit te gooien. JavaScript-bibliotheken laten de code enorm groeien. Daarom moet je je bij elk script van derden afvragen: heb ik dat echt nodig? Moet ik moments.js toevoegen als ik één keer een datum converteer? Is de carrousel-plug-in de moeite waard, heb ik jQuery echt nodig omdat $(…) zo lekker kort is?

    Niet te vergeten: de browser is niet klaar na het downloaden, hij moet de code ook verwerken. Terwijl dat bij afbeeldingen een kwestie van milliseconden is, is het harder werken bij JavaScript, dat de hoofdthread vaak secondenlang blokkeert. Op een apparaat met weinig rekenkracht kan het compileren en uitvoeren langer duren dan het downloaden. Tests met echte hardware bij verschillende netwerkkwaliteiten leveren soms verrassende resultaten op, maar zijn tijdrovend.

    Bij projecten die in de loop der jaren steeds gegroeid zijn, kom je vaak een verbazingwekkende warboel aan code tegen, zoals verschillende jQuery-versies of polyfills die eigenlijk al jaren niemand meer nodig heeft. Maar test de site grondig en gooi er niet overhaast code uit! Een JavaScript-exception stopt dan bijvoorbeeld verdere uitvoering van de code, en als die niet meer werkt is zelfs de beste optimalisatie nutteloos.

    Chrome heeft bij de ontwikkelaarstools het tabblad Coverage (in het menu onder ‘More tools’) dat ongebruikte CSS-selectors en JavaScript-functies rood markeert. Bij de meeste websites het aandeel daarvan ver boven de 50 procent. De Node.js-tool UnCSS geeft de werkelijk gebruikte CSS weer – zelfs overkoepelend voor meerdere pagina’s en schermformaten.

    Zoals Chromes Coverage-tool laat zien, zijn veel gekoppelde scripts en stijlen niet noodzakelijk op de huidige webpagina.

    Bij het importeren van modules is het vaak mogelijk om dat te beperken tot afzonderlijke componenten. Moderne bundlers zoals webpack en Rollup kunnen overweg met die ‘tree-shaking’ en kopiëren met import {func1} from ‘bigFile.js’ alleen de code die bij func1 hoort naar het project in plaats van het hele scriptbestand.

    Level 2: overdracht

    Ondanks kleine verbeteringen heeft het netwerkprotocol HTTP zijn wortels in het begin van de jaren negentig, en TCP, waar het op gebaseerd is, is nog ouder. Beide doen hun werk degelijk, maar een beetje omslachtig – ze zijn eigenlijk niet bedacht voor de veel voorkomende scenario’s van vandaag de dag met vaak meer dan honderd requests per pagina-aanroep.

    De door beide protocollen veroorzaakte overhead is vooral nadelig bij het versturen van kleine bestanden. Daarom wordt het als een performance-optimalisatie beschouwd om kleine datapakketten te combineren tot grotere – bijvoorbeeld door verschillende script- en stylesheetbestanden te bundelen (bundling) of door trucs zoals CSS-sprites, waarbij alle pictogramafbeeldingen in één afbeelding worden gepropt om er met behulp van CSS de juiste uit te pikken.

    Volgens de HTTP-specificatie beperken browsers bovendien het aantal gelijktijdige verbindingen met dezelfde host. Doorgaans staan ze zes gelijktijdige downloads toe. Om dat te omzeilen, gebruiken sommige sites domain-sharding – het verdelen van bronnen over meerdere subdomeinen.

    HTTP/2 elimineert de noodzaak voor dergelijke hacks. Er is slechts één TCP-verbinding nodig om een willekeurig aantal HTTP-responses terug te sturen – zelfs responses waar de client nog niet om heeft gevraagd (server-push). HTTP/2 is ondertussen een gevestigde norm, die volgens W3Techs bij 45 procent van alle websites gebruikt wordt.

    Het protocol wordt inderdaad gebruikt bij internationale websites zoals Google, Facebook, Amazon, eBay, LinkedIn en hun content-delivery-networks (CDN). Zelfs sommige kant-en-klare shared-hosting aanbieders bieden HTTP/2, terwijl andere hosters tot nu toe nog niet zijn overgestapt. Je moet echter geen wonderen verwachten van HTTP/2.

    De snelste download is natuurlijk de download die niet gedaan hoeft te worden. Slim cachen kan het herhaaldelijk laden van pagina’s enorm versnellen en er zelfs voor zorgen dat bezoekers iets zien als ze offline zijn. Gebruik daar de HTTP-headers Cache-Control of Expires voor. Daarbij kun je differentiëren naar content: de browser mag een afbeelding bijvoorbeeld een maand in de cache bewaren, terwijl de stylesheet slechts twee uur geldig blijft. De startpagina moet daarentegen al na korte tijd (bijvoorbeeld 30 seconden) opnieuw worden opgevraagd.

    Als er ook een ETag-header is ingesteld, kunnen de browser en de server vergelijken of ze beide dezelfde bestandsversie hebben. In dat geval antwoordt de server met een 304-code zonder data over te dragen.

    De programmeerbare front-end-cache die mogelijk is met Progressive Web Apps (PWA) gaat een stap verder. Het belangrijkste doel is om websites offline beschikbaar te maken op mobiele apparaten, maar prestatie-optimalisatie voor desktopbrowsers werkt er net zo goed mee. Maar of het nu gaat om PWA of cache-instellingen: overdrijf het niet, anders ziet de bezoeker te lang een verouderde versie van de website!

     

    Webpagetest.org is een alternatief voor Googles performance-tools. Voor de test met standaardinstellingen moet je even geduld hebben.

    (Deze tekst is verschenen in c’t 4/2021, p.120, met medewerking van Herbert Braun en Daniel Dupré)

     

     

    Wil je op de hoogte blijven van het laatste IT-nieuws en de nieuwste online-artikelen? Meld je dan hier aan voor onze nieuwsbrief:

    Meer handige workshops vind je in c't magazine dec/2021

    Deel dit artikel

    Lees ook

    Een smarthome opzetten met ESPHome en Home Assistant

    We laten zien hoe je de gratis Home Assistant software samen met ESPHome gebruikt voor een smarthome opzetten en centraal aansturen.

    Chrome OS alternatief CloudReady installeren: gratis Chromebook

    Je kunt Cloudready installeren als gratis alternatief voor Chrome OS.  Maak je eigen Chromebook van een oude laptop. Zo werkt het.

    0 Praat mee
    avatar
      Abonneer  
    Laat het mij weten wanneer er