Optimalisering av JavaScript-prioritet for raskere sideinnlasting

Lær hvordan du prioriterer skript effektivt for å forbedre Core Web Vitals.

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

Håndtering av JavaScript-prioriteter for bedre nettytelse

Én ting har alltid vært klart: ikke all JavaScript er skapt lik. Noen skript håndterer kritiske interaksjoner som 'menyinteraksjon' eller 'legg i handlekurv', mens andre skript er langt mindre viktige. Ta for eksempel 'exit intent'-popup-skriptet ditt som inviterer besøkende som er i ferd med å forlate nettstedet ditt til å fylle ut et spørreskjema. Jeg er sikker på at vi alle kunne levd uten de siste, men det ville vært veldig vanskelig å navigere et nettsted uten det første.

Likevel, på  'ditt gjennomsnittlige nettsted' på et teknisk nivå blir dette skillet nesten aldri gjort. Alle JavaScripts blir 'bare lagt til' på siden, og nettleseren må finne ut av det selv. Det er et problem fordi nettleseren din ikke har noen anelse om hva som er viktig og hva som ikke er det. Vi, som utviklere, vet det. Så la oss fikse det!

Hvordan JavaScript-prioritet kan påvirke Core Web Vitals

Å bare legge til skript på siden uten riktig vurdering kan påvirke alle 3 Core Web Vitals. Largest Contentful Paint, Interaction to Next Paint og Cumulative Layout Shift. 

javascript lcp impact example

Eksempel: LCP-nettverksressursen blir forsinket av renderingsblokkerende JavaScripts

Largest contentful Paint er utsatt for båndbredde- og CPU-konkurranse. Når for mange skript kjemper om tidlige nettverksressurser, vil det forsinke Largest Contentful Paint-nettverksressursen, og tidlig CPU-arbeid vil forsinke LCP ved å blokkere hovedtråden.

Interaction to Next Paint kan påvirkes av skript som kjører rett før en interaksjon. Når skript kjører, blokkerer de hovedtråden og vil forsinke enhver interaksjon i løpet av den kjøretiden.

Skript kan også forårsake en Cumulative Layout Shift hvis skript 'endrer hvordan siden ser ut'. Annonseskript som injiserer bannere på siden og skyveknapper er beryktet for å gjøre dette.

5 typer JavaScript-prioriteter

Jeg liker å skille mellom 5 typer JavaScript-prioriteter. La oss raskt diskutere disse før vi graver dypere.

  • Renderingskritisk: disse skriptene er blant de verste å ha. De endrer sideoppsettet, og uten å laste disse skriptene vil oppsettet være helt annerledes. Eksempel: noen skyveknapp-skript eller en A/B-test.
  • Kritiske skript: Disse skriptene håndterer kritisk sidefunksjonalitet, og uten disse skriptene er kritiske oppgaver som å legge et produkt i handlekurven, nettstedssøk eller navigasjon ikke mulig.
  • Viktige skript. Disse skriptene håndterer viktig (forretnings)logikk, og nettstedet ditt er avhengig av disse. For eksempel: Analytics
  • Greit å ha-skript. Disse skriptene er greie å ha, men hvis det virkelig gjelder, trenger vi dem egentlig ikke for at siden skal fungere. For eksempel en chat-widget eller en exit intent
  • Fremtidige skript. Disse skriptene kan være kritiske eller greie å ha, men vi trenger dem ikke akkurat nå fordi 'andre steg' må tas før vi faktisk kan bruke disse skriptene. For eksempel et flertrinns utsjekkingsskript.
Nå som vi har en idé om skriptprioriteter, la oss bryte det ned!

1. Renderingskritiske skript

Dette er de mest forstyrrende skriptene, ettersom de direkte påvirker hvordan siden vises. Uten dem kan oppsettet bryte sammen eller se drastisk annerledes ut enn det tiltenkte designet. Eksempler inkluderer skript for skyveknapper eller A/B-testrammeverk som endrer oppsettet tidlig i innlastingsprosessen. 

Problemet med denne typen skript er at de ikke kan utsettes eller forsinkes. Enhver forsinkelse vil føre til at nettstedets oppsett forskyver seg, noe som forårsaker dårlig UX og at Core Web Vitals feiler.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Page Title</title>
    <link href="styles.css" rel="stylesheet" />
    <script src="render-critical.js"></script>
  </head>
  <body></body>
</html>

Beste praksis:

  • Unngå renderingskritiske skript som dette når det er mulig. Skriv om koden din for å unngå avhengighet av denne typen skript.
  • Hvis det ikke er mulig å unngå det, inline eller last bare de absolutt nødvendige delene av disse skriptene. 
  • Ikke bruk defer eller async på disse skriptene, og plasser dem øverst i head for å utløse en 'så tidlig som mulig'-nedlasting.

2. Kritiske skript

Disse skriptene muliggjør grunnleggende interaksjoner. Uten dem blir kritiske oppgaver som nettstedsnavigasjon, legge varer i handlekurven, informasjonskapselvarsling eller utføre søk umulig. De er uunnværlige for nettstedets kjernefunksjonalitet.

Disse skriptene bør plasseres i head på siden med enten async- eller defer-attributtet.

<script defer src="critical.js"></script>
<script async src="critical.js"></script>

Beste praksis:

  • Hold skript som disse til et minimum, og ikke kombiner denne funksjonaliteten med annen, mindre kritisk funksjonalitet.
  • Last disse skriptene tidlig ved hjelp av async eller defer, avhengig av deres avhengigheter.
  • Bruk Real User Monitoring (RUM)-verktøy, som Coredash, for å identifisere flaskehalser i kjøringen og sikre at ytelsen samsvarer med brukernes behov.

3. Viktige skript

Selv om de ikke er direkte knyttet til nettstedets brukervennlighet, støtter viktige skript sentrale forretningsfunksjoner. Analytics-skript gir for eksempel essensielle data, men trenger ikke å lastes før viktigere visuelle elementer. Naturligvis kan skillet mellom kritiske og viktige skript være gjenstand for debatt, så sørg for å snakke med alle interessenter før du setter denne prioriteten!

Det finnes 3 måter å senke skriptprioriteten for denne typen skript.

<html>
<head>
<!-- method 1: low fetchpriority -->
<script fetchpriority="low" defer src="important.js"></script>

<!-- method 2: inject after DOMContentLoaded -->
<script>
  document.addEventListener('DOMContentLoaded', function() {
    var script = document.createElement('script');
    script.src = 'important.js';
    document.body.appendChild(script);
  });
</script>
</head>
<body>

<!-- method 3: place at the bottom of the page -->
<script defer src="important.js"></script>
</body>
</html>

1. Lav fetchpriority. 

Å sette fetchpriority vil senke den relative prioriteten til skriptet. Andre deferred eller asynced skript vil sannsynligvis bli køet med høy prioritet, mens skriptene med fetchprioriy="low" vil bli køet med lav prioritet. Avhengig av siden din (eller renderingsbanen din) kan dette være nok til å prioritere andre ressurser som Largest Contentful Paint-bildet ditt og viktige fonter. 

2: Injiser etter DOMContentLoaded

Ved å injisere skriptet etter DOMContentLoaded-hendelsen sikrer du at skriptet begynner å laste ned direkte etter at HTML-en er ferdig parset. Dette lar oppdagbare ressurser, som bilder og fonter, få forrang. Denne metoden gir en balanse: skriptet begynner å laste tidlig nok til å unngå forsinkelser i funksjonalitet, men konkurrerer ikke med tidlige ressurser som er avgjørende for den første siderenderingen.

3: Plasser nederst på siden

Denne klassiske teknikken utsetter skriptinnlasting til etter at nettleseren har behandlet hele dokumentet, og oppnår omtrent det samme resultatet som teknikk 2. Den eneste forskjellen er at teknikk 2 hopper over nettleserens preload-skanner, mens denne teknikken ikke gjør det.  Preload-skanneren er en lettvekts hurtigskanner som nettleseren din bruker for raskt å identifisere og køe kritiske ressurser. Å hoppe over preload-skanneren kan være en god idé hvis det er mulighet for lazy-lastede bilder i viewporten, mens bruk av preload-skanneren vil fremskynde innlastingen av dette skriptet.

4. Greit å ha-skript

Disse skriptene forbedrer user experience, men er ikke nødvendige for at nettstedet skal fungere. Eksempler inkluderer chat-widgeter, tilbakemeldingspopuper fra kunder eller valgfrie animasjoner. Selv om de er nyttige, bør de ikke forstyrre den primære user experience.

Disse skriptene er en ideell kandidat for å laste med et mønster kalt 'lazy on load'. Dette betyr å vente på sidens load-hendelse og deretter, i ledig tid, injisere skriptet.  Å vente på load-hendelsen sikrer at skriptet ikke konkurrerer om båndbredde og CPU  med viktigere tidlige ressurser. Å vente på et ledig øyeblikk sikrer at nettleseren ikke håndterer viktigere oppgaver som brukerinndata.

Her er et fungerende eksempel:

window.addEventListener("load", () => {
  window.requestIdleCallback(() => {
    const script = document.createElement("script");
    script.src = "/path/to/script.js";
    document.head.appendChild(script);
  });
});

Beste praksis:

  • Lazy-last disse skriptene etter at siden er lastet, og vent på et ledig øyeblikk.
  • Forstå at skript som lastes med dette mønsteret ikke er garantert å laste raskt

5. Fremtidige skript

Fremtidige skript er de som ikke trengs før spesifikke betingelser er oppfylt. For eksempel blir et flertrinns utsjekkingsskript relevant først etter at en bruker har lagt varer i handlekurven. Disse skriptene kan ofte vente til mye senere i brukerens reise.

Ta en titt på dette eksempelet. Det bruker intersection observer for å laste JS-logikken som kreves for registreringsskriptet bare når skjemaet er i det synlige viewporten.

<!DOCTYPE html>
<html>
  <head>
    <script>
      document.addEventListener("DOMContentLoaded", function () {
        const form = document.querySelector("form");
        const observer = new IntersectionObserver(function (entries) {
          entries.forEach((entry) => {
            if (entry.isIntersecting) {
              const script = document.createElement("script");
              script.src = "/sign-up.js";
              document.head.appendChild(script);
              observer.unobserve(form);
            }
          });
        });
        observer.observe(form);
      });
    </script>
  </head>
  <body>
    <form action="/sign-up" method="post">
      <label for="email">Email:</label>
      <input type="email" id="email" name="email" required />
      <button type="submit">Sign Up</button>
    </form>
  </body>
</html>

Beste praksis:

  • Last disse skriptene på forespørsel, utløst av brukerhandlinger.
  • Bruk code-splitting-teknikker for å levere bare de delene som kreves ved hvert steg.
  • Injiser dem dynamisk bare når det er nødvendig, for eksempel når en bruker ruller til en bestemt seksjon.

Lab data is not enough.

I analyze your field data to find the edge cases failing your user experience.

Analyze My Data >>

  • Real User Data
  • Edge Case Detection
  • UX Focused
Optimalisering av JavaScript-prioritet for raskere sideinnlastingCore Web Vitals Optimalisering av JavaScript-prioritet for raskere sideinnlasting