Ga naar hoofdinhoud
Diensten
Kick-off in april?

100/100 Performance Lighthouse score met Magento 2


3 januari 2020
Auteur: Paul Hachmang
7 minuten leestijd

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.

reach-digital-bundling.png

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’

Hoe Performance wordt gemeten

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.

Optimalisatiekansen en weging

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.

Javascript en Bundling in Magento 2

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.

Effect van javascript op score

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:

  • Magento 2.3.3, met optimalisatie ‘Move script to Bottom’ ingeschakeld.
  • Lighthouse instellingen: Mobile, Simulated Slow, 4G, 4x CPU Slowdown.

Magento demo, categoriepagina - Zonder bundling

geen-bundling.png

⬤ 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’.

Magento demo, categoriepagina - Basic bundling

standaard-bundling.png

⬤ 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.

Test zonder javascript

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:

geen-javascript.png

⬤ 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.

De oplossing: rebuild van Advanced Bundling

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:

  • We maken één (zo klein mogelijke) bundel met daarin de belangrijkste frameworks. Deze bundel wordt synchroon ingeladen en bevat bijvoorbeeld JQuery en require.js. Niet alle features werken, maar we krijgen geen errors.
  • Per pagina registreren we welke javascript bestanden asynchroon nodig zijn en kijken daarbij op een slimme manier naar waar overlap is. Bijvoorbeeld: javascript bestanden voor hoofdnavigatie en minicart gaan in één bundel, maar deze bundel wordt niet ingeladen op de afrekenpagina.
  • We maken extra bundels aan voor pagina’s met extra features. Zo heeft de checkoutpagina de bundel met javascript benodigd voor de footer en een ‘unieke’ bundle met javascript voor ‘Winkelwagen Totalen en ‘Verzendkosten indicatie’.

Bijna het hele proces is geautomatiseerd.

Overige javascript optimalisaties

  • Laatste versie van jQuery gebruikt (van 1.12.4 naar 3.4.1)
  • Verwijderen van Polyfill voor IE8, IE9 en IE10. Wij ondersteunen zelf vanaf IE11, dus die hebben we laten zitten. In theorie zit hier nog veel winst, want wanneer IE11 vervalt kunnen we gebruik maken van de native ES6 module loader en vervalt het nut van require.js
  • Verwijderen van verouderde jquery.mobile.custom.js
  • Verwijderen van frontend inline translate features
  • Verwijderen van MatchMedia Polyfill. Deze feature wordt inmiddels door de browser ondersteund.
  • Update require.js van versie 2.1.11 naar 2.3.6 [...en 10 andere optimalisaties]

Met alleen deze optimalisaties werd de Magento 2 Lighthouse Performance score verhoogd van ~53 naar ~66.

Testresultaten na javascript optimalisatie

reach-digital-bundling.png

⬤ 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.

Performance optimalisatie consult

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 gebruik van community modules en een custom thema betekent meer Javascript. Mogelijk zitten ook daarin referenties naar ongebruikte javascriptfuncties, die performance negatief beïnvloeden.
  • Google blijft de manier waarop statistieken worden gemeten altijd aanscherpen.

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.

Bestaande webshop optimaliseren

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

  • Tijd benodigd: enkele dagen
  • Doelstelling te behalen score: Tussen 90% en 100%
  • Geen noodzaak om over te stappen van development partij

Meer weten over dit onderwerp, of reageren?
Paul Hachmang
Paul Hachmang
071 744 0084
paul@reachdigital.nl
contactformulier