Zware JavaScript-modules identificeren

Zware JavaScript kan een nadelig effect hebben op zowel de laadprestaties van de pagina als de interactiviteit. Moderne web-apps zijn meer dan ooit afhankelijk van JavaScript uit meerdere bronnen. Dit omvat de app-code zelf (en de frameworkcode waarop deze is gebaseerd), evenals scripts van derden die functionaliteit toevoegen, zoals chatwidgets en videospelers. Analysescripts en marketingscripts achter de schermen zijn ook veelvoorkomende bijdragers die je makkelijk vergeet.

Het kan lastig zijn om de hoofdoorzaken van een niet-reagerende webpagina te achterhalen. Er is bepaalde expertise vereist om webprestaties te traceren of te profileren en de resultaten te interpreteren. Daarnaast verschillen veldgegevens vaak sterk van labgegevens, die maar een kleine subset van echte gebruikersscenario's nabootsen. Dit kan het moeilijk maken om de hoofdoorzaken van slechte prestaties te identificeren, vooral voor interacties.

De Long Animation Frames API is een lichte API die kan worden gebruikt om zware JavaScript in het veld te identificeren. Een zwaar script kan een enkel langlopend script zijn of een script dat meerdere keren wordt uitgevoerd tijdens de levenscyclus van de pagina.

Hoe wordt dit geïmplementeerd

Lange animatieframes worden gecontroleerd via de PerformanceObserver-interface. Er wordt een long-animation-frame-vermelding gemaakt als de weergave van een animatieframe langer dan 50 ms duurt. De invoer bevat informatie over het lange animatieframe, waaronder de duur van het frame en de scripts die tijdens het frame zijn uitgevoerd.

De invoer long-animation-frame bevat een property scripts. Dit is een matrix van PerformanceScript-objecten. Elk PerformanceScript-object bevat informatie over het script dat is uitgevoerd tijdens het lange animatieframe, waaronder de sourceURL en duration van het script.

Voorbeeld van hoe je de langstlopende scripts herkent die bijdragen aan lange animatieframes

// Accumulate all script entries across the page lifecycle so no
// data is lost between observer callbacks.
const allScripts = [];

const observer = new PerformanceObserver(list => {
  // Collect all script entries across frames to find the biggest offenders.
  allScripts.push(...list.getEntries().flatMap(entry => entry.scripts));

  // Group by sourceURL so you can identify which scripts contribute
  // the most total time, even if each individual invocation is short.
  const scriptSource = [...new Set(allScripts.map(script => script.sourceURL))];
  const scriptsBySource = scriptSource.map(sourceURL => ([sourceURL,
      allScripts.filter(script => script.sourceURL === sourceURL)
  ]));
  const processedScripts = scriptsBySource.map(([sourceURL, scripts]) => ({
    sourceURL,
    count: scripts.length,
    totalDuration: scripts.reduce((subtotal, script) => subtotal + script.duration, 0)
  }));

  // Only include scripts above a certain threshold to reduce noise.
  const heavyScripts = processedScripts.filter(script => {
    return script.totalDuration > 100;
  });

  // Sort by total duration so the worst offenders appear first,
  // making it easier to prioritize optimization efforts.
  heavyScripts.sort((a, b) => b.totalDuration - a.totalDuration);

  // Log to the console for local debugging. In production, replace
  // this with a call to send the data to your analytics service.
  console.table(heavyScripts);
});

// Use buffered: true to capture any long frames that occurred before
// this observer was registered.
observer.observe({type: 'long-animation-frame', buffered: true});

Praktische tips

  • Geef de voorkeur aan de Long Animation Frames API boven alternatieven zoals de JS Self-Profiling API, die een hogere runtime-overhead heeft.
  • VAT de belangrijkste informatie samen, omdat de Long Animation Frames API veel details bevat.
  • WEL de vereiste informatie naar een analyseservice in productie sturen.

Browserondersteuning en fallback-strategieën

De Long Animation Frames API wordt genegeerd door browsers die deze niet ondersteunen. Je kunt de API dus veilig gebruiken zonder fallbacks. In de meeste gevallen zijn de prestatieverbeteringen die de tool vindt ook van toepassing op andere browsers.