content-sichtbarkeit: die neue CSS-Eigenschaft zur Steigerung der Rendering-Leistung

Du kannst die anfängliche Ladezeit verbessern, indem du das Rendering von nicht sichtbaren Inhalten überspringst.

Vladimir Levin
Vladimir Levin

Die content-visibility-Property, die in Chromium 85 eingeführt wird, ist möglicherweise eine der wirkungsvollsten neuen CSS-Eigenschaften zur Verbesserung der Seitenladeleistung. Mit content-visibility kann der User-Agent die Rendering-Arbeit eines Elements überspringen, einschließlich Layout und Painting, bis es benötigt wird. Da das Rendern übersprungen wird, wird durch die Verwendung des Attributs content-visibility das anfängliche Laden des Nutzers viel beschleunigt, wenn ein großer Teil des Inhalts außerhalb des sichtbaren Bildschirminhalts liegt. Außerdem ermöglicht es eine schnellere Interaktion mit den Bildschirminhalten. Ziemlich praktisch.

Demo mit Abbildungen der Netzwerkergebnisse
In unserer Artikeldemo kann die Anwendung von content-visibility: auto auf aufgeteilte Inhaltsbereiche eine 7-fache Rendering-Leistung beim ersten Laden bewirken. Lesen Sie weiter, um mehr zu erfahren.

Unterstützte Browser

Unterstützte Browser

  • 85
  • 85
  • 124

Quelle

content-visibility stützt sich auf Primitive innerhalb der CSS-Begrenzungsspezifikationen. Obwohl content-visibility derzeit nur in Chromium 85 unterstützt wird und für Firefox als "lohnendes Prototyping" gilt, wird die Begrenzungsspezifikation in den meisten modernen Browsern unterstützt.

CSS-Begrenzung

Das wichtigste und übergeordnete Ziel der CSS-Begrenzung besteht darin, die Rendering-Leistung von Webinhalten durch die vorhersehbare Isolierung einer DOM-Unterstruktur vom Rest der Seite zu verbessern.

Grundsätzlich kann ein Entwickler einem Browser mitteilen, welche Teile der Seite als Inhaltssatz eingekapselt sind. So können Browser über den Inhalt nachdenken, ohne den Zustand außerhalb der Unterstruktur berücksichtigen zu müssen. Wenn der Browser weiß, welche Inhaltselemente (Unterstrukturen) isolierten Inhalt enthalten, kann er Entscheidungen für die Optimierung des Seiten-Renderings treffen.

Es gibt vier Arten der CSS-Begrenzung. Jeder mögliche Wert für die CSS-Eigenschaft contain, der in einer durch Leerzeichen getrennten Liste von Werten kombiniert werden kann:

  • size: Durch die Größenbegrenzung eines Elements wird sichergestellt, dass die Box des Elements eingeblendet werden kann, ohne dass die Nachfolgerelemente untersucht werden müssen. Das bedeutet, dass wir das Layout der Nachfolger möglicherweise überspringen können, wenn wir nur die Größe des Elements benötigen.
  • layout: Layout-Begrenzung bedeutet, dass die Nachfolgerelemente keine Auswirkungen auf das externe Layout anderer Felder auf der Seite haben. So können wir das Layout der Nachfolger überspringen, wenn wir nur weitere Felder anlegen wollen.
  • style: Durch die Stilbegrenzung wird sichergestellt, dass Eigenschaften, die Auswirkungen auf mehr als nur die Nachfolgerelemente haben können, das Element nicht maskiert (z.B. Zähler). Auf diese Weise können wir die Stilberechnung für die Nachfolger überspringen, wenn nur Stile auf anderen Elementen berechnet werden sollen.
  • paint: Die Farbbegrenzung sorgt dafür, dass die Nachfolgerelemente der entsprechenden Box nicht außerhalb ihrer Begrenzungen angezeigt werden. Es darf nichts über das Element sichtbar sein. Wenn ein Element außerhalb des Bildschirms oder anderweitig nicht sichtbar ist, sind die Nachfolgerelemente ebenfalls nicht sichtbar. So können wir das Painting der Nachfolger überspringen, wenn das Element nicht auf dem Bildschirm zu sehen ist.

Rendering mit content-visibility überspringen

Es kann schwierig sein, herauszufinden, welche Begrenzungswerte zu verwenden sind, da Browseroptimierungen möglicherweise nur wirksam werden, wenn ein geeigneter Satz angegeben ist. Sie können mit den Werten experimentieren, um zu sehen, was am besten funktioniert, oder eine andere CSS-Eigenschaft namens content-visibility verwenden, um die erforderliche Begrenzung automatisch anzuwenden. content-visibility sorgt dafür, dass Sie als Entwickler mit minimalem Aufwand die größtmögliche Leistungssteigerung für den Browser erzielen.

Für die Eigenschaft „Inhaltssichtbarkeit“ sind mehrere Werte zulässig. Mit auto wird jedoch sofort die Leistung verbessert. Ein Element mit content-visibility: auto erhält die Begrenzung layout, style und paint. Wenn das Element nicht auf dem Bildschirm zu sehen ist (und für den Nutzer nicht relevant ist – wären Elemente mit Fokus oder Auswahl in ihrer Unterstruktur relevant), erhält es auch eine size-Begrenzung (und es wird nicht mehr übermalt und Treffer getestet).

Was bedeutet das? Kurz gesagt: Wenn sich das Element nicht auf dem Bildschirm befindet, werden die Nachfolgerelemente nicht gerendert. Der Browser bestimmt die Größe des Elements, ohne dessen Inhalt zu berücksichtigen, und beendet das Ereignis dort. Das Rendering, darunter Gestaltung und Layout der Unterstruktur des Elements, werden größtenteils übersprungen.

Wenn sich das Element dem Darstellungsbereich nähert, fügt der Browser die size-Begrenzung nicht mehr hinzu, malt den Inhalt des Elements und führt einen Treffertest durch. Dadurch kann das Rendering gerade rechtzeitig für den Nutzer sichtbar sein.

Hinweis zur Barrierefreiheit

Eine der Funktionen von content-visibility: auto ist, dass die nicht sichtbaren Inhalte im Dokumentobjektmodell und daher in der Baumstruktur für Barrierefreiheit verfügbar bleiben (im Gegensatz zu visibility: hidden). Das bedeutet, dass Inhalte auf der Seite gesucht und aufgerufen werden können, ohne auf ihr Laden warten zu müssen oder Abstriche bei der Rendering-Leistung zu machen.

Das Gegenteil ist jedoch, dass landmark-Elemente mit Stilelementen wie display: none oder visibility: hidden auch im Baum für Bedienungshilfen erscheinen, wenn sie sich außerhalb des Bildschirms befinden, da der Browser diese Stile erst rendert, wenn sie im Darstellungsbereich erscheinen. Um zu verhindern, dass diese in der Baumstruktur für Bedienungshilfen sichtbar sind und das zu Unordnung führen könnte, fügen Sie auch aria-hidden="true" hinzu.

Beispiel: ein Reiseblog

In diesem Beispiel liegt die Referenz für unseren Reiseblog auf der rechten Seite vor und content-visibility: auto wird auf die aufgeteilten Bereiche auf der linken Seite angewendet. Die Ergebnisse zeigen die Rendering-Zeiten, die beim ersten Seitenaufbau von 232 ms bis 30 ms liegen.

Ein Reiseblog enthält in der Regel eine Reihe von Geschichten mit einigen Bildern und einer Beschreibung. Beim Aufrufen eines Reiseblogs passiert Folgendes in einem typischen Browser:

  1. Ein Teil der Seite wird zusammen mit allen erforderlichen Ressourcen aus dem Netzwerk heruntergeladen.
  2. Der Browser gestaltet und erstellt den gesamten Inhalt der Seite, ohne zu berücksichtigen, ob er für den Nutzer sichtbar ist.
  3. Der Browser kehrt zu Schritt 1 zurück, bis alle Seite und Ressourcen heruntergeladen sind.

In Schritt 2 verarbeitet der Browser den gesamten Inhalt und sucht nach Änderungen. Der Stil und das Layout aller neuen Elemente werden aktualisiert, ebenso wie die Elemente, die sich infolge neuer Aktualisierungen möglicherweise verschoben haben. Das ist Rendering-Arbeit. Das dauert seine Zeit.

Screenshot eines Reiseblogs.
Beispiel für einen Reiseblog. Siehe Demo zu Codepen

Überlegen Sie nun, was passiert, wenn Sie content-visibility: auto für jede einzelne Story im Blog einfügen. Die allgemeine Schleife ist dieselbe: Der Browser lädt Blöcke der Seite herunter und rendert sie. Der Unterschied liegt jedoch in der Menge an Arbeit, die in Schritt 2 erledigt wird.

Wenn Inhalte sichtbar sind, werden alle Inhalte, die derzeit für den Nutzer (auf dem Bildschirm) sichtbar sind, gestaltet und angeordnet. Wenn jedoch eine Story verarbeitet wird, die nicht auf dem Bildschirm zu sehen ist, überspringt der Browser das Rendering und gestaltet nur das Elementfeld selbst.

Die Leistung beim Laden dieser Seite würde so aussehen, als würde sie vollständige Geschichten auf dem Bildschirm und leere Felder für jede der nicht sichtbaren Stories enthalten. Die Leistung ist deutlich besser, da sich die Renderingkosten beim Laden erwartet um mindestens 50% reduzieren. In unserem Beispiel sehen wir einen Anstieg von einer Renderingzeit von 232ms auf eine Renderingzeit von 30ms. Damit ist die Leistung um das 7-Fache gestiegen.

Welche Arbeit müssen Sie tun, um von diesen Vorteilen zu profitieren? Zunächst teilen wir den Inhalt in Abschnitte auf:

Ein kommentierter Screenshot, der das Aufteilen von Inhalt in Abschnitte mithilfe einer CSS-Klasse zeigt.
Beispiel für die Unterteilung von Inhalt in Abschnitte mit der angewendeten Klasse story, um content-visibility: auto zu erhalten. Siehe Demo zu Codepen

Anschließend wenden wir die folgende Stilregel auf die Abschnitte an:

.story {
  content-visibility: auto;
  contain-intrinsic-size: 1000px; /* Explained in the next section. */
}

Natürliche Größe eines Elements mit contain-intrinsic-size angeben

Um die potenziellen Vorteile von content-visibility nutzen zu können, muss der Browser eine Größenbeschränkung anwenden, damit sich die Rendering-Ergebnisse der Inhalte nicht auf die Größe des Elements auswirken. Das bedeutet, dass das Element so angeordnet wird, als wäre es leer. Wenn für das Element in einem normalen Blocklayout keine Höhe angegeben ist, hat es eine Höhe von 0.

Dies ist möglicherweise nicht ideal, da sich die Größe der Bildlaufleiste verändert, da jede Geschichte eine Höhe ungleich null hat.

Glücklicherweise bietet CSS eine weitere Eigenschaft, contain-intrinsic-size, die die natürliche Größe des Elements angibt, wenn das Element von einer Größenbegrenzung beeinflusst wird. In unserem Beispiel setzen wir ihn auf 1000px, um die Höhe und Breite der Abschnitte zu schätzen.

Das heißt, es wird so angeordnet, als hätte es ein einzelnes untergeordnetes Element mit unveränderlichen Abmessungen, sodass sichergestellt wird, dass Ihre nicht formatierten div-Elemente weiterhin Platz belegen. contain-intrinsic-size dient als Platzhaltergröße anstelle des gerenderten Inhalts.

In Chromium 98 und höher gibt es das neue Keyword auto für contain-intrinsic-size. Wenn angegeben, merkt sich der Browser die zuletzt gerenderte Größe, falls vorhanden, und verwendet diese anstelle der vom Entwickler bereitgestellten Platzhaltergröße. Wenn Sie beispielsweise contain-intrinsic-size: auto 300px angegeben haben, beginnt das Element mit einer intrinsischen Größe von 300px in jeder Dimension. Sobald der Inhalt des Elements gerendert wurde, behält es jedoch die gerenderte intrinsische Größe bei. Alle nachfolgenden Änderungen der Rendering-Größe werden ebenfalls gespeichert. In der Praxis bedeutet dies, dass beim Scrollen eines Elements mit angewendetem content-visibility: auto und dann wieder aus dem Bildschirm zurückscrollen, behält es automatisch seine ideale Breite und Höhe bei und wird nicht wieder auf die Platzhaltergröße zurückgesetzt. Diese Funktion ist besonders nützlich für unendliche Scrollen, die jetzt automatisch die Größenschätzung im Laufe der Zeit verbessern kann, wenn der Nutzer die Seite erkundet.

Inhalte werden mit content-visibility: hidden ausgeblendet

Was ist, wenn die Inhalte nicht gerendert werden sollen, unabhängig davon, ob sie auf dem Bildschirm zu sehen sind oder nicht, und gleichzeitig die Vorteile des Renderingstatus im Cache nutzen möchten? Geben Sie Folgendes ein: content-visibility: hidden.

Das Attribut content-visibility: hidden bietet dieselben Vorteile wie nicht gerenderte Inhalte und im Cache gespeicherter Renderingstatus wie content-visibility: auto außerhalb des Bildschirms. Im Gegensatz zu auto wird das Rendering auf dem Bildschirm jedoch nicht automatisch gestartet.

Dadurch erhalten Sie mehr Kontrolle und können den Inhalt eines Elements ausblenden und später schnell wieder einblenden.

Vergleichen Sie dies mit anderen gängigen Methoden zum Ausblenden von Elementinhalten:

  • display: none: blendet das Element aus und löscht seinen Renderingstatus. Dies bedeutet, dass das Einblenden eines Elements genauso teuer ist wie das Rendern eines neuen Elements mit demselben Inhalt.
  • visibility: hidden: blendet das Element aus und behält seinen Renderingstatus bei. Dadurch wird das Element nicht vollständig aus dem Dokument entfernt, da es (und seine Unterstruktur) immer noch geometrischen Raum auf der Seite einnimmt und weiterhin angeklickt werden kann. Außerdem wird der Renderingstatus bei Bedarf aktualisiert, auch wenn er ausgeblendet ist.

content-visibility: hidden blendet hingegen das Element aus und behält seinen Renderingstatus bei. Änderungen, die vorgenommen werden müssen, werden also nur ausgeführt, wenn das Element wieder angezeigt wird, d. h. die Eigenschaft content-visibility: hidden entfernt wird.

Einige gute Anwendungsfälle für content-visibility: hidden sind die Implementierung erweiterter virtueller Scroller und das Messen des Layouts. Sie eignen sich auch bestens für Single-Page-Anwendungen (SPA). Inaktive App-Ansichten können im DOM mit content-visibility: hidden belassen werden, um die Anzeige zu verhindern, aber ihren Cache-Status beizubehalten. Dadurch wird die Ansicht schnell gerendert, wenn sie wieder aktiv wird.

Auswirkungen auf die Interaktion mit Next Paint (INP)

INP ist ein Messwert, der die Fähigkeit einer Seite bewertet, zuverlässig auf Nutzereingaben zu reagieren. Die Reaktionsfähigkeit kann durch übermäßig viel Arbeit im Hauptthread, einschließlich Rendering, beeinträchtigt werden.

Wenn Sie das Rendering auf einer bestimmten Seite reduzieren können, geben Sie dem Hauptthread die Möglichkeit, schneller auf Nutzereingaben zu reagieren. Dazu gehört auch das Rendering. Die Verwendung der CSS-Eigenschaft content-visiblity kann den Rendering-Aufwand reduzieren, insbesondere beim Start, wenn die meisten Rendering- und Layout-Arbeiten erledigt sind.

Eine Reduzierung der Rendering-Arbeit hat direkte Auswirkungen auf INP. Wenn Nutzer versuchen, mit einer Seite zu interagieren, für die die content-visibility-Eigenschaft ordnungsgemäß verwendet wird, um das Layout und das Rendern nicht sichtbarer Elemente zu verzögern, gibst du dem Hauptthread die Möglichkeit, auf wichtige für Nutzer sichtbare Inhalte zu reagieren. Dadurch kann der INP-Wert deiner Seite in manchen Situationen verbessert werden.

Fazit

content-visibility und die CSS-Eindämmungsspezifikation bedeuten, dass Sie direkt in Ihrer CSS-Datei aufregende Leistungsoptimierungen haben werden. Weitere Informationen zu diesen Eigenschaften finden Sie hier: