Geschrieben von

Cumulative Layout Shift (CLS)

WebDev

Der Cumulative Layout Shift (CLS) ist einer von drei Kennzahlen aus den Web Vitals. In diesem Beitrag gehe ich näher auf die Kennzahl ein.

Hintergrund

Manchmal passieren auf Websites unerwartete Dinge. Sicherlich hat jeder schon einmal erlebt, dass sich während des Ladevorgangs einer Website Elemente verschieben. Manchmal kommen auch wie aus dem Nichts neue Elemente wie Buttons hinzu. Das wird vor allem dann ärgerlich, wenn man bestimmte Aktionen durchführen oder abbrechen möchte – durch die Verschiebung von Elementen dann aber andere Aktionen in Gang gesetzt werden als eigentlich gewünscht. Man stelle sich folgendes Szenario vor:

  • Man legt Waren in einen Warenkorb und geht den Bestellprozess durch
  • Man landet auf der Bestätigungsseite, wo man die Bestellung nur noch bestätigen muss
  • Während die Seite noch lädt ist schon der “Jetzt kaufen”-Button sichtbar
  • Plötzlich stellt man fest, dass von der Ware fälschlicherweise eine größere Menge angegeben worden ist
  • Man möchte daher auf “Abbrechen” – unter dem “Jetzt kaufen”-Button klicken
  • Man Klick auf die Maus
  • Einen Augenblick vor dem Klick erscheint plötzlich ein Element über den 2 Buttons, was dazu führt, dass alles etwas nach unten rutscht
  • Und da passiert es: Durch die Verschiebung hat man doch auf den “Jetzt kaufen”-Button geklickt

Das ist für den Nutzer ärgerlich! Es wurde eine andere Aktion als gewollt ausgelöst. Bestellung muss storniert werden, was zu Aufwänden auf beiden Seiten führt. Ob der Nutzer nochmal auf dieser Website bestellen wird? Als Website-Betreiber muss man also sicherstellen, dass so etwas vermieden wird.

CLS erklärt

CLS steht für “Cumulative Layout Shift” und ist eine Kennzahl, um die visuelle Stabilität einzelner Elemente auf einer Seite zu messen. Genauer gesagt können so Layout-Verschiebungen ermittelt werden. Dadurch lassen sich solche Szenarien wie vorhin beschrieben rechtzeitig erkennen und beheben.

Eine Layout-Verschiebung liegt vor, wenn ein sichtbares Element seine ursprüngliche Position im Layout ändert. Dies kann folgende Gründe haben:

  • Ressourcen werden asynchron geladen. Dadurch können einzelne Elemente schneller zur Verfügung stehen als andere. Wenn die Elemente nicht aufeinander abgestimmt sind, dann verschieben sich die Elemente gegenseitig.
  • Elemente werden erst nachgelagert in das DOM geladen und verursachen so, dass in ein bestehendes Layout Änderungen vorgenommen werden.

Wann eine Layout-Verschiebung vorliegt, wird von der Layout Instability API vorgegeben. Jedes Mal wenn ein im Viewport sichtbares Element seine Startposition ändert, wird es als “unstabil” gekennzeichnet. Dabei wird im PerformanceEntry-Objekt der API der Wert “layout-shift” im Attribut entryType gesetzt. Ändern Elemente ihre Startposition im nicht sichtbaren Bildschirmbereich, dann liegt kein CLS vor.

Wichtig zu beachten: Eine Layout-Verschiebung liegt dabei nur vor, wenn ein bestehendes Element seine Startposition ändert. Wird ein neues Element im DOM sichtbar oder verändert ein bestehendes Element seine Größe, dann gilt das nicht als Layout-Verschiebung.

