Debuguj wydajność w terenie

Dowiedz się, jak przypisywać dane o wydajności do informacji debugowania, aby łatwiej było Ci identyfikować i rozwiązywać problemy dotyczące rzeczywistych użytkowników za pomocą funkcji analitycznych

Google udostępnia 2 kategorie narzędzi do pomiaru i debugowania skuteczności:

  • Narzędzia laboratoryjne: narzędzia takie jak Lighthouse, w których przypadku strona jest wczytywana w symulowanym środowisku, które może symulować różne warunki (np. wolną sieć i niedrogowe urządzenie mobilne).
  • Narzędzia dotyczące danych z pól: narzędzia takie jak raport na temat użytkowania Chrome (CrUX), który jest oparty na zbiorczych danych o użytkownikach Chrome. Pamiętaj, że dane pól raportowane przez narzędzia takie jak PageSpeed InsightsSearch Console pochodzą z danych CrUX.

Narzędzia terenowe zapewniają dokładniejsze dane, które odzwierciedlają rzeczywiste wrażenia użytkowników, ale narzędzia laboratoryjne często lepiej pomagają w identyfikowaniu i rozwiązywaniu problemów.

Dane CrUX lepiej odzwierciedlają rzeczywistą skuteczność strony, ale znajomość wyników CrUX nie pomoże Ci zwiększyć jej skuteczności.

Z drugiej strony Lighthouse wskazuje problemy i podaje konkretne sugestie dotyczące ich rozwiązania. Lighthouse będzie jednak podawać sugestie tylko w przypadku problemów z wydajnością, które wykryje w momencie wczytywania strony. Nie wykrywa problemów, które występują tylko w wyniku interakcji użytkownika, takich jak przewijanie lub klikanie przycisków na stronie.

W związku z tym pojawia się ważne pytanie: jak możesz rejestrować informacje debugowania dotyczące podstawowych wskaźników internetowych lub innych danych o wydajności, które pochodzą od rzeczywistych użytkowników?

W tym artykule szczegółowo opisujemy, których interfejsów API możesz używać do zbierania dodatkowych informacji debugujących dla każdego z obecnych podstawowych wskaźników internetowych. Podpowiadamy też, jak rejestrować te dane w dotychczasowym narzędziu analitycznym.

Interfejsy API do atrybucji i debugowania

Skumulowane przesunięcie układu (CLS)

Spośród wszystkich podstawowych wskaźników internetowych CLS jest prawdopodobnie tym, dla którego zbieranie informacji debugujących w polu jest najważniejsze. Wartość CLS jest mierzona przez cały okres istnienia strony, więc sposób, w jaki użytkownik z niej korzysta (jak daleko przewija stronę, co klika itp.), może mieć znaczący wpływ na to, czy występują przesunięcia układu i które elementy się przesuwają.

Rozważ ten raport z PageSpeed Insights:

Raport PageSpeed Insights z różnymi wartościami CLS
W przypadku dostępności danych terenowych i laboratoryjnych narzędzie PageSpeed Insights pokazuje oba typy danych, które mogą się różnić

Wartość CLS z testów laboratoryjnych (Lighthouse) w porównaniu z wartością CLS z testów terenowych (dane z raportu CrUX) jest dość różna, co ma sens, jeśli weźmiemy pod uwagę, że strona może zawierać dużo interaktywnych treści, których nie wykorzystuje się podczas testów w Lighthouse.

Nawet jeśli wiesz, że interakcja użytkownika wpływa na dane w polu, musisz wiedzieć, które elementy na stronie się zmieniają, aby uzyskać wynik 0,28 w 75.percentylu. Umożliwia to interfejs LayoutShiftAttribution.

Uzyskiwanie atrybucji przesunięć układu

Interfejs LayoutShiftAttribution jest dostępny w przypadku każdego wpisu layout-shift, który generuje interfejs API niestabilności układu.

Szczegółowe omówienie obu tych interfejsów znajdziesz w artykule Zmiana układu na potrzeby debugowania. W ramach tego artykułu najważniejsze jest to, że jako deweloper możesz obserwować każdą zmianę układu na stronie, a także które elementy się zmieniają.

