Largest Contentful Paint (LCP)

Obsługa przeglądarek

  • Chrome: 77.
  • Edge: 79.
  • Firefox: 122.
  • Safari: nieobsługiwane.

Źródło

W przeszłości webmasterzy mierzyli się z wyzwaniem, jakim jest pomiar szybkości wczytywania i widoczności głównej zawartości strony internetowej 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. 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 wskaźniki wydajności, takie jak pierwsze wyrenderowanie treści (FMP)indeks szybkości (SI) (oba dostępne w Lighthouse), aby pomóc w lepszym zobrazowaniu wczytywania po pierwszym wyrenderowaniu, ale te dane są skomplikowane, trudne do wyjaśnienia i często błędne – nadal nie określają, kiedy wczytano główne treści strony.

Na podstawie dyskusji w grupie roboczej W3C Web Performance Group i badań przeprowadzonych przez Google stwierdziliśmy, że dokładniejszym sposobem mierzenia, kiedy główna zawartość strony jest wczytywana, jest sprawdzanie, 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 największego wyrenderowania treści wynoszący 2,5 sekund lub krócej. Aby mieć pewność, że w przypadku większości użytkowników osiągniesz ten cel, warto mierzyć 75 centyl wczytań stron z podziałem na urządzenia mobilne i komputery.

Dobre wartości LCP wynoszą maksymalnie 2,5 sekundy, niskie wartości powyżej 4,0 sekund, a niektóre z nich wymagają poprawy
Dobra wartość LCP to 2,5 sekundy lub mniej.

Jakie elementy są brane pod uwagę?

Zgodnie z obecnie określoną w interfejsie API największego wyrenderowania treści lista typów elementów uwzględnianych w przypadku największego wyrenderowania treści:

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

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>).

Pomijając fakt, że wskaźnik LCP uwzględnia tylko niektóre elementy, wykorzystuje on heurystyki, aby wykluczać elementy, które użytkownicy prawdopodobnie uznają za „niezawierające treści”. W przypadku przeglądarek opartych na Chromium są to między innymi:

  • 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 nadal ulepszać te heurystyki, aby spełniać oczekiwania użytkowników dotyczące największego elementu zawierającego treści.

Te „treść” heurystyki mogą różnić się od metod stosowanych w przypadku pierwszego wyrenderowania treści (FCP), które 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ę jako kandydaci LCP. Mimo że obie nazwy zawierają słowo „contentful”, mają one inny cel. FCP mierzy czas, w którym dowolne treści są renderowane na ekranie, a LCP – gdy renderowane są treści główne. Wskaźnik LCP ma więc być bardziej selektywny.

Jak określa się rozmiar elementu?

Rozmiar elementu zgłaszanego w ramach LCP to zwykle rozmiar widoczny dla użytkownika w widocznym obszarze. Jeśli element wykracza poza widoczny obszar, jeśli część elementu jest przycięta lub jeśli element ma niewidoczny przepełnienie, te części nie są wliczane do rozmiaru elementu.

W przypadku elementów graficznych, których rozmiar został zmieniony ze swojego rozmiaru wewnętrznego, raportowany rozmiar to rozmiar widoczny lub wewnętrzny, w zależności od tego, który z tych rozmiarów 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, dlatego największy element na stronie może się zmienić.

Aby obsłużyć tę potencjalną zmianę, przeglądarka wysyła PerformanceEntry typu largest-contentful-paint, który identyfikuje największy element treści, gdy tylko przeglądarka wyrenderuje pierwszy kadr. 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 najpierw renderować tylko tekst. W tym momencie wysyła ona wpis largest-contentful-paint, którego właściwość element odwołuje się prawdopodobnie do elementu <p> lub <h1>. Później, gdy obraz nagłówka zostanie załadowany, zostanie wysłany drugi wpis largest-contentful-paint, a jego właściwość element będzie się odwoływać 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 załadowane, nie są uważane za „renderowane”. 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 ładowania 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 którykolwiek z tych nowych elementów jest większy niż poprzedni największy element zawierający treści, nowy element PerformanceEntry zostanie również zgłoszony.

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, 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 analizy do usługi analitycznej należy przesyłać tylko ostatnio wysłane PerformanceEntry.

Czas wczytywania a czas renderowania

Ze względów bezpieczeństwa sygnatura czasowa renderowania obrazów nie jest udostępniana w przypadku obrazów z różnych źródeł, które nie mają nagłówka Timing-Allow-Origin. Zamiast tego wyświetlany jest tylko czas ich wczytywania (ponieważ jest on już dostępny w ramach wielu 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 pozycji 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 później pojawiają się na ekranie, mogą nie zostać zarejestrowane. 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 osi czasu powyżej największy element zmienia się w miarę 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.

Często się zdarza, że zbyt późno ładujące się treści są większe niż te, które znajdują się już na stronie, ale nie musi być to prawdą. W następnych 2 przypadkach LCP występuje przed pełnym załadowaniem strony.

Oś czasu największego wyrenderowania treści na instagram.com
Czas trwania LCP na stronie instagram.com.
Czas największego wyrenderowania treści na google.com
Czas trwania LCP na stronie google.com.

W pierwszym przykładzie logo Instagrama jest ładowane stosunkowo wcześnie i pozostanie największym elementem nawet wtedy, gdy inne treści będą stopniowo wyświetlane. Na przykład na stronie wyników wyszukiwania Google największym elementem jest akapit tekstu wyświetlany przed zakończeniem wczytywania dowolnego obrazu lub logo. Ponieważ wszystkie obrazy są mniejsze niż ten akapit, pozostaje on największym elementem podczas ładowania.

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 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 zarejestrowany wpis largest-contentful-paint reprezentuje bieżącego 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 następującej sekcji opisano różnice między tym, co raportuje interfejs API, a sposobem obliczania danych.

Różnice między danymi a interfejsem API

  • Interfejs API wysyła wpisy largest-contentful-paint w przypadku stron wczytywanych na karcie w tle, ale strony te należy zignorować przy obliczaniu LCP.
  • Po zakończeniu działania strony w tle interfejs API będzie nadal wysyłać wpisy largest-contentful-paint, ale należy je zignorować przy obliczaniu LCP (elementy mogą być brane pod uwagę tylko wtedy, gdy strona była przez 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 elementach iframe, ale dane je uwzględniają, ponieważ wchodzą w skład użytkownika strony. Na stronach, na których element LCP znajduje się w elemencie iframe (np. obraz plakatu w osadzonym filmie), będzie to widoczne jako różnica między CrUX a RUM. Aby prawidłowo mierzyć LCP, weź je pod uwagę. Ramki podrzędne mogą używać interfejsu API do raportowania swoich wpisów largest-contentful-paint do ramki nadrzędnej w celu ich 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 to za Ciebie (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 JavaScript znajdziesz w źródłowym kodzie 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 tym samym co największy element, a deweloperzy mogą być bardziej zainteresowani pomiarem czasu renderowania tych innych 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 optymalizowaniu ich za pomocą danych z laboratorium.

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. Dlatego trzeba czasem wprowadzać zmiany, które mogą być widoczne jako ulepszenia lub regresje w wewnętrznych raportach i panelach.

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. danych web-vitals.