Grundsätzlich muss man auch bedenken, dass man zwischen erwarteten und unerwarteten Layout-Verschiebungen unterscheiden kann:

  • Unerwartete Layout-Verschiebungen sind für den Nutzer schlecht und sollten daher vermieden werden. Dies ermittelt der CLS.
  • Es gibt aber auch erwartete Layout-Verschiebungen, die nicht Teil des CLS sind. Diese betreffen Änderungen, die der Nutzer selbst durch z.B. Klicks veranlasst hat. Oder Animationen, die das Layout ändern, aber ohne dass die Änderungen für den Nutzer überraschend sind. Dies gilt aber nur, wenn die Website innerhalb 500 ms ein Feedback gibt. Heißt: Wenn der Nutzer einen Button klickt und darunter ein neuer Content-Block eingefügt wird, dann muss diese Änderung innerhalb von 500 ms stattfinden, damit kein CLS ausgelöst wird. Eine Ausnahme stellt hier das Scrollen dar. Auch wenn der Nutzer das Scrollen selbst veranlasst, zählen Layout-Verschiebungen zum CLS.

CLS Berechnung

Der CLS wird wie folgt berechnet:

CLS = Impact fraction * Distance fraction

Impact fraction und Distance fraction

Die Impact fraction gibt in Prozent an, wie viel Prozent des sichtbaren Bereichs ein Element nach seiner Verschiebung einnimmt. Gehen wir von folgendem Szenario aus:

  • Bei Laden der Seite nimmt ein Element 50 % des sichtbaren Bereichs ein (1. Frame)
  • Während dem Laden rutscht das Element auf einmal 25 % nach unten (2. Frame)

Die Impact fraction ist nun die Summe beider Frames: 50 % + 25 % = 75 %. Also ist die Impact fraction 0,75.

Die Distance fraction gibt an, wie groß die Layout-Verschiebung zwischen den Frames war. Dabei wird die größte Entfernung (horizontal oder vertikal), die ein Element zurückgelegt hat, als Ausgangwert genommen. Dieser wird dann durch die größte Dimension des Viewports geteilt (Höhe oder Breite, je nachdem was größer ist). Nimmt man einen Wert von 0,25 an, dann hätte man folgende Berechnung:

CLS = 0,75 * 0,25 = 0,1875

Am 7. April 2021 hat Google eine neue Berechnungsmethode beim CLS verkündet. Es werden nicht mehr alle Layout-Verschiebungen einer Seite addiert. Mit dieser Methode hatten vor allem längere Seiten Nachteile beim CLS-Wert verzeichnet. Die neue Berechnungsmethode basiert auf Session Windows.

Eine Session Window ist eine Gruppe von Layout-Verschiebungen. Das Fenster startet dabei bei der ersten Layout-Verschiebung und endet, sobald eine größere Lücke zur nächsten Layout-Verschiebung entsteht. So kann es sein, dass bei einer Seite mehrere CLS-Session-Windows entstehen. Die CLS-Werte einzelner Session Windows werden addiert. Die Session Window mit dem höchsten Wert wird dann als CLS-Wert für die jeweilige Seite herangezogen. Weitere Details dazu gibt es im webdev-Blog.

Was ist ein guter CLS-Wert?

Laut Google kann man sich an folgende Werte orientieren:

  • Unter 0.1 ist der CLS gut
  • Zwischen 0.1 und 0.25 braucht es eine Optimierung
  • Ab 0.25 liegt ein schlechter CLS-Wert vor

CLS messen

Je nachdem ob man Feld- oder Labordaten messen möchte, gibt es verschiedene Ansätze.

Felddaten

Labordaten

CLS in den DevTools analysieren

Die Chrome DevTools bieten 2 wichtige Funktionen, um den CLS einer URL näher zu analysieren. Diese 2 Funktionen sind:

  • Anzeigen der “Layout Shift Regions”
  • Elemente, die eine Layout-Verschiebung verursachen, im Performance-Report identifizieren

Mit der Aktivierung der Funktion “Layout Shift Regions” markiert Chrome während dem Laden der Seite die Elemente, die vom CLS betroffen sind. Um die Funktion zu aktivieren, ruft man die DevTools auf und navigiert zu den Rendering-Einstellungen wie folgt:

DevTools

Es öffnet sich ein Tab, wo man “Layout Shift Regions” aktivieren muss:

DevTools

Danach musst du die Seite einfach neu laden (z.B. mit F5). Während die Seite neu lädt, markiert Chrome farblich die Elemente, die vom CLS betroffen sind (aber nicht, die den CLS verursachen). In meinem Fall wäre das z.B. unter anderem die Navigation:

