In der Vergangenheit war es für Webentwickler eine Herausforderung, zu messen, wie schnell der Hauptinhalt einer Webseite geladen und für Nutzer sichtbar ist. Ältere Messwerte wie load oder DOMContentLoaded funktionieren weniger gut, da sie nicht unbedingt dem entsprechen, was der Nutzer auf seinem Bildschirm sieht. Neuere, nutzerorientierte Leistungsmesswerte wie First Contentful Paint (FCP) erfassen nur den Anfang des Ladevorgangs. Wenn auf einer Seite ein Startbildschirm oder ein Ladebalken angezeigt wird, ist dieser Moment für den Nutzer nicht sehr relevant.
In der Vergangenheit haben wir Leistungsmesswerte wie First Meaningful Paint (FMP) und Speed Index (SI) empfohlen, die beide in Lighthouse verfügbar sind. Diese Messwerte geben Aufschluss über den gesamten Ladevorgang nach dem ersten Paint-Vorgang. Sie sind jedoch komplex, schwer zu erklären und oft falsch. Das bedeutet, dass sie immer noch nicht erkennen, wann der Hauptinhalt der Seite geladen wurde.
Basierend auf Diskussionen in der W3C Web Performance Working Group und Studien von Google haben wir festgestellt, dass es genauer ist, zu messen, wann das größte Element gerendert wird, um zu ermitteln, wann der Hauptinhalt einer Seite geladen ist.
Was ist LCP?
LCP gibt die Renderingzeit des größten Bilds, Textblocks oder Videos an, das im Darstellungsbereich sichtbar ist, bezogen auf den Zeitpunkt, zu dem der Nutzer die Seite aufgerufen hat.
Was ist ein guter LCP-Wert?
Für eine gute Nutzerfreundlichkeit sollten Websites einen Largest Contentful Paint von 2,5 Sekunden oder weniger anstreben. Damit Sie dieses Ziel für die meisten Nutzer erreichen, ist der 75. Perzentilwert der Seitenladezeiten ein guter Messwert. Dieser sollte für Mobilgeräte und Computer getrennt gemessen werden.
Welche Elemente werden berücksichtigt?
Derzeit werden in der Largest Contentful Paint API die folgenden Elementtypen für Largest Contentful Paint berücksichtigt:
<img>
-Elemente (die Präsentationszeit des ersten Frames wird für animierte Inhalte wie GIFs oder animierte PNGs verwendet)<image>
-Elemente in einem<svg>
-Element<video>
-Elemente (die Ladezeit des Posterbilds oder die Darstellungszeit des ersten Frames für Videos, je nachdem, was früher eintritt)- Ein Element mit einem Hintergrundbild, das mit der Funktion
url()
geladen wird (im Gegensatz zu einem CSS-Farbverlauf) - Elemente auf Blockebene, die Textknoten oder andere untergeordnete Textelemente auf Inline-Ebene enthalten.
Die Beschränkung der Elemente auf diese begrenzte Menge war beabsichtigt, um die Dinge am Anfang einfach zu halten. Wenn weitere Studien durchgeführt werden, werden möglicherweise zusätzliche Elemente hinzugefügt, z. B. die vollständige Unterstützung von <svg>
.
Bei LCP-Messungen werden nicht nur einige Elemente berücksichtigt, sondern auch bestimmte Elemente, die Nutzer wahrscheinlich als „nicht inhaltsbezogen“ empfinden, anhand von Heuristiken ausgeschlossen. Zu den Chromium-basierten Browsern gehören:
- Elemente mit einer Deckkraft von 0, die für den Nutzer nicht sichtbar sind
- Elemente, die den gesamten Darstellungsbereich abdecken und eher als Hintergrund denn als Inhalt betrachtet werden
- Platzhalterbilder oder andere Bilder mit niedriger Entropie, die wahrscheinlich nicht den tatsächlichen Inhalt der Seite widerspiegeln
Diese Heuristiken werden in Browsern wahrscheinlich weiter verbessert, damit die Erwartungen der Nutzer an das größte elementarste Element erfüllt werden.
Diese „inhaltlichen“ Heuristiken können sich von denen unterscheiden, die für First Contentful Paint (FCP) verwendet werden. Dabei werden einige dieser Elemente, z. B. Platzhalterbilder oder Bilder im Vollansichtsbereich, möglicherweise berücksichtigt, auch wenn sie nicht als LCP-Kandidaten infrage kommen. Obwohl beide Messwerte den Begriff „aussagekräftig“ im Namen tragen, haben sie unterschiedliche Ziele. Der FCP misst, wann Inhalte auf dem Bildschirm gerendert werden, und der LCP, wann die Hauptinhalte gerendert werden. Der LCP soll also selektiver sein.
Wie wird die Größe eines Elements bestimmt?
Die Größe des Elements, die für LCP erfasst wird, entspricht in der Regel der Größe, die für den Nutzer im Darstellungsbereich sichtbar ist. Wenn sich das Element über den Darstellungsbereich hinaus erstreckt, ein Teil des Elements zugeschnitten ist oder einen nicht sichtbaren Overflow hat, werden diese Teile nicht auf die Größe des Elements angerechnet.
Bei Bildelementen, deren Größe ausgehend von ihrer systemeigenen Größe geändert wurde, wird entweder die sichtbare Größe oder die intrinsische Größe gemeldet – je nachdem, welche Größe kleiner ist.
Bei Textelementen wird für die LCP nur das kleinste Rechteck berücksichtigt, das alle Textknoten enthalten kann.
Der LCP berücksichtigt nicht für alle Elemente Ränder, Abstände oder Rahmen, die mithilfe von CSS angewendet wurden.
Wann wird der LCP erfasst?
Webseiten werden oft in mehreren Schritten geladen. Daher kann es sein, dass sich das größte Element auf der Seite ändert.
Um diesem Änderungspotenzial zu begegnen, sendet der Browser ein PerformanceEntry
vom Typ largest-contentful-paint
, das das größte Inhaltselement identifiziert, sobald der Browser den ersten Frame gezeichnet hat. Nach dem Rendern nachfolgender Frames wird jedoch jedes Mal, wenn sich das Element mit dem größten Inhalt ändert, eine weitere PerformanceEntry
gesendet.
Auf einer Seite mit Text und einem Hero-Image rendert der Browser beispielsweise möglicherweise zuerst nur den Text. In diesem Fall sendet der Browser einen largest-contentful-paint
-Eintrag, dessen element
-Eigenschaft wahrscheinlich auf eine <p>
oder <h1>
verweist. Später, wenn das Hero-Bild vollständig geladen ist, wird ein zweiter largest-contentful-paint
-Eintrag gesendet und seine element
-Eigenschaft verweist auf die <img>
.
Ein Element kann erst dann als größtes Inhaltselement betrachtet werden, wenn es gerendert wurde und für den Nutzer sichtbar ist. Bilder, die noch nicht geladen wurden, gelten nicht als „gerendert“. Auch Textknoten verwenden während des Zeitraums des Schriftblockes keine Webschriftarten. In solchen Fällen kann ein kleineres Element als größtes inhaltsorientiertes Element gemeldet werden. Sobald das größere Element jedoch vollständig gerendert wurde, wird ein weiteres PerformanceEntry
-Element erstellt.
Neben den spät geladenen Bildern und Schriftarten kann eine Seite dem DOM neue Elemente hinzufügen, sobald neue Inhalte verfügbar sind. Wenn eines dieser neuen Elemente größer als das bisher größte Element mit Inhalt ist, wird auch eine neue PerformanceEntry
gemeldet.
Wenn das größte Inhaltselement aus dem Darstellungsbereich oder sogar aus dem DOM entfernt wird, bleibt es das größte Inhaltselement, sofern kein größeres Element gerendert wird.
Der Browser meldet keine neuen Einträge mehr, sobald der Nutzer per Tippen, Scrollen oder Tastendruck mit der Seite interagiert. Dies liegt daran, dass sich durch die Nutzerinteraktion häufig die Sichtbarkeit des Nutzers ändert. Dies gilt insbesondere für das Scrollen.
Zu Analysezwecken sollten Sie nur die zuletzt gesendeten PerformanceEntry
an Ihren Analysedienst senden.
Ladezeit im Vergleich zur Renderingzeit
Aus Sicherheitsgründen wird der Renderingzeitstempel von Bildern für ursprungsübergreifende Bilder ohne den Header Timing-Allow-Origin
nicht verfügbar gemacht. Stattdessen wird nur die Ladezeit angegeben, da diese bereits über viele andere Web-APIs verfügbar ist.
Das kann zu der scheinbar unmöglichen Situation führen, dass der LCP von Web-APIs früher als der FCP gemeldet wird. Das ist nicht der Fall, sondern nur aufgrund dieser Sicherheitseinschränkung so zu sehen.
Wenn möglich, sollten Sie immer die Timing-Allow-Origin
-Kopfzeile festlegen, damit Ihre Messwerte präziser sind.
Wie werden Änderungen am Layout und der Größe von Elementen gehandhabt?
Um den Leistungsoverhead bei der Berechnung und dem Versand neuer Leistungseinträge niedrig zu halten, werden durch Änderungen an der Größe oder Position eines Elements keine neuen LCP-Kandidaten generiert. Es wird nur die ursprüngliche Größe und Position des Elements im Darstellungsbereich berücksichtigt.
Das bedeutet, dass Bilder, die zuerst außerhalb des sichtbaren Bereichs gerendert und dann auf dem Bildschirm angezeigt werden, möglicherweise nicht gemeldet werden. Außerdem wird für Elemente, die anfänglich im Darstellungsbereich gerendert und dann nach unten und außerhalb des sichtbaren Bereichs verschoben wurden, weiterhin ihre ursprüngliche Größe im Darstellungsbereich gemeldet.
Beispiele
Hier sind einige Beispiele dafür, wann die Largest Contentful Paint auf einigen beliebten Websites auftritt:
In beiden Zeitleisten oben ändert sich das größte Element, während der Inhalt geladen wird. Im ersten Beispiel werden neue Inhalte zum DOM hinzugefügt, wodurch sich das größte Element ändert. Im zweiten Beispiel werden die Layoutänderungen und der vorher größte Inhalt aus dem Darstellungsbereich entfernt.
Es kommt zwar häufig vor, dass zu spät ladender Content größer ist als der bereits auf der Seite vorhandene Content. Dies muss jedoch nicht unbedingt der Fall sein. Die nächsten beiden Beispiele zeigen den LCP, der vor dem vollständigen Laden der Seite erfolgt.
Im ersten Beispiel wird das Instagram-Logo relativ früh geladen und bleibt das größte Element, auch wenn andere Inhalte nach und nach eingeblendet werden. Im Beispiel für die Google-Suchergebnisseite ist das größte Element ein Textabsatz, der angezeigt wird, bevor die Bilder oder das Logo vollständig geladen sind. Da alle einzelnen Bilder kleiner als dieser Absatz sind, bleibt es das größte Element während des Ladevorgangs.
LCP messen
Der LCP kann im Labor oder im Feld gemessen werden und ist in den folgenden Tools verfügbar:
Tools für die Arbeit im Außendienst
- Chrome User Experience Report
- PageSpeed Insights
- Search Console (Core Web Vitals-Bericht)
web-vitals
JavaScript-Bibliothek
Lab-Tools
LCP in JavaScript messen
Zum Messen des LCP in JavaScript können Sie die Largest Contentful Paint API verwenden. Das folgende Beispiel zeigt, wie Sie eine PerformanceObserver
erstellen, die largest-contentful-paint
-Einträge überwacht und in der Console protokolliert.
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
console.log('LCP candidate:', entry.startTime, entry);
}
}).observe({type: 'largest-contentful-paint', buffered: true});
Im obigen Beispiel steht jeder protokollierte largest-contentful-paint
-Eintrag für den aktuellen LCP-Kandidaten. Im Allgemeinen ist der startTime
-Wert des letzten ausgegebenen Eintrags der LCP-Wert. Das ist jedoch nicht immer der Fall. Nicht alle largest-contentful-paint
-Einträge sind für die Messung des LCP gültig.
Im folgenden Abschnitt werden die Unterschiede zwischen den Angaben in der API und der Berechnung des Messwerts aufgeführt.
Unterschiede zwischen dem Messwert und der API
- Die API sendet
largest-contentful-paint
-Einträge für Seiten, die in einem Hintergrundtab geladen werden. Diese Seiten sollten bei der Berechnung der LCP jedoch ignoriert werden. - Die API sendet auch dann weiterhin
largest-contentful-paint
-Einträge, wenn eine Seite im Hintergrund ist. Diese Einträge sollten bei der Berechnung des LCP jedoch ignoriert werden. Elemente können nur berücksichtigt werden, wenn die Seite die ganze Zeit im Vordergrund war. - Die API meldet keine
largest-contentful-paint
-Einträge, wenn die Seite aus dem Back-Forward-Cache wiederhergestellt wird. Der LCP sollte in diesen Fällen jedoch gemessen werden, da die Nutzer sie als separate Seitenaufrufe erleben. - Die API berücksichtigt keine Elemente in Iframes. Der Messwert hingegen berücksichtigt sie, da sie Teil der Nutzerfreundlichkeit der Seite sind. Auf Seiten mit einem LCP innerhalb eines iFrames, z. B. einem Posterbild in einem eingebetteten Video, wird dies als Unterschied zwischen CrUX und RUM angezeigt. Sie sollten sie berücksichtigen, um den LCP-Wert korrekt zu messen. Untergeordnete Frames können die API verwenden, um ihre
largest-contentful-paint
-Einträge zur Aggregation an den übergeordneten Frame zu melden. - Die API misst den LCP vom Beginn der Navigation an. Bei vorab gerenderten Seiten sollte der LCP jedoch ab
activationStart
gemessen werden, da dies der LCP-Zeit entspricht, die der Nutzer wahrnimmt.
Anstatt sich all diese kleinen Unterschiede zu merken, können Entwickler den LCP mithilfe der web-vitals
-JavaScript-Bibliothek messen. Dort werden diese Unterschiede für Sie behoben (wo möglich – das Problem mit den iFrames wird nicht behandelt):
import {onLCP} from 'web-vitals';
// Measure and log LCP as soon as it's available.
onLCP(console.log);
Im Quellcode für onLCP()
finden Sie ein vollständiges Beispiel zum Erfassen der LCP in JavaScript.
Was ist, wenn das größte Element nicht das wichtigste ist?
In einigen Fällen sind die wichtigsten Elemente auf der Seite nicht mit dem größten Element identisch. Entwickler sind möglicherweise eher daran interessiert, die Renderzeiten dieser anderen Elemente zu messen. Dies ist mit der Element Timing API möglich, wie im Artikel zu benutzerdefinierten Messwerten beschrieben.
LCP verbessern
Es steht ein vollständiger Leitfaden zur LCP-Optimierung zur Verfügung, der Sie durch die Ermittlung des LCP-Timings vor Ort und die Verwendung von Lab-Daten zur Aufschlüsselung und Optimierung der LCP-Werte führt.
Zusätzliche Ressourcen
- Lessons learned from performance monitoring in Chrome von Annie Sullivan auf performance.now() (2019)
Änderungsprotokoll
Gelegentlich werden Fehler in den APIs gefunden, die zum Erfassen von Messwerten verwendet werden, und manchmal auch in den Definitionen der Messwerte selbst. Daher müssen manchmal Änderungen vorgenommen werden. Diese Änderungen können sich in Ihren internen Berichten und Dashboards als Verbesserungen oder Rückschritte zeigen.
Alle Änderungen an der Implementierung oder Definition dieser Messwerte werden in diesem Changelog aufgeführt.
Wenn Sie Feedback zu diesen Messwerten haben, können Sie es in der Google-Gruppe „web-vitals-feedback“ geben.