Performance van webshops is een belangrijk, continu aandachtspunt. Een snellere webshop betekent een betere gebruikerservaring, minder belasting van de server en hogere ranking in zoekresultaten.
Sinds de laatste versie van Lighthouse (V5), biedt deze tool van Google een ‘realistische en steeds betere’ manier om gevoel van snelheid in cijfers uit te drukken. Een gecompliceerde taak, want er zijn veel factoren die beïnvloeden of het laden van een pagina door bezoekers als ‘snel’ of ‘langzaam’ wordt ervaren.
Met een aantal aanpassingen in Magento’s core en een hele nieuwe, verbeterde manier van Javascript bundling, kunnen we nu een Magento 2 Lighthouse Performance score van 100 halen.
Belangrijk detail: we halen een 100/100 Performance score op Mobile, Simulated Slow 4G, 4x CPU Slowdown
Deze instellingen simuleren de rekenkracht en netwerkeigenschappen van een smartphone. Het behalen van een goede performance score is júist voor mobiele bezoekers belangrijk, want zij zullen het eerst last ervaren bij tegenvallende performance. Daarnaast is het halen van een hoge performance score voor desktops zonder throttling (simuleren slechtere verbinding) goed te doen.
Instructies voor uitvoeren Lighthouse Performance Audit via Chrome Open inspector (CMD+Shift+C) en klik op de tab ‘Audits’ Kies Device: Mobile Kies Audits: Performance (vink anderen uit) Kies Throttling: Simulated Slow 4G, 4x CPU Slowdown Start Audit met ‘Run Audits’
Lighthouse meet performance op basis van verschillende metrics. Alle metrics worden uitgedrukt in tijd, waarbij korter = beter.
First Contentful Paint Meet de tijd van het navigeren naar de url, tot het tijdstip waarop de browser het eerste pixel tekent.
Speed Index Meet de tijd benodigd voor het laden van de zichtbare delen van de pagina. De delen de de bezoeker kan zien. Lighthouse maakt ‘een video’ en berekent de visuele progressie tussen frames.
Time to Interactive Meet hoe lang het duurt voordat een pagina volledig interactief is, gedefinieerd als het punt waarop: De pagina heeft de inhoud weergegeven, gemeten met First Contentful Paint . EventHandles worden geregistreerd voor de meest zichtbare pagina-elementen De pagina reageert binnen 50 miliseconden op gebruikersinteractie.
First Meaningful Paint Meet wanneer de primaire inhoud van een pagina zichtbaar is voor de gebruiker. Paints met alleen de h1, navigatiebalk of laadindicator kwalificeren niet. First Contentful Paint is de tijd waarin iets inhoudelijks (tekst, afbeelding, canvas of SVG) voor het eerst toont. In principe de tijd benodigd voor de meest grote ‘paint’ van content.
First CPU Idle Meet het eerste punt waarop de pagina snel op invoer kan reageren. De meeste UI-elementen op het scherm zijn interactief De pagina reageert binnen een redelijke tijd op de meeste gebruikersinvoer
Max Potential First Input Delay Meet de grootste input die gebruikers kunnen ervaringen. Het RAIL model van google adviseert om de tijd tussen de actie die een bezoeker doet en de (zichtbare) reactie te beperken tot maximaal 100ms.
Al deze metrics zijn kunstmatig: bedacht om in kaart te kunnen brengen hoe snel pagina’s zijn. We weten niet exact hoe scores worden berekend. Wel is het optimaliseren op deze metrics steeds waardevoller. In het verleden merkten we dat pagina’s hoog konden scoren, maar traag aanvoelden. Of vise versa.
Sinds Lighthouse V5, voelen pagina’s met een hoge score (90-100) in onze ervaring daadwerkelijk sneller dan een webshop met lage score.
De weging van deze aandachtspunten is als volgt:
3X - First Contentful Paint 1X - First Meaningful Paint 2X - First CPU Idle 5X - Time to Interactive 4X - Speed index 0X - Estimated Input Latency Bron: Lighthouse Docs Lees meer: Lighthouse Github
We zien dus dat Time to Interactive, Speed Index en First Contentful paint zwaar wegen. Punten waarop Magento door de grote hoeveelheid javascript en afhankelijkheid van javascript niet goed scoort.
Toch is het aantal javascript bestanden niet écht het probleem. Het opsplitsen in vele kleine bestanden is een technische designkeuze en resultaat van de modulariteit van Magento.
Het probleem zit hem in bundling: het samenvoegen van javascript bestanden. In het algemeen is het bundelen van javascript een goed manier om het aantal requests terug te brengen, te voorkomen dat er onnodige javascript wordt ingeladen en daarmee performance te verbeteren. Magento biedt 2 manieren van bundelen:
Basic bundling De circa 996 javascript bestanden uit een frontend thema worden samengevoegd tot 10 bundels van gelijke grootte. Dit verkleint het aantal requests bij het laden van de pagina. Wel wordt nu álle javascript ingeladen.
Advanced bundling Op basis van pagina type (productpagina, categoriepagina, checkout) worden javascript bestanden gebundeld. Per pagina wordt een bundel ingeladen met alleen de op de pagina gebruikte javascript.
Sinds Magento 2.3.3 is de feature ‘Move scripts to bottom’ beschikbaar. Deze instelling verplaatst alle javascript referenties in de broncode naar de onderkant van de pagina. Javascript in de head blokkeert metrics als First Meaningful Paint, dus we zien met het verplaatsen naar de onderkant gemiddeld de Lighthouse Performance score van ~20 naar ~50 verbeteren. Dit is al een flinke verbetering ten opzichte van Magento 2.3.2. In onze tests hebben we deze optimalisatie ingeschakeld.
Test setup:
⬤ First Contentful Paint: 1.5s
⬤ Speed Index: 5.1s
⬤ Time to Interactive: 11s
⬤ First Meaningful Paint: 1.5s
⬤ First CPU Idle: 9.9s
⬤ Max Potential First Input Delay: 220ms
Javascript gedownload: ~1MB Aantal JS bestanden: 80 (Magento 2) Lighthouse Performance score: ~53
Het aantal javascript bestanden dat de categoriepagina van Magento 2 inlaadt, varieert tussen de 160 en 180 stuks (een deel van de 996 stuks totaal). Hoewel browsers sinds HTTP/2 bestanden parallel kunnen downloaden, ‘weet’ de browser niet of er sprake is van afhankelijkheden. Dus worden javascript bestanden lineair (direct na elkaar, ‘gechained’) gedownload. Niet goed voor de Magento 2 Lighthouse Performance score, dus.
Zonder bundling voorkomen we wel dat er meer javascript wordt gedownload dan nodig is. Dit zien we terug in de hoeveelheid javascript die wordt gedownload, want dit is met 1MB ‘relatief weinig’.
⬤ First Contentful Paint: 1.4s
⬤ Speed Index: 5.2
⬤ Time to Interactive: 11.2s
⬤ First Meaningful Paint: 1.4s
⬤ First CPU Idle: 10.8s
⬤ Max Potential First Input Delay: 870ms
Javascript gedownload: 5.1MB Aantal JS bestanden: 15 (Magento 2) Lighthouse Performance score: ~51
Het samenvoegen van javascript bestanden heeft verrassend weinig effect op de Lighthouse score. Het lijkt er op dat het voordeel van minder bestanden wordt weggestreept tegenover het nadeel van de grote hoeveelheid javascript. Wat totaal zo’n 4.5 MB is (waarbij executietijd, niet downloadtijd, het probleem is). Als zien we dit niet goed terug in de metrics.
De omvang van de bundels is samen groter dan de 180 bestanden op de categoriepagina waarbij bundling was uitgeschakeld. Dit komt omdat Magento geen onderscheid kan maken tussen javascript bedoeld voor frontend of backend, niet gebruikte scripts of niet gebruikte functies. Op elke pagina laden we altijd, álle javascript (afkomstig uit 996 bestanden) in.
Er zijn veel punten waarop Lighthouse adviseert om op te optimaliseren. Bij het draaien van een audit, zien we bijvoorbeeld tips als: Properly size images, Remove unused CSS, Defer offscreen images etc.
Toch is dit niet waar de grootste winst te behalen is. Dit wordt duidelijk wanneer we een audit draaien waarbij we Javascript uitschakelen. Nog steeds draaien we de Lighthouse audit met de instellingen: Mobile, Simulated Slow, 4G, 4x CPU Slowdown:
⬤ First Contentful Paint: 1.2s
⬤ Speed Index: 1.2s
⬤ Time to Interactive: 1.8s
⬤ First Meaningful Paint: 1.2s
⬤ First CPU Idle: 1.8s
⬤ Max Potential First Input Delay: 100ms
Javascript gedownload: 0MB Aantal JS bestanden: 0 (Magento 2) Lighthouse Performance score: ~100
Nadeel: de webshop is kapot. Toch zouden we in potentie dicht bij deze score moeten kunnen komen.
Advanced Bundling heeft in Magento 2 nooit gewerkt. Require.js kan niet omgaan met mixins; de mogelijkheid om javascript bestanden te extenden. Iets wat veelvuldig wordt gebruikt in de Magento core. Door dit probleem ontstaan met Advanced Bundling ingeschakeld zoveel conflicten dat een webshop onbruikbaar wordt.
Toch is de theorie van bundelen de logische weg. Omdat de website zonder javascript probleemloos een Lighthouse score van 100 haalt, bouwden we een nieuwe, snellere en slimmere bundler.
De bundler werkt als volgt:
Bijna het hele proces is geautomatiseerd.
Met alleen deze optimalisaties werd de Magento 2 Lighthouse Performance score verhoogd van ~53 naar ~66.
⬤ First Contentful Paint: 1.2s
⬤ Speed Index: 1.4s
⬤ Time to Interactive: 2.3s
⬤ First Meaningful Paint:1.2s
⬤ First CPU Idle: 2.0s
⬤ Max Potential First Input Delay: 100ms
Javascript gedownload: 174 kb Aantal JS bestanden: 6 (Magento 2) Lighthouse Performance score: ~100
Het resultaat na het doorvoeren van de performance optimalisaties en inzetten van de bundler is een zeer snel aanvoelende Magento webshop.
De resultaten behaald zijn van toepassing op een schone Magento installatie met het Luma thema geïnstalleerd. Veel optimalisaties kunnen 1-op-1 worden toegepast op live webshops, want veel custom thema’s baseren zich Luma/Blank.
Het grootste deel van de optimalisaties zijn het resultaat van beter bundelen. Daadwerkelijk minder javascript bestanden inladen en slim samenvoegen van veelgebruikte javascript bestanden tot één bundel.
In de echte wereld zullen resultaten afwijken:
Het doel is dan ook niet om persé een score van 100 te halen, maar om zo hoog mogelijk te scoren en daarbij enige speelruimte te creëren. Dan kan development mooie features bouwen, zonder een groot rood cijfer voor Performance te krijgen.
Performance optimalisatie is een standaard onderdeel van onze dienstverlening. Er zal tijd nodig zijn om in de codebase te verdiepen en Javascript te optimaliseren, maar het is geen onmogelijke taak om onze optimalisaties toe te passen bij een bestaande webshop. Mocht er interesse zijn, neem dan even contact op.
Consult