Largest Contentful Paint (LCP)

Obsługa przeglądarek

  • Chrome: 77.
  • Krawędź: 79.
  • Firefox: 122.
  • Safari: nieobsługiwane.

Źródło

W przeszłości twórcy stron internetowych musieli mieć problem z określeniem, jak szybko wczytuje się główna treść strony i jest ona widoczna dla użytkowników. Starsze dane, takie jak load czy DOMContentLoaded, nie sprawdzają się dobrze, ponieważ niekoniecznie odpowiadają temu, co użytkownik widzi na ekranie. A nowsze, zorientowane na użytkownika dane o wydajności, takie jak Pierwsze wyrenderowanie treści (FCP), rejestrują tylko sam początek wczytywania treści. Jeśli na stronie wyświetla się ekran powitalny lub wskaźnik wczytywania, ten moment nie jest zbyt istotny dla użytkownika.

W przeszłości zalecaliśmy korzystanie z danych dotyczących wydajności, takich jak Pierwsze wyrenderowanie (FMP) i Wskaźnik szybkości (SI) (oba elementy dostępne w Lighthouse), aby ułatwić uchwycenie procesu wczytywania po pierwszym wyrenderowaniu. Są one jednak złożone, trudne do wyjaśnienia i często błędne, co oznacza, że nadal nie rozpoznają, kiedy główna zawartość strony została wczytana.

Na podstawie dyskusji w grupie roboczej W3C ds. wydajności stron internetowych oraz badań przeprowadzonych w Google stwierdziliśmy, że dokładniejszym sposobem pomiaru czasu wczytania głównej zawartości strony jest sprawdzenie, kiedy renderowany jest największy element.

Co to jest LCP?

LCP odpowiada czasowi renderowania największego obrazu, bloku tekstu lub filmu w widocznym obszarze w odniesieniu do czasu, w którym użytkownik po raz pierwszy otworzył stronę.

Jaki jest dobry wynik LCP?

Aby zapewnić użytkownikom wygodę, witryny powinny mieć czas Largest Contentful Paint wynoszący 2,5 sekund lub krócej. Aby mieć pewność, że osiągasz ten cel w przypadku większości użytkowników, warto mierzyć 50. percentyl wczytywania stron podzielony na urządzenia mobilne i komputery.

Dobre wartości LCP to 2,5 sekundy lub mniej, złe wartości to więcej niż 4,0 sekundy, a wszystkie wartości pośrednie wymagają poprawy
Dobra wartość LCP wynosi maksymalnie 2,5 sekundy.

Jakie elementy są brane pod uwagę?

Zgodnie z obecnie określonym w największym wyrenderowaniu treści API, czyli typy elementów, brane pod uwagę w przypadku największego wyrenderowania treści, to:

  • <img> (czas wyświetlania pierwszego kadru jest używany w przypadku treści animowanych, takich jak GIF-y lub animowane PNG-y);
  • Elementy <image> wewnątrz elementu <svg>
  • <video> (używany jest czas wczytywania obrazu plakatu lub czas wyświetlania pierwszego klatki w przypadku filmów – w zależności od tego, co jest wcześniejsze);
  • Element z obrazem tła wczytanym za pomocą funkcji url() (a nie gradientu CSS).
  • Elementy na poziomie bloku zawierające węzły tekstowe lub inne elementy podrzędne elementów tekstowych na poziomie wbudowanego.

Ograniczenie elementów do tego ograniczonego zbioru było celowe, aby na początku zachować prostotę. W przyszłości, gdy przeprowadzimy więcej badań, możemy dodać dodatkowe elementy (np. pełną obsługę <svg>).

Oprócz uwzględniania tylko niektórych elementów pomiary LCP korzystają z heurystyki, aby wykluczać elementy, które użytkownicy prawdopodobnie uznają za „nietreści”. W przypadku przeglądarek opartych na Chromium:

  • Elementy o przezroczystości 0, które są niewidoczne dla użytkownika
  • Elementy, które zajmują cały widoczny obszar i są raczej traktowane jako tło niż treść.
  • obrazy zastępcze lub inne obrazy o niskiej entropii, które prawdopodobnie nie odzwierciedlają prawdziwej zawartości strony;

Przeglądarki będą prawdopodobnie ulepszać działanie heurystyki, aby spełniać oczekiwania użytkowników dotyczące największego elementu contentful.

Takie „treść” dane heurystyczne mogą różnić się od tych używanych w funkcji First Contentful Paint (FCP), która może uwzględniać niektóre z tych elementów, np. obrazy zastępcze lub obrazy w pełnym widocznym obszarze, nawet jeśli nie kwalifikują się do udziału w programie LCP. Mimo że w obu przypadkach użyto określenia „contentful” cel tych danych jest inny. FCP mierzy, kiedy jakakolwiek treść jest malowana na ekranie i LCP, gdy główna treść jest malowana, tak aby LCP był bardziej selektywny.

Jak określa się rozmiar elementu?

Rozmiar elementu zgłaszanego dla LCP to zwykle rozmiar, który jest widoczny dla użytkownika w widocznym obszarze. Jeśli element wykracza poza widoczny obszar albo jeśli którykolwiek z elementów jest przycięty lub ma niewidoczne przepełnienie, te części nie wliczają się do jego rozmiaru.

W przypadku elementów obrazu, których rozmiar został zmieniony w stosunku do właściwego rozmiaru, rozmiar, który jest zgłaszany, to widoczny rozmiar lub właściwy rozmiar, zależnie od tego, który z nich jest mniejszy.

W przypadku elementów tekstowych LCP uwzględnia tylko najmniejszy prostokąt, który może zawierać wszystkie węzły tekstowe.

W przypadku wszystkich elementów LCP nie uwzględnia marginesów, wypełnień ani obramowań zastosowanych za pomocą kodu CSS.

Kiedy jest raportowany LCP?

Strony internetowe często wczytują się etapami, w rezultacie największy z nich może się zmienić.

Aby wykorzystać potencjał zmian, przeglądarka wysyła PerformanceEntry typu largest-contentful-paint identyfikujący największy element treści zaraz po wyrenderowaniu pierwszej klatki przez przeglądarkę. Jednak po wyrenderowaniu kolejnych klatek wysyła kolejny PerformanceEntry za każdym razem, gdy zmieni się największy element treści.

Na przykład na stronie z tekstem i banerem powitalnym przeglądarka może początkowo tylko wyrenderować tekst – wtedy przeglądarka wysyła wpis largest-contentful-paint, którego właściwość element prawdopodobnie odwołuje się do <p> lub <h1>. Później, po zakończeniu wczytywania banera powitalnego, wysyłany jest drugi wpis largest-contentful-paint, a jego właściwość element odwoływała się do <img>.

Element może być uznany za największy element treści tylko po tym, jak zostanie wyrenderowany i zostanie wyświetlony użytkownikowi. Obrazy, które nie zostały jeszcze wczytane, nie są uważane za „wyrenderowane”. Nie są to też węzły tekstowe, które używają czcionek internetowych w okresie blokowania czcionek. W takich przypadkach mniejszy element może zostać zgłoszony jako największy element treści, ale gdy tylko większy element zakończy renderowanie, zostanie utworzony inny element PerformanceEntry.

Oprócz wczytywania obrazów i czcionek w później fazie strona może dodawać do DOM nowe elementy, gdy stają się dostępne nowe treści. Jeśli dowolny z tych nowych elementów jest większy niż poprzedni największy element treści, w raportach pojawi się również nowy PerformanceEntry.

Jeśli największy element treści zostanie usunięty z widocznego obszaru lub nawet z DOM, pozostanie największym elementem treści, dopóki nie zostanie wyrenderowany większy element.

Przeglądarka przestanie rejestrować nowe wpisy, gdy użytkownik wejdzie w interakcję ze stroną (kliknie ją, przewinie lub naciśnie klawisz), ponieważ interakcja użytkownika często zmienia to, co jest widoczne dla użytkownika (szczególnie w przypadku przewijania).

Na potrzeby analiz należy zgłaszać do usługi analitycznej tylko ostatnio wysłane dane typu PerformanceEntry.

Czas wczytywania a czas renderowania

Ze względów bezpieczeństwa sygnatura czasowa renderowania obrazów nie jest widoczna w przypadku obrazów z innych domen, które nie mają nagłówka Timing-Allow-Origin. Zamiast tego udostępniany jest tylko czas ich wczytywania (ponieważ jest on już udostępniany przez wiele innych interfejsów API).

Może to prowadzić do pozornie niemożliwej sytuacji, w której LCP jest zgłaszany przez internetowe interfejsy API z wyprzedzeniem FCP. Nie jest to prawda, ale tak się dzieje z powodu tego ograniczenia bezpieczeństwa.

Zalecamy, aby w miarę możliwości zawsze ustawiać nagłówek Timing-Allow-Origin, aby dane były dokładniejsze.

Jak są obsługiwane zmiany układu i rozmiaru elementów?

Aby zmniejszyć nakład pracy związany z wydajnością, który wiąże się z obliczaniem i wysyłaniem nowych wpisów dotyczących skuteczności, zmiany rozmiaru lub pozycji elementu nie generują nowych kandydatów LCP. Uwzględniane są tylko początkowy rozmiar i położenie elementu w widocznym obszarze.

Oznacza to, że obrazy, które początkowo są renderowane poza ekranem, a potem przechodzą na ekran, mogą nie zostać zgłoszone. Oznacza to też, że elementy początkowo renderowane w widocznym obszarze, które następnie zostają przesunięte w dół, poza widok, nadal będą miały początkowy rozmiar w widocznym obszarze.

Przykłady

Oto kilka przykładów sytuacji, w których Largest Contentful Paint występuje w kilku popularnych witrynach:

Oś czasu największego wyrenderowania treści z cnn.com
Oś czasu LCP z cnn.com.
Oś czasu największego wyrenderowania treści z techcrunch.com
Oś czasu LCP z techcrunch.com.

Na obu powyższych osiach czasu największy element zmienia się podczas wczytywania treści. W pierwszym przykładzie do DOM-u dodano nowe treści, co zmienia element o największym rozmiarze. W drugim przykładzie układ się zmienia, a treści, które były wcześniej największe, są usuwane z widocznego obszaru.

Chociaż często zdarza się, że wczytywane później treści są większe niż te, które już są na stronie, nie zawsze tak jest. W następnych 2 przykladach LCP występuje przed pełnym załadowaniem strony.

Oś czasu największego wyrenderowania treści z instagram.com
Oś czasu LCP z instagram.com
Oś czasu największego wyrenderowania treści z google.com
Oś czasu LCP z google.com.

W pierwszym przykładzie logo Instagrama jest ładowane stosunkowo wcześnie i pozostawia największym elementem, mimo że stopniowo wyświetlają się inne treści. W przykładzie strony z wynikami wyszukiwania Google największym elementem jest akapit tekstu, który wyświetla się, zanim wczytanie obrazów lub logo zostanie ukończone. Ponieważ wszystkie poszczególne obrazy są mniejsze niż ten akapit, pozostaje on największym elementem w trakcie całego procesu wczytywania.

Jak mierzyć LCP

LCP można mierzyć w laboratorium lub w warunkach rzeczywistych. Jest on dostępny w tych narzędziach:

Narzędzia w polu

Narzędzia laboratoryjne

Pomiar LCP w języku JavaScript

Aby mierzyć LCP w JavaScript, możesz użyć interfejsu API największego wyrenderowania treści. Przykład poniżej pokazuje, jak utworzyć obiekt PerformanceObserver, który nasłuchuje wpisów largest-contentful-paint i rejestruje je w konsoli.

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    console.log('LCP candidate:', entry.startTime, entry);
  }
}).observe({type: 'largest-contentful-paint', buffered: true});

W tym przykładzie każdy zapisany wpis largest-contentful-paint reprezentuje obecnego kandydata LCP. Zazwyczaj wartość startTime ostatniego wyemitowanego wpisu to wartość LCP, ale nie zawsze tak jest. Nie wszystkie wpisy largest-contentful-paint są prawidłowe do pomiaru LCP.

W tej sekcji opisujemy różnice między danymi w raportach interfejsu API a sposobem obliczania danych.

Różnice między danymi a interfejsem API

  • Interfejs API wyśle rekordy largest-contentful-paint dla stron wczytywanych na karcie w tle, ale te strony powinny być ignorowane podczas obliczania LCP.
  • Po przejściu strony na drugi plan interfejs API nadal będzie wysyłać wpisy largest-contentful-paint, ale te wpisy powinny być ignorowane podczas obliczania LCP (elementy mogą być brane pod uwagę tylko wtedy, gdy strona była cały czas na pierwszym planie).
  • Interfejs API nie zgłasza wpisów largest-contentful-paint po przywróceniu strony z pamięci podręcznej stanu strony internetowej, ale w takich przypadkach należy mierzyć LCP, ponieważ użytkownicy odnotowują je jako odrębne wizyty na stronie.
  • Interfejs API nie uwzględnia elementów w ramkach iframe, ale dane tak, ponieważ są one częścią wrażeń użytkownika. Na stronach z parametrem LCP w elemencie iframe – na przykład w obrazie plakatu w umieszczonym filmie – będzie to wyróżniać się jako różnica między CrUX a RUM. Aby prawidłowo mierzyć LCP, należy je wziąć pod uwagę. Ramki podrzędne mogą używać interfejsu API do zgłaszania wpisów largest-contentful-paint do ramki nadrzędnej w celu agregacji.
  • Interfejs API mierzy LCP od momentu rozpoczęcia nawigacji, ale w przypadku stron z renderowaniem wstępnym czas LCP powinien być mierzony od activationStart, ponieważ odpowiada on temu, jak długo użytkownik odczuwa czas LCP.

Zamiast zapamiętywać te subtelne różnice, programiści mogą używać biblioteki JavaScript web-vitals do pomiaru LCP, która załatwia te różnice (w miarę możliwości – zwróć uwagę, że problem z iframe nie jest uwzględniany):

import {onLCP} from 'web-vitals';

// Measure and log LCP as soon as it's available.
onLCP(console.log);

Pełny przykład pomiaru LCP w języku JavaScript znajdziesz w kodzie źródłowym tagu onLCP().

Co zrobić, jeśli największy element nie jest najważniejszy?

W niektórych przypadkach najważniejszy element (lub elementy) na stronie nie jest taki sam jak największy element, a programiści mogą być zainteresowani pomiarem czasu renderowania pozostałych elementów. Jest to możliwe dzięki interfejsowi Element Timing API, jak opisano w artykule o wskaźnikach niestandardowych.

Jak poprawić LCP

Pełny przewodnik dotyczący optymalizacji LCP pomoże Ci w określaniu wartości LCP w warunkach rzeczywistych i w optymalizacji tych wartości za pomocą danych z testów laboratoryjnych.

Dodatkowe materiały

Historia zmian

Czasami błędy wykrywane są w interfejsach API używanych do pomiaru danych, a czasem w definicjach samych wskaźników. W związku z tym czasami trzeba wprowadzić zmiany, które mogą się pojawiać w raportach i panelach wewnętrznych jako ulepszenia lub regresje.

Aby ułatwić Ci zarządzanie tymi danymi, wszystkie zmiany w ich implementacji lub definicji będą widoczne w historii zmian.

Jeśli masz opinię na temat tych danych, możesz ją przekazać w grupie Google nt. opinii na temat funkcji web-vitals.