Oto przykładowy kod, który rejestruje każde przesunięcie układu oraz elementy, które się przesunęły:

new PerformanceObserver((list) => {
  for (const {value, startTime, sources} of list.getEntries()) {
    // Log the shift amount and other entry info.
    console.log('Layout shift:', {value, startTime});
    if (sources) {
      for (const {node, curRect, prevRect} of sources) {
        // Log the elements that shifted.
        console.log('  Shift source:', node, {curRect, prevRect});
      }
    }
  }
}).observe({type: 'layout-shift', buffered: true});

Prawdopodobnie nie jest praktyczne mierzenie i przesyłanie danych do narzędzia analitycznego w przypadku każdego wystąpienia zmiany układu. Jednak dzięki monitorowaniu wszystkich zmian możesz śledzić najgorsze zmiany i wysyłać tylko informacje o nich.

Celem nie jest identyfikowanie i naprawianie każdego przesunięcia układu, które występuje u każdego użytkownika, ale identyfikowanie przesunięć, które wpływają na największą liczbę użytkowników i tym samym w największym stopniu wpływają na CLS strony w 75. percentylu.

Nie musisz też obliczać największego elementu źródłowego za każdym razem, gdy nastąpi zmiana. Wystarczy, że zrobisz to, gdy będziesz gotowy wysłać wartość CLS do narzędzia analitycznego.

Podany niżej kod pobiera listę wpisów layout-shift, które przyczyniły się do CLS, i zwraca największy element źródłowy z największym przesunięciem:

function getCLSDebugTarget(entries) {
  const largestEntry = entries.reduce((a, b) => {
    return a && a.value > b.value ? a : b;
  });
  if (largestEntry && largestEntry.sources && largestEntry.sources.length) {
    const largestSource = largestEntry.sources.reduce((a, b) => {
      return a.node && a.previousRect.width * a.previousRect.height >
          b.previousRect.width * b.previousRect.height ? a : b;
    });
    if (largestSource) {
      return largestSource.node;
    }
  }
}

Po zidentyfikowaniu największego elementu, który przyczynił się do największej zmiany, możesz przekazać tę informację do narzędzia analitycznego.

Element, który najbardziej wpływa na CLS na danej stronie, prawdopodobnie będzie się różnić w zależności od użytkownika, ale jeśli zsumujesz te elementy dla wszystkich użytkowników, będziesz mieć możliwość wygenerowania listy elementów, które wpływają na największą liczbę użytkowników.

Gdy znajdziesz i usuniesz główną przyczynę zmian tych elementów, kod Analytics zacznie raportować mniejsze zmiany jako „największe” zmiany na stronach. Ostatecznie wszystkie zgłoszone przesunięcia będą na tyle małe, że Twoje strony będą się mieścić w dopuszczalnym progu 0,1.

Inne metadane, które warto rejestrować wraz z elementem źródła o największej zmianie:

  • Czas największej zmiany
  • Ścieżka URL w momencie największej zmiany (w przypadku witryn, które dynamicznie aktualizują adres URL, np. aplikacji jednostronicowych).

Największe wyrenderowanie treści (LCP)

Aby debugować LCP w polu, musisz znać element, który był największym elementem (elementem kandydującym do LCP) podczas wczytywania danej strony.

Pamiętaj, że możliwe (a w zasadzie dość prawdopodobne) jest, że element kandydujący do LCP będzie się różnić w zależności od użytkownika, nawet w przypadku tej samej strony.

Dzieje się tak z kilku powodów:

  • Urządzenia użytkowników mają różne rozdzielczości ekranu, co powoduje różne układy stron, a w konsekwencji różne elementy widoczne w widocznym obszarze.
  • Użytkownicy nie zawsze wczytują strony przewinięte do samego końca. Linki często zawierają identyfikatory fragmentów lub nawet fragmenty tekstu, co oznacza, że strony mogą być wczytywane i wyświetlane w dowolnym miejscu na stronie.
  • Treści mogą być spersonalizowane dla danego użytkownika, więc element kandydujący do LCP może się znacznie różnić w zależności od użytkownika.

