Identyfikowanie obciążającego kodu JavaScript

Intensywne wykonywanie kodu JavaScript może mieć negatywny wpływ zarówno na wydajność wczytywania strony, jak i na interaktywność. Nowoczesne aplikacje internetowe są bardziej niż kiedykolwiek wcześniej zależne od kodu JavaScript z różnych źródeł. Obejmuje to sam kod aplikacji (i kod platformy, na której się opiera), a także skrypty innych firm, które dodają funkcje, takie jak widżety czatu i odtwarzacze wideo. Często zapomina się też o skryptach analitycznych i marketingowych działających w tle.

Zidentyfikowanie głównych przyczyn braku odpowiedzi strony internetowej może być trudne, ponieważ wymaga specjalistycznej wiedzy na temat śledzenia lub profilowania wydajności sieci oraz interpretowania wyników. Ponadto dane zgromadzone w terenie często bardzo się różnią od danych laboratoryjnych, które odzwierciedlają tylko niewielki podzbiór rzeczywistych scenariuszy użytkowników. Może to utrudnić identyfikację głównych przyczyn niskiej wydajności, zwłaszcza w przypadku interakcji.

Interfejs Long Animation Frames API to lekki interfejs API, który może służyć do identyfikowania intensywnie działającego kodu JavaScript w terenie. Skrypt, który obciąża zasoby, może być pojedynczym skryptem, który działa przez długi czas, lub skryptem, który działa wielokrotnie podczas cyklu życia strony.

Jak to zrobić?

Długie klatki animacji są monitorowane za pomocą interfejsu PerformanceObserver. Wpis long-animation-frame jest generowany, gdy renderowanie klatki animacji trwa dłużej niż 50 ms. Wpis zawiera informacje o długiej klatce animacji, w tym o czasie jej trwania i skryptach, które zostały wykonane podczas jej wyświetlania.

Wpis long-animation-frame zawiera właściwość scripts, która jest tablicą obiektów PerformanceScript. Każdy obiekt PerformanceScript zawiera informacje o skrypcie, który został wykonany podczas długiej klatki animacji, w tym sourceURL i duration skryptu.

Przykład identyfikowania najdłużej działających skryptów, które przyczyniają się do powstawania długich klatek animacji

// 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});

Sprawdzone metody

  • ZALECAMY używanie interfejsu Long Animation Frames API zamiast alternatywnych rozwiązań, takich jak JS Self-Profiling API, które wiążą się z większym obciążeniem w czasie działania.
  • PODSUMUJ najważniejsze informacje, ponieważ interfejs Long Animation Frames API zawiera wiele szczegółów.
  • WYŚLIJ wymagane informacje do usługi analitycznej w środowisku produkcyjnym.

Obsługa przeglądarek i strategie zastępcze

Interfejs Long Animation Frames API jest ignorowany przez przeglądarki, które go nie obsługują, więc można go bezpiecznie używać bez rozwiązań zastępczych. W większości przypadków możliwości poprawy wydajności, które zidentyfikuje, będą dotyczyć również innych przeglądarek.