CLS

Eine Möglichkeit Elemente, die einen CLS verursachen, zu analysieren ist im Performance-Tab versteckt. Dabei gehst du wie folgt vor:

  1. Performance-Tab aufrufen
  2. Seite neu laden
  3. Bereich “Timings” einblenden lassen
  4. CLS (“Layout Shift”) heraussuchen und draufklicken
  5. Unter “Summary” sieht du welches Element den CLS verursacht

Hier der Screenshot dazu:

CLS

Wenn du nun auf das Element (Nummer 5 im Screenshot) klickst, wirst du in den DOM-Baum im Tab “Elements” auf das entsprechende Element geleitet und kannst es so näher analysieren.

CLS verbessern

  • Bei Bildern und Videos sollte man immer eine Größenangabe (width und height) mitgeben. Dadurch kann der Platz auf der Seite beim Laden reserviert werden. Alternativ kann der Platz mit CSS Aspect Ratio Boxes reserviert werden. Wenn Bilder innerhalb von Containern eingebunden sind, die eine feste Größe schon haben, dann sollten Bilder im CSS auf height: auto; gesetzt werden.
  • Kommen Werbebanner zum Einsatz, dann sollten diese ebenfalls Größenangaben enthalten. Zudem sollte man Banner am obersten Bereich des Viewports nach Möglichkeit vermeiden. Banner im obersten Bereich bewegen bei einer Layout-Verschiebung alle Elemente, die darunter liegen, was zu einem hohen CLS führen kann.
  • Umgekehrt kann es passieren, dass ein Platz für den Werbebanner reserviert ist, aber dann doch kein Banner ausgespielt wird. Dann kann es sein, dass der darunter liegende Content nach oben rutscht, was ebenfalls zu einem CLS führt. In so einem Fall sollte es einen Fallback geben, wo statt dem Banner ein internes Bild oder Text ausgespielt wird, um den reservierten Platz zu besetzen.
  • Auch eingebettete Widgets und iFrames sollten Größenangaben erhalten.
  • Wenn Bilder und Banner dynamisch ausgespielt werden und man nicht konkret weiß wie die Größenangaben sind, dann sollte man zumindest eine Mindest-Höhenangabe (min-height) setzen. Dadurch ist die Layout-Verschiebung nicht so groß.
  • Bestehender Content sollte nicht durch neuen Content beim Seitenaufbau ersetzt werden. Ausnahme: Dies geschieht aufgrund von Nutzer-Eingaben.
  • Bei erwarteten Layout-Verschiebungen – durch Nutzer-Eingaben (z.B. Klick) hervorgerufen – sollten diese innerhalb von 500 ms ein visuelles Feedback geben. Klickt z.B. der Nutzer einen Button und wird Content darunter hinzugefügt, dann sollte dieser innerhalb von 500 ms vorliegen, damit kein CLS gezählt wird. Falls der Content “zu schwer” ist um so schnell geladen zu werden, dann sollte man einen schlanken Platzhalter schonmal direkt laden bis der Hauptinhalt zur Verfügung steht.
  • Auch Webschriften können zu einem schlechten CLS-Wert führen. Dabei spielen FOUT (Flash Of Unstyled Text) und FOIT (Flash Of Invisible Text) eine Rolle. Bei FOUT wird die Fallback-Schriftart durch die Neue ersetzt. Bei FOIT wird ein “unsichtbarer” Text angezeigt bis die Schrift zur Verfügung steht. Um FOUT und FOIT zu vermeiden, kann font-display auf “optional” gesetzt werden. Oder man verwendet die Font Loading API. Zudem sollten Resource Hints wie Preload verwendet werden.
  • Bei Animationen sollte man mit der transform-Property arbeiten. Angaben wie box-shadow oder box-sizing führen zu einem Re-Layout.
  • Werden Ressourcen vorab geladen, dann kann das auch beim CLS helfen.

Um den CLS zu verbessern ist es grundsätzlich wichtig: Reserviere den Platz für die Elemente, die auf der Website geladen werden (z.B. mittels width und height).