Oznacza to, że nie możesz zakładać, który element lub zestaw elementów będzie najczęściej występującym elementem kandydującym do LCP na danej stronie. Musisz je mierzyć na podstawie zachowań rzeczywistych użytkowników.

Określanie elementu kandydującego do LCP

Aby określić element kandydujący do LCP w JavaScript, możesz użyć interfejsu Largest Contentful Paint API, czyli tego samego interfejsu API, którego używasz do określenia wartości czasu LCP.

Obserwując wpisy largest-contentful-paint, możesz określić aktualny element kandydujący do LCP, sprawdzając właściwość element ostatniego wpisu:

new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lastEntry = entries[entries.length - 1];

  console.log('LCP element:', lastEntry.element);
}).observe({type: 'largest-contentful-paint', buffered: true});

Gdy już poznasz element kandydujący do LCP, możesz go wysłać do narzędzia analitycznego wraz z wartością danych. Podobnie jak w przypadku CLS, pomoże Ci to określić, które elementy należy najpierw zoptymalizować.

Oprócz elementu kandydującego LCP może być też przydatne mierzenie czasów poszczególnych części LCP, co może pomóc w określaniu, które konkretne kroki optymalizacji są odpowiednie dla Twojej witryny.

Interakcja do kolejnego wyrenderowania (INP)

Najważniejsze informacje, które należy podać w polu dotyczącym INP:

  1. Z jakim elementem nastąpiła interakcja
  2. Typ interakcji
  3. Kiedy doszło do interakcji

Główną przyczyną powolnego działania interakcji jest zablokowany wątek główny, co może być częstym zjawiskiem podczas wczytywania kodu JavaScript. Wiedza o tym, czy większość wolnych interakcji występuje podczas wczytywania strony, pomaga określić, co należy zrobić, aby rozwiązać problem.

Dane INP uwzględniają pełny czas oczekiwania na interakcję, w tym czas potrzebny na wykonanie wszystkich zarejestrowanych odbiorników zdarzeń, a także czas potrzebny na wyrenderowanie następnego obrazu po wykonaniu wszystkich odbiorników zdarzeń. Oznacza to, że w przypadku INP przydatne jest poznanie elementów docelowych, które powodują spowolnienie interakcji, oraz rodzajów tych interakcji.

Poniższy kod rejestruje element docelowy i czas wpisu INP.

function logINPDebugInfo(inpEntry) {
  console.log('INP target element:', inpEntry.target);
  console.log('INP interaction type:', inpEntry.name);
  console.log('INP time:', inpEntry.startTime);
}

Pamiętaj, że ten kod nie pokazuje, jak określić, które pole event jest polem INP, ponieważ ta logika jest bardziej skomplikowana. W następującej sekcji wyjaśniono, jak uzyskać te informacje za pomocą biblioteki JavaScript web-vitals.

Używanie z biblioteką JavaScript web-vitals

W poprzednich sekcjach znajdziesz ogólne wskazówki i przykłady kodu, które pomogą Ci rejestrować informacje debugowania, aby uwzględniać je w danych przesyłanych do narzędzia analitycznego.

Od wersji 3 biblioteka JavaScript web-vitals zawiera kompilację atrybucji, która udostępnia wszystkie te informacje, a także kilka dodatkowych sygnałów.

Poniższy przykładowy kod pokazuje, jak ustawić dodatkowy parametry wydarzenia (lub wymiar niestandardowy), który zawiera ciąg debugowania, ułatwiający identyfikację głównej przyczyny problemów ze skutecznością.

import {onCLS, onINP, onLCP} from 'web-vitals/attribution';

function sendToGoogleAnalytics({name, value, id, attribution}) {
  const eventParams = {
    metric_value: value,
    metric_id: id,
  }

  switch (name) {
    case 'CLS':
      eventParams.debug_target = attribution.largestShiftTarget;
      break;
    case 'LCP':
      eventParams.debug_target = attribution.element;
      break;
    case 'INP':
      eventParams.debug_target = attribution.interactionTarget;
      break;
  }

  // Assumes the global `gtag()` function exists, see:
  // https://developers.google.com/analytics/devguides/collection/ga4
  gtag('event', name, eventParams);
}

onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

Ten kod jest przeznaczony do Google Analytics, ale ogólna idea powinna się sprawdzić również w przypadku innych narzędzi analitycznych.

Ten kod pokazuje też, jak tworzyć raporty na podstawie jednego sygnału debugowania, ale przydatne jest zbieranie i raportowanie wielu różnych sygnałów na podstawie jednej metryki.

Na przykład, aby debugować INP, możesz zbierać informacje o elemencie, z którym następuje interakcja, typ interakcji, czas, stan ładowania, fazy interakcji i inne (np. dane o długim klatce animacji).

Wersja atrybucji web-vitals ujawnia dodatkowe informacje o atrybucji, jak pokazano w tym przykładzie w przypadku INP:

import {onCLS, onINP, onLCP} from 'web-vitals/attribution';

function sendToGoogleAnalytics({name, value, id, attribution}) {
  const eventParams = {
    metric_value: value,
    metric_id: id,
  }

  switch (name) {
    case 'INP':
      eventParams.debug_target = attribution.interactionTarget;
      eventParams.debug_type = attribution.interactionType;
      eventParams.debug_time = attribution.interactionTime;
      eventParams.debug_load_state = attribution.loadState;
      eventParams.debug_interaction_delay = Math.round(attribution.inputDelay);
      eventParams.debug_processing_duration = Math.round(attribution.processingDuration);
      eventParams.debug_presentation_delay =  Math.round(attribution.presentationDelay);
      break;

    // Additional metric logic...
  }

  // Assumes the global `gtag()` function exists, see:
  // https://developers.google.com/analytics/devguides/collection/ga4
  gtag('event', name, eventParams);
}

onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

Pełną listę dostępnych sygnałów debugowania znajdziesz w dokumentacji dotyczącej przypisywania danych wskaźników internetowych.

Raportowanie i wizualizowanie danych

Po rozpoczęciu zbierania informacji debugowania wraz z wartościami danych następnym krokiem jest zgrupowanie danych dotyczących wszystkich użytkowników, aby można było zacząć szukać wzorców i trendów.

Jak już wspomnieliśmy, nie musisz rozwiązywać wszystkich problemów, z którymi spotykają się użytkownicy. Zwróć uwagę przede wszystkim na problemy, które dotyczą największej liczby użytkowników, ponieważ to one mają największy negatywny wpływ na wyniki metryk Core Web Vitals.

W przypadku GA4 zapoznaj się z artykułem poświęconym wykonywaniu zapytań i wizualizacji danych za pomocą BigQuery.

Podsumowanie

Mamy nadzieję, że ten artykuł pomógł Ci poznać sposoby korzystania z dotychczasowych interfejsów API dotyczących wydajności i biblioteki web-vitals, aby uzyskiwać informacje debugowania, które ułatwiają diagnozowanie wydajności na podstawie wizyt rzeczywistych użytkowników. Ten przewodnik skupia się na podstawowych wskaźnikach internetowych, ale omawiane w nim zagadnienia mają też zastosowanie do debugowania wszelkich danych dotyczących wydajności, które można mierzyć w JavaScript.

Jeśli dopiero zaczynasz mierzyć skuteczność i korzystasz już z Google Analytics, dobrym punktem wyjścia może być narzędzie Raport podstawowych wskaźników internetowych, które obsługuje już raportowanie informacji debugujących dotyczących podstawowych wskaźników internetowych.

Jeśli jesteś dostawcą usług analitycznych i chcesz ulepszyć swoje produkty oraz udostępnić użytkownikom więcej informacji do debugowania, rozważ zastosowanie opisanych tutaj technik, ale nie ograniczaj się tylko do przedstawionych tu pomysłów. Ten post ma zastosowanie do wszystkich narzędzi analitycznych, ale poszczególne narzędzia analityczne mogą (i powinny) rejestrować i przekazywać jeszcze więcej informacji debugujących.

Jeśli uważasz, że nie możesz debugować tych danych z powodu braku funkcji lub informacji w samych interfejsach API, prześlij opinię na adres web-vitals-feedback@googlegroups.com.