W przeszłości webmasterzy mierzyli się z problemami związanymi z mierzeniem szybkości wczytywania i widoczności głównych treści strony. Starsze dane, takie jak load czy DOMContentLoaded, nie sprawdzają się dobrze, ponieważ niekoniecznie odpowiadają temu, co użytkownik widzi na ekranie. Nowsze dane o wydajności zorientowane na użytkownika, takie jak pierwsze wyrenderowanie treści (FCP), obejmują 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) i 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 nieprawidłowe, ponieważ nadal nie określają, kiedy wczytano główne treści strony.
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 wskazuje czas renderowania największego obrazu, bloku tekstu lub filmu wyświetlanego 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.
Jakie elementy są brane pod uwagę?
Zgodnie z obecnie określoną w interfejsie API największego wyrenderowania treści listą 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>
w elementach<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 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 zestawu 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:
- Elementy o przezroczystości 0, które są niewidoczne dla użytkownika
- Elementy, które pokrywają cały widoczny obszar, i które są raczej uważane za tło niż za 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 heurystyki dotyczące „treści” mogą się różnić od tych używanych przez pierwsze wyrenderowanie treści (FCP), które mogą uwzględniać niektóre z tych elementów, np. obrazy zastępcze lub obrazy w całym widocznym obszarze, nawet jeśli nie kwalifikują się jako kandydaci do 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 – czas, w którym renderowane są treści główne. Wskaźnik LCP ma 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 obrazu, których rozmiar został zmieniony względem właściwego rozmiaru, rozmiar, który jest raportowany, 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, 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 renderowaniu kolejnych klatek będzie wysyłać kolejną wartość 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 z treścią, ale gdy tylko większy element zostanie wyrenderowany, zostanie utworzony kolejny element PerformanceEntry
.
Oprócz ładowania obrazów i czcionek z opóźnieniem strona może dodawać do DOM nowe elementy, gdy staje się dostępna nowa treść. Jeśli którykolwiek z tych nowych elementów jest większy niż poprzedni największy element zawierający treści, nowy 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 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 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 interfejsy API internetowe zgłaszają LCP jako wcześniejsze niż 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 ograniczyć obciążenie związane z obliczaniem i przesyłaniem nowych wpisów dotyczących wydajności, zmiany rozmiaru lub położenia elementu nie powodują generowania nowych kandydatów do LCP. Uwzględniany jest tylko początkowy rozmiar i pozycja elementu w widocznym obszarze.
Oznacza to, że obrazy, które są początkowo 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:
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.
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.
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. 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 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
- Raport na temat użytkowania Chrome
- PageSpeed Insights
- Search Console (raport Core Web Vitals)
web-vitals
Biblioteka JavaScript
Narzędzia laboratoryjne
Pomiar LCP w JavaScript
Aby mierzyć LCP w JavaScript, możesz użyć interfejsu API największego wyrenderowania treści. Ten przykład pokazuje, jak utworzyć regułę PerformanceObserver
, która nasłuchuje wpisów largest-contentful-paint
i zapisują 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 wyśle rekordy
largest-contentful-paint
dla stron wczytywanych na karcie w tle, ale te strony powinny być ignorowane podczas obliczania LCP. - Po przełączeniu strony na tło interfejs API będzie nadal 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 przekazuje rekordów
largest-contentful-paint
, gdy strona jest przywracana z bufora wstecznego/do przodu, ale w takich przypadkach należy mierzyć LCP, ponieważ użytkownicy traktują te zdarzenia jako oddzielne 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 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ć web-vitals
biblioteki JavaScriptu do pomiaru LCP, która załatwia te różnice (w miarę możliwości – zwróć uwagę, że problem z iframem 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
- Lessons learned from performance monitoring in Chrome (na podstawie wystąpienia Annie Sullivan na konferencji performance.now() (2019 r.)
Historia zmian
Czasami w interfejsach API służących do pomiaru danych i czasami w definicjach samych danych występują błędy. 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.