Geschrieben von

Cumulative Layout Shift (CLS)

Performance

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.

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.

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

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 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.
  • Auch eingebettete Widgets und iFrames sollten Größenangaben erhalten.
  • Bestehender Content sollte nicht durch neuen Content beim Seitenaufbau ersetzt werden. Ausnahme: Dies geschieht aufgrund von Nutzer-Eingaben.
  • 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.

Last modified: 11. Oktober 2020