Debuguj wydajność w terenie

Dowiedz się, jak przypisać dane o skuteczności za pomocą danych debugowania, aby wykrywać i rozwiązywać problemy użytkowników ze statystykami

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

  • Narzędzia do Laboratorium: narzędzia takie jak Lighthouse, w których strona wczytuje się w symulowanym środowisku, które może naśladować różne warunki (np. wolną sieć czy słabsze urządzenie mobilne).
  • Narzędzia terenowe: narzędzia takie jak Raport na temat użytkowania Chrome (CrUX), który opiera się na zbiorczych danych rzeczywistych użytkowników z Chrome. Pamiętaj, że dane z pomiarów zgłaszane przez narzędzia takie jak PageSpeed Insights i Search Console pochodzą z danych raportu na temat użytkowania Chrome.

Narzędzia w terenie dostarczają dokładniejsze dane, czyli dane, które odzwierciedlają rzeczywiste wrażenia użytkowników. Narzędzia laboratoryjne często są skuteczniejsze w identyfikowaniu i rozwiązywaniu problemów.

Dane raportu na temat użytkowania Chrome są bardziej reprezentatywne dla rzeczywistej skuteczności strony, ale poznanie jego wyników raczej nie pomoże w ustaleniu, jak poprawić wydajność.

Z kolei narzędzie Lighthouse wykryje problemy i zasugeruje sposoby ich ulepszenia. ale tylko w przypadku problemów z wydajnością wykrytych podczas wczytywania strony. Nie wykrywa problemów, które pojawiają się wyłącznie w wyniku interakcji użytkownika, takich jak przewijanie lub klikanie przycisków na stronie.

Pojawia się ważne pytanie: jak można zebrać informacje debugowania na potrzeby podstawowych wskaźników internetowych lub innych danych dotyczących wydajności od rzeczywistych użytkowników w terenie?

W tym poście szczegółowo omawiamy interfejsy API, za pomocą których można zbierać dodatkowe informacje debugowania dotyczące każdego z bieżących wskaźników podstawowych wskaźników internetowych, oraz podsuwamy pomysły na to, 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 to CLS jest chyba najważniejszym elementem, w przypadku którego zbieranie w tej dziedzinie informacji o debugowaniu jest najważniejsze. CLS jest mierzony przez cały okres istnienia strony, więc sposób interakcji użytkownika ze stroną – odległość przewijania, klikanie elementów itd. – może mieć znaczny wpływ na to, czy występują przesunięcia układu, i które elementy się przenoszą.

Zobacz następujący raport z PageSpeed Insights:

Raport PageSpeed Insights z różnymi wartościami CLS
PageSpeed Insights (o ile są dostępne) pokazuje dane z poszczególnych pól i z laboratoriów. Mogą się one różnić.

Wartości CLS z modułu (Lighthouse) w porównaniu z CLS z pola (dane CrUX) są całkiem inne. Warto to rozważyć, jeśli uważasz, że strona może zawierać dużo treści interaktywnych, które nie są używane podczas testowania w Lighthouse.

Ale nawet jeśli rozumiesz, że interakcje użytkownika wpływają na dane w polach, nadal musisz wiedzieć, które elementy na stronie się zmieniają, aby uzyskać wynik 0,28 w 75 centylu. Umożliwia to interfejs LayoutShiftAttribution.

Pobierz atrybucję przesunięcia układu

Interfejs LayoutShiftAttribution jest widoczny przy każdym wpisie layout-shift wysyłanym przez interfejs Layout Instability API.

Szczegółowe omówienie obu tych interfejsów znajdziesz w artykule Debugowanie przesunięć układu. Na potrzeby tego posta przede wszystkim musisz wiedzieć, że jako programista możesz obserwować każde przesunięcie układu zachodzące na stronie oraz ustalić, które elementy się przesuwają.

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

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

Mierzenie i wysyłanie danych do narzędzia analitycznego w przypadku każdego zachodzącego przesunięcia układu może nie być praktyczne. Jednak monitorując wszystkie zmiany, możesz śledzić najgorsze zmiany i raportować o nich informacje.

Nie mamy na celu identyfikacji i naprawiania poszczególnych przesunięć układu, które zachodzą u każdego użytkownika. Celem jest identyfikacja zmian, które wpływają na największą liczbę użytkowników, a tym samym największy wpływ na CLS strony na 75. percentylu.

Nie musisz też obliczać największego elementu źródłowego przy każdej zmianie. Jest to konieczne tylko wtedy, gdy chcesz wysłać wartość CLS do swojego narzędzia analitycznego.

Ten kod pobiera listę wpisów layout-shift, które zostały uwzględnione w CLS, i zwraca największy element źródłowy po wystąpieniu największego przesunięcia:

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 wpływającego na największą zmianę możesz zgłosić to w narzędziu analitycznym.

Element, który ma największy wpływ na CLS w przypadku danej strony, będzie się różnić w zależności od użytkownika, ale jeśli pogrupujesz te elementy wśród wszystkich użytkowników, będziesz w stanie wygenerować listę zmieniających się elementów, które wpływają na największą liczbę użytkowników.

Po znalezieniu i usunięciu głównej przyczyny zmian w tych elementach kod Analytics zacznie raportować mniejsze zmiany jako „najgorsze” dla stron. W końcu wszystkie raportowane zmiany będą na tyle niewielkie, że liczba stron mieści się w „dobrym” progu 0,1.

Inne metadane, które przydają się do przechwytywania wraz z największym elementem źródłowym shift, to:

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

Największe wyrenderowanie treści (LCP)

Aby debugować LCP w tym polu, musisz wiedzieć, który konkretnie element był największym elementem (kandydującym elementem LCP) podczas danego wczytywania strony.

Pamiętaj, że jest całkiem możliwe – w rzeczywistości jest to dość powszechne – że kandydujący element LCP będzie się różnić w zależności od użytkownika, nawet w przypadku dokładnie tej samej strony.

Taka sytuacja może mieć miejsce z kilku powodów:

  • Urządzenia użytkowników mają różną rozdzielczość ekranu, co powoduje odmienne układy stron i w widocznym obszarze widoczne różne elementy.
  • Użytkownicy nie zawsze wczytują strony, które znajdują się na samej górze. Linki często zawierają identyfikatory fragmentów, a nawet fragmenty tekstu, co oznacza, że strony mogą się wczytywać i wyświetlać w dowolnym miejscu przewijania strony.
  • Treści mogą być spersonalizowane pod kątem bieżącego użytkownika, więc kandydujący element LCP może się znacznie różnić w zależności od użytkownika.

Oznacza to, że nie można zakładać, który element lub zestaw elementów będzie najpopularniejszym elementem kandydującym do LCP w przypadku danej strony. Trzeba mierzyć takie wyniki na podstawie rzeczywistych zachowań użytkowników.

Określ element kandydujący LCP

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

Obserwując wpisy largest-contentful-paint, możesz określić bieżący element kandydujący LCP, patrząc na 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 znasz już element kandydujący LCP, możesz przesłać go do swojego narzędzia analitycznego razem z wartością danych. Podobnie jak w przypadku CLS, pomoże Ci to określić, które elementy należy zoptymalizować w pierwszej kolejności.

Oprócz kandydującego elementu LCP przydaje się też pomiar podczasów podpunktów LCP, ponieważ pomaga określić, jakie konkretne kroki optymalizacji są odpowiednie w przypadku Twojej witryny.

Od interakcji do kolejnego wyrenderowania (INP)

Najważniejsze informacje, które należy zarejestrować w polu INP, to:

  1. Z jakim elementem podjęto interakcję
  2. Dlaczego rodzaj interakcji
  3. kiedy miała miejsce interakcja;

Główną przyczyną powolnych interakcji jest zablokowany wątek główny, co może być częste podczas wczytywania JavaScriptu. Wiedza o tym, czy dochodzi do większości powolnych interakcji podczas wczytywania strony, pomaga określić, co trzeba zrobić, by rozwiązać problem.

Wskaźnik INP uwzględnia pełne opóźnienie interakcji, w tym czas potrzebny na uruchomienie zarejestrowanych detektorów zdarzeń, a także czas potrzebny na wyrenderowanie następnej klatki po uruchomieniu wszystkich detektorów zdarzeń. Oznacza to, że w przypadku INP warto wiedzieć, które elementy docelowe zwykle powodują powolne interakcje i jakie są rodzaje interakcji.

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

Ten kod nie pokazuje, jak określić, który wpis event należy do wartości INP, ponieważ ta logika jest bardziej skomplikowana. Jednak w tej sekcji wyjaśniamy, jak uzyskać te informacje za pomocą biblioteki JavaScript web- Vitals.

Użycie z biblioteką JavaScript Web Vitals

W poprzednich sekcjach znajdziesz ogólne sugestie i przykłady kodu, które umożliwiają rejestrowanie danych debugowania i uwzględnianie ich w danych wysyłanych do narzędzia analitycznego.

Od wersji 3 biblioteka web Vitals zawiera kompilację atrybucji, która wyświetla wszystkie te informacje, a także kilka dodatkowych sygnałów.

Poniższy przykładowy kod pokazuje, jak ustawić dodatkowy parametr zdarzenia (lub wymiar niestandardowy) zawierający ciąg debugowania, który pomaga w znalezieniu głównej przyczyny problemów z wydajnoś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);
onFID(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

Kod ten dotyczy tylko Google Analytics, ale ogólna zasada powinna się też przełożyć na inne narzędzia analityczne.

Pokazuje on też, jak generować raporty na temat 1 sygnału debugowania, ale przydaje się możliwość zbierania i raportowania wielu różnych sygnałów na podstawie każdego rodzaju danych.

Na przykład do debugowania wartości INP możesz potrzebować m.in. zbierania danych o elemencie, z którym nastąpiła interakcja, o typie interakcji, czasie, parametr loadState, fazach interakcji i inne (np. dane klatki długiej animacji).

Kompilacja atrybucji web-vitals udostępnia dodatkowe informacje o atrybucji, tak jak w tym przykładzie dla 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);
onFID(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

Pełną listę ujawnionych sygnałów debugowania znajdziesz w dokumentacji atrybucji Web Vitals.

Raportowanie i wizualizacja danych

Gdy zaczniesz zbierać informacje o debugowaniu wraz z wartościami danych, kolejnym krokiem będzie zebranie danych od wszystkich użytkowników, co pozwoli Ci szukać wzorców i trendów.

Jak wspomnieliśmy wcześniej, nie musisz rozwiązywać wszystkich problemów napotykanych przez użytkowników. W pierwszej kolejności musisz rozwiązywać problemy, które dotykają największej liczby użytkowników, czyli problemy, które mają największy negatywny wpływ na wyniki w Podstawowych wskaźnikach internetowych.

W przypadku GA4 przeczytaj specjalny artykuł o tworzeniu zapytań i wizualizacji danych za pomocą BigQuery.

Podsumowanie

Mamy nadzieję, że w tym poście pokazaliśmy konkretne sposoby wykorzystania istniejących interfejsów API wydajności i biblioteki web-vitals do uzyskiwania danych debugowania, które pomogą diagnozować wydajność na podstawie wizyt rzeczywistych użytkowników w terenie. Chociaż ten przewodnik skupia się na podstawowych wskaźnikach internetowych, pojęcia te mają też zastosowanie do debugowania wszelkich danych dotyczących wydajności, które można zmierzyć w języku JavaScript.

Jeśli dopiero zaczynasz mierzyć skuteczność, a korzystasz już z Google Analytics, możesz na początek użyć narzędzia do raportowania wskaźników internetowych, ponieważ obsługuje ono już raportowanie danych debugowania dotyczących danych podstawowych wskaźników internetowych.

Jeśli jesteś dostawcą usług analitycznych i chcesz ulepszyć swoje usługi i zapewnić użytkownikom więcej informacji na temat debugowania, rozważ zastosowanie niektórych z opisanych tu technik, ale nie ograniczaj się tylko do przedstawionych tu pomysłów. Ten post dotyczy wszystkich narzędzi analitycznych, jednak poszczególne narzędzia analityczne mogą (i powinny) zbierać i raportować jeszcze więcej informacji na potrzeby debugowania.

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