Skjut upp skript tills de behövs

Lär dig hur du förbättrar Core Web Vitals genom att skjuta upp skript tills de behövs

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

Skjut upp skript tills de behövs

I den här artikeln kommer jag att visa och förklara ett smart mönster för att ladda skript som inte behövs vid sidladdningens start vid ett senare tillfälle, precis innan de behövs.

Det absolut mest effektiva du kan göra med JavaScript när det gäller Core Web Vitals är att fördröja laddningen av en resurs tills den behövs. Detta tar bort oanvänd och onödig JavaScript från sidan och laddar den bara när den behövs. Detta åtgärdar Lighthouse-varningen 'reduce unused JavaScript' och förbättrar även responsivitetsmått som Interaction to Next Paint (INP).
Vi har gjort detta med bilder under lång tid. Det kallas lazy loading. Med lazy loading laddas en bild som befinner sig nedanför den synliga delen av sidan precis innan den scrollas in i vyn. På så sätt behöver vi inte ladda bilden direkt vid sidladdningen och webbläsaren kan lägga sina värdefulla resurser på att ladda ner, tolka och rendera saker som faktiskt behövs.

Tänk dig nu att vi kunde göra samma sak med skript istället för bilder. Det visar sig att vi kan! Tyvärr är det inte lika enkelt som att lägga till loading="lazy" på en bild, men med lite ansträngning kan vi få det att fungera.

Steg 1: Ladda skript på begäran

För att lägga till skript på sidan efter sidladdningen behöver vi ett litet skript som gör detta åt oss.

function injectScript(scriptUrl, callback) {
  var script = document.createElement("script");
  script.src = scriptUrl;
  if (typeof callback === "function") {
    script.onload = function () {
      callback();
    };
  }
  document.head.appendChild(script);
}        

Denna funktion injicerar ett skript i den aktuella webbsidan genom att skapa ett nytt script-element och lägga till det i dokumentets head. Parametern scriptUrl anger URL:en för skriptet som ska injiceras. Parametern callback är en valfri funktion som anropas när skriptet har laddats klart. När skriptet har laddats klart utlöses onload-händelsen för script-elementet. Om en callback-funktion angavs kommer den att anropas vid den tidpunkten.

Steg 2: Ladda skript på begäran

Nästa steg är att ladda skript på begäran. Det finns två vanliga metoder för att göra detta. Den första är den mer tillförlitliga metoden 'när en del av sidan är synlig' och den andra är den snabbare metoden 'vid interaktion'.

2a: Intersection observer

Den första metoden för att ladda ett skript precis innan det behövs använder sig av intersection observer. Intersection observer är en tillförlitlig metod som 'aktiveras' när ett element korsar den synliga delen av skärmen. Vi kan använda detta beteende för att utlösa en skriptnedladdning bara när ett element är synligt. Nackdelen med denna metod är att även om ett element är 'på skärmen' kanske det fortfarande inte används.

function injectScriptOnIntersection(scriptUrl, elementSelector) {
  var observer = new IntersectionObserver(function(entries, observer) {
    entries.forEach(function(entry) {
      if (entry.isIntersecting) {
        injectScript(scriptUrl);
        observer.unobserve(entry.target);
      }
    });
  });

  var element = document.querySelector(elementSelector);
  observer.observe(element);
}
        

Denna funktion tar två parametrar: scriptUrl är URL:en för skriptet som ska injiceras, och elementSelector är en CSS-selektor för elementet som ska utlösa injiceringen.

Funktionen skapar ett nytt IntersectionObserver-objekt och skickar en callback-funktion som anropas varje gång ett observerat element korsar viewporten. Callback-funktionen kontrollerar om elementet korsar och injicerar i så fall skriptet och slutar observera elementet.

Observera att Intersection Observer API inte stöds i alla webbläsare, så du kan behöva använda en polyfill om du behöver stödja äldre webbläsare.

injectScriptOnIntersection('script.js', '#my-element');

Detta injicerar skriptet när elementet med ID my-element blir synligt i viewporten.

2b: Vid interaktion

Den mest effektiva metoden för att ladda JavaScript på begäran är att ladda det när en besökare interagerar med ett visst element. Till exempel ett formulär. Fördelen med denna metod är att du förmodligen aldrig laddar skriptet om det inte behövs. Nackdelen är att nedladdningen sker ganska sent och vi måste bestämma vilka händelser (mouseover, hover, touchstart osv.) vi vill lyssna efter.

function injectScriptOnInteraction(scriptUrl, elementSelector, eventTypes) {
  var element = document.querySelector(elementSelector);
  var eventHandler = function() {
    injectScript(scriptUrl);
    eventTypes.forEach(function(eventType) {
      element.removeEventListener(eventType, eventHandler);
    });
  };
  eventTypes.forEach(function(eventType) {
    element.addEventListener(eventType, eventHandler);
  });
}
        

Denna funktion tar tre parametrar: scriptUrl är URL:en för skriptet som ska injiceras, elementSelector är en CSS-selektor för elementet som ska utlösa injiceringen, och eventTypes är en array av händelsetyper som ska utlösa injiceringen (t.ex. ["click", "mouseover"]).

Funktionen hittar elementet med document.querySelector och lägger till händelselyssnare för var och en av de angivna händelsetyperna. När någon av de angivna händelserna inträffar anropas funktionen injectScript med den angivna URL:en, och händelselyssnarna tas bort med element.removeEventListener.

injectScriptOnInteraction(
  'script.js',
  '#my-element', 
  ['click', 'mouseover']
);

Detta injicerar skriptet när elementet med ID my-element klickas på eller hovras över, och tar sedan bort händelselyssnarna.

Slutsats

När skript inte behövs direkt vid sidladdningens start är det en utmärkt idé att ladda dem på begäran! Vi kan göra detta med hjälp av intersection observer eller vid interaktion. Detta frigör värdefulla resurser under de tidiga stadierna av sidladdningen.

Performance is a Feature.

Treating speed as an afterthought fails. Build a performance culture with a dedicated 2-sprint optimization overhaul.

Initialize Project >>

  • 2-Sprint Overhaul
  • Culture Building
  • Sustainable Speed
Skjut upp skript tills de behövsCore Web Vitals Skjut upp skript tills de behövs