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 będą dobrze działać, ponieważ niekoniecznie muszą odpowiadać 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, użytkownik nie patrzy na ten moment.
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 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 raportuje czas renderowania największego bloku graficznego lub tekstowego widocznego w widocznym obszarze w odniesieniu do czasu, w którym użytkownik po raz pierwszy przeszedł na stronę.
Jaki jest dobry wynik LCP?
W trosce o wygodę użytkowników witryny powinny dążyć do tego, aby największe wyrenderowanie treści było możliwe po maksymalnie 2,5 sekundy. 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.
Jakie elementy są brane pod uwagę?
Zgodnie z obecnie określonym w największym wyrenderowaniu treści API, czyli typy elementów, dla największego wyrenderowania treści to:
- elementów
<img>
(czas prezentacji pierwszej klatki jest stosowany w przypadku treści animowanych, takich jak GIF-y czy 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()
(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.
Pamiętaj, że ograniczenie liczby elementów do tego ograniczonego zestawu było celowe, ponieważ dzięki temu od początku wszystko jest proste. W miarę przeprowadzania kolejnych badań możemy dodawać kolejne elementy (takie jak pełna obsługa <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 są to między innymi:
- Elementy o przezroczystości 0, które są niewidoczne dla użytkownika
- Elementy zakrywające cały widoczny obszar, które prawdopodobnie są uznawane za tło, a nie jako 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 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 bierze pod uwagę 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, dopełnień ani obramowań zastosowanych za pomocą CSS.
Kiedy raportowana jest wartość 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 zostać uznany za największy z nich dopiero po wyrenderowaniu i wyświetleniu się użytkownikowi. Obrazy, które nie zostały jeszcze wczytane, nie są uważane za „wyrenderowane”. W okresie blokowania czcionek węzły tekstowe też nie korzystają z czcionek internetowych. 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 obrazów i czcionek wczytujących się z opóźnieniem strona może dodawać do DOM nowe elementy w miarę pojawiania się nowych 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 z treścią zostanie usunięty z widocznego obszaru lub nawet z elementu DOM, pozostanie on największym elementem treści, chyba że zostanie wyrenderowany większy.
Przeglądarka przestaje raportować nowe wpisy, gdy tylko użytkownik wejdzie w interakcję ze stroną (klikając, przewijając lub naciskając klawisz), ponieważ interakcja użytkownika często zmienia to, co jest dla niego widoczne (zwłaszcza 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 widoczny jest tylko czas wczytywania (ponieważ jest on już udostępniany przez wiele innych internetowych 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 niż FCP. Nie jest to słuszne, ale tylko tak się dzieje ze względu na to ograniczenie bezpieczeństwa.
Zalecamy, aby w miarę możliwości ustawić nagłówek Timing-Allow-Origin
, aby zwiększyć dokładność danych.
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 później pojawiają się na ekranie, mogą nie zostać zarejestrowane. Oznacza to również, że elementy wyrenderowane na początku w widocznym obszarze, które następnie są przesuwane w dół, przez co nadal będą raportowane swój początkowy rozmiar.
Przykłady
Oto kilka przykładów sytuacji, w których następuje największe wyrenderowanie treści w kilku popularnych witrynach:
Na obu powyższych osiach czasu największy element zmienia się podczas wczytywania treści. W pierwszym przykładzie nowa treść jest dodawana do modelu DOM, która zmienia największy z nich. W drugim przykładzie układ się zmienia, a treści, które wcześniej były 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 kolejnych 2 przykładach widać LCP, zanim strona zostanie w pełni załadowana.
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. 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 terenie. Wartość ta jest dostępna w tych narzędziach:
Narzędzia terenowe
- Raport na temat użytkowania Chrome
- PageSpeed Insights
- Search Console (raport dotyczący podstawowych wskaźników internetowych)
- Biblioteka JavaScript
web-vitals
Narzędzia laboratoryjne
Pomiar LCP w języku JavaScript
Aby zmierzyć LCP w JavaScript, możesz użyć interfejsu Largest Contentful Paint API. 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. Ogólnie wartość startTime
ostatniego opublikowanego 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 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 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 rozpoczęcia nawigacji, ale w przypadku wstępnie renderowanych stron wartość LCP należy mierzyć od
activationStart
, ponieważ odpowiada on czasowi LCP widocznemu przez użytkownika.
Zamiast zapamiętywać wszystkie te subtelne różnice, deweloperzy mogą użyć biblioteki JavaScript web-vitals
, aby zmierzyć wskaźnik LCP, który uwzględnia te różnice za Ciebie (tam, gdzie to możliwe – problem z elementami iframe nie został omówiony):
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. Możesz to zrobić za pomocą interfejsu Element Timing API zgodnie z opisem w artykule o danych niestandardowych.
Jak poprawić LCP
Znajdziesz w nim pełny przewodnik po optymalizacji LCP, dzięki któremu dowiesz się, jak identyfikować czasy LCP w terenie i wykorzystywać dane laboratoryjne do ich analizowania i optymalizowania.
Dodatkowe materiały
- Wnioski wyciągnięte z monitorowania wydajności w Chrome, autorka: Annie Sullivan, performance.now() (2019)
Historia zmian
Czasami błędy wykrywane są w interfejsach API używanych do pomiaru danych, a czasem w definicjach samych wskaźników. Dlatego czasami konieczne jest wprowadzenie zmian, które mogą być widoczne jako ulepszenia lub regresje w wewnętrznych raportach i panelach.
Aby ułatwić Ci to zadanie, wszystkie zmiany w implementacji lub definicji tych danych będą widoczne w tym dzienniku zmian.
Jeśli chcesz podzielić się opinią na temat tych danych, możesz przesłać ją w grupie dyskusyjnej Google z informacjami o web-vitals-feedback.