Het GRATIS noodgreep pagespeed optimalisatie script

Versnel je onherstelbare pagina met deze noodgreep-methode om zelfs de traagste pagina's te verbeteren

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2024-11-27

Het GRATIS noodgreep pagespeed optimalisatie script

Als Core Web Vitals consultant kom ik soms een onherstelbare pagina tegen. Niet omdat ik niet weet hoe ik het moet oplossen! 
Nee, de pagina is onherstelbaar omdat de oplossing het herschrijven van grote delen van een site vereist die al op de planning staat om vervangen te worden. Of soms wanneer er gewoon niet genoeg toegang en controle is om de code van de site te verbeteren, zoals je ziet bij meer gesloten CMS-systemen zoals (WIX, HubSpot, WebFlow etc). Of, ten slotte, als het budget er gewoon niet is. Het gebeurt niet vaak, maar soms kunnen klanten de hoeveelheid werk die gedaan en betaald moet worden niet nauwkeurig inschatten.

Introductie van "Het noodgreep pagespeed optimalisatie script"

Wanneer je in zo'n lastig parket zit, is dit script je laatste wanhopige poging om de pagespeed op zijn minst een beetje te verbeteren totdat je iets beters kunt bouwen. Het werkt slim door gebruik te maken van de Mutation Observer. Het script kijkt toe hoe de browser het Document Object Model van je site opbouwt en onderschept en vervangt onmiddellijk trage code door snellere code.

Wat het doet:

  • Onderschept alle render-blocking scripts en stelt ze uit door het type van het script te veranderen naar type="module". Deze truc maakt gebruik van het feit dat alle modulaire scripts standaard worden uitgesteld. Zelfs inline scripts. Dit maakt dit de veiligste methode om alle scripts op de pagina uit te stellen.
  • Lazy-loaden van afbeeldingen: loading="lazy" en decoding="async" worden aan alle afbeeldingen toegevoegd. Dit stelt het laden van deze afbeeldingen uit totdat ze bijna in de zichtbare viewport zijn, samen met een asynchrone update van de image layout.
  • Lazy-loaden van iframes. Net als bij afbeeldingen, kan het lazy-loaden van iframes prioriteit geven aan je eigen, belangrijkere, content!

Configuratie

Het script accepteert een enkel 'config object' en gebruikt die config om het uitstellen of lazy-loaden van belangrijke afbeeldingen en scripts over te slaan. Voor iframes werkt het andersom: het lazy-loadt alleen de iframes die overeenkomen met je config. Alle configuraties worden opgegeven als een regular expression. Dat klinkt misschien eng, maar in de praktijk is het heel eenvoudig. 

  • prioScripts: Slaat het uitstellen van scripts over waarvan de src overeenkomt met de configuratie.
  • Voorbeeld: 'jquery|menu' matcht je jquery en je menu script.
  • prioImgs: Slaat lazy-loading over voor alle afbeeldingen waarvan de afbeeldingsnaam, image class of image id overeenkomt.
    Voorbeeld: 'hero' matcht zowel <img id="hero" ..> als <img src="hero.jpg">
  • lazyFrames: Lazy-loadt alleen iframes waarvan de iframe src overeenkomt met de config.
    Voorbeeld: 'youtube|maps' lazy-loadt alle YouTube en Google Maps iframes.

Gebruik

Pas de config aan naar de behoeften van je website en plak het script als allereerste in de head van de pagina. Onthoud: het script kan problemen pas oplossen nadat het zelf is gevonden. Dus hoe lager je het in de head van de pagina plaatst, hoe minder effectief het zal zijn!

Beperkingen

Zoals ik al eerder aangaf, moet je dit script echt niet gebruiken als je belangrijkste oplossing om je pagespeed te verbeteren. Alleen als al het andere faalt, en terwijl je actief aan een nieuwe site werkt, is een dergelijke oplossing acceptabel!
In meer technische termen: dit script racet tegen de browser (en de preload scanner), dus het is niet te voorspellen welke trage elementen al voor download zijn aangeroepen voordat het script wordt geactiveerd.

Het noodgreep pagespeed optimalisatie script

Hier is een minified versie die je in productie moet gebruiken.

!function(t){['prioScripts', 'prioImgs', 'lazyFrames'].forEach(e=>{t[e]=t[e]?RegExp(t[e],"i"):null});let e=new MutationObserver(e=>{e.forEach(({addedNodes:e})=>{e.forEach(e=>{if(1===e.nodeType)switch(e.tagName){case"SCRIPT":if(!t.prioScripts||!t.prioScripts.test(e.src)){let t=e.getAttribute("type");t&&"text/javascript"!==t||e.setAttribute("type","module")}break;case"IMG":console.log(e.outerHTML),t.prioImgs&&(t.prioImgs.test(e.outerHTML)||e.getAttribute("loading"))||(e.setAttribute("loading","lazy"),e.setAttribute("decoding","async"));break;case"IFRAME":t.lazyFrames.test(e.src)&&e.setAttribute("loading","lazy")}})})});/MSIE|Trident/.test(navigator.userAgent)||(e.observe(document.documentElement,{childList:!0,subtree:!0}),document.addEventListener("DOMContentLoaded",()=>{e.disconnect()}))}({prioScripts:"jquery",prioImgs:"hero",lazyFrames:"youtube|maps"});

Hier is een beter leesbare versie van het script. Gebruik deze niet in productie! Gebruik de minified versie!

!function (cfg) {

    // Regexify config or nullify
    ['prioScripts', 'prioImgs', 'lazyFrames'].forEach((e) => {
        cfg[e] = cfg[e] ? new RegExp(cfg[e], "i") : null;
    });

    t0 = performance.now();

    /* Watch mutated nodes */
    const mutator = new MutationObserver((e) => {
        e.forEach(({ addedNodes: e }) => {
            e.forEach((e) => {
                switch (e.nodeType) {
                    case 1:
                        switch (e.tagName) {
                            // defer scripts by adding type="module", excusive test on src
                            case "SCRIPT":
                                if (!cfg.prioScripts || !cfg.prioScripts.test(e.src)) {
                                    let type = e.getAttribute("type");
                                    if (!type || type === "text/javascript") {
                                        e.setAttribute("type", "module");
                                    }
                                }
                                break;

                            // lazy load images, excusive test on outerHTML for classname, id etc etc
                            case "IMG":
                                console.log(e.outerHTML);
                                if (!cfg.prioImgs || (!cfg.prioImgs.test(e.outerHTML) && !e.getAttribute("loading"))) {
                                    e.setAttribute("loading", "lazy");
                                    e.setAttribute("decoding", "async");
                                }
                                break;

                            // lazy load iframes, inclusive test on src
                            case "IFRAME":
                                if (cfg.lazyFrames.test(e.src)) {
                                    e.setAttribute("loading", "lazy");
                                }
                                break;
                        }
                        break;
                }
            });
        });
    });


    // Check for IE
    if (!/MSIE|Trident/.test(navigator.userAgent)) {
        mutator.observe(document.documentElement, { childList: true, subtree: true });
        document.addEventListener("DOMContentLoaded", () => {
            mutator.disconnect();
            console.log("I quit after watching for " + (performance.now() - t0) + " ms");
        });
    }
}({
    prioScripts: 'jquery',
    prioImgs: 'hero',
    lazyFrames: 'youtube|maps',
});


Het GRATIS noodgreep pagespeed optimalisatie scriptCore Web Vitals Het GRATIS noodgreep pagespeed optimalisatie script