Startseite / Artikel / Überspringen des Außerhalb-des-Bildschirms-Renderings mit „content-visibility“ und „contain-intrinsic-size“

Überspringen des Außerhalb-des-Bildschirms-Renderings mit „content-visibility“ und „contain-intrinsic-size“

Erfahren Sie, wie „content-visibility“ die Layoutkosten auf langen, vom Server bereitgestellten Seiten reduziert, warum „contain-intrinsic-size“ erforderlich ist und wie es sich im Vergleich zur Virtualisierung verhält.

2789 Wörter

Lange Seiten, die voller wiederkehrender Elemente sind – wie Produktlisten, Feeds, Archiven und große Tabellen – wirken oft langsam, selbst wenn die dazugehörige JavaScript-Datei klein ist. Der Grund liegt meist darin, dass der Browser für jedes Element auf der Seite Styles und Layout berechnet – einschließlich Hunderten von Karten, zu denen der Besucher noch nicht gescrollt hat und die er vielleicht niemals erreichen wird. Diese Anleitung zeigt, wie zwei CSS-Eigenschaften, content-visibility und contain-intrinsic-size, es dem Browser ermöglichen, diese Berechnungen hinauszuzögern, wie sich dieser Wandel auf Core Web Vitals und die Indexierung auswirkt – sowie wo diese Technik versagt oder das falsche Mittel ist.

Ein typischer Fall: eine lange Liste, die aus unklaren Gründen langsam ist

Stellen Sie sich eine Kategorie-Seite „Alle Produkte ansehen“ für einen Online-Shop vor. Etwa 600 Produktkarten, jede mit einem Bild, einem Titel, einem Preis und einer Bewertung, werden auf dem Server zu einer einzigen langen Seite zusammengefasst. Es gibt weder Paginierung noch unbegrenztes Scrollen und keine Virtualisierung. Der Betreiber bevorzugt es so: eine einzige URL, jedes Produkt ist auffindbar, alles ist über die Suchfunktion des Browsers erreichbar.

Auf einem Laptop der Mittelklasse dauert es fast vier Sekunden, bis die Seite interaktiv wirkt. Der erste Verdächtige ist JavaScript: ein zu großer Bundle, ein fehlerhaftes useEffect, eine wiederholte Neulayoutung von Komponenten. Eine genaue Prüfung des Bundles ergibt jedoch nichts, was die Verzögerung erklären könnte.

Das Leistungs-Panel in DevTools erzählt eine andere Geschichte. Der größte Teil der Zeit auf dem Hauptthread wird für Layout aufgewendet – und das bereits, bevor irgendein Skript eine Rolle spielen kann.

Warum offscreen befindliches Content Ihnen trotzdem Kosten verursacht

Die Darstellung ist keine einzige Aktion. Zunächst berechnet der Browser die Styles für jedes Element, danach führt er das Layout aus, um die Größe und Position jeder Box zu bestimmen, und erst danach werden die Pixel dargestellt. Die Darstellung beschränkt sich größtenteils auf das, was innerhalb oder in der Nähe des Sichtbereichs liegt, doch die Styles-Berechnung und das Layout werden für den gesamten Dokumentinhalt durchgeführt, einschließlich des Inhalts weit unterhalb des Sichtbereichs. Bis der Browser entschieden hat, was dargestellt werden soll, ist die aufwändige geometrische Verarbeitung bereits abgeschlossen.

In dem Ladenbeispiel bedeutet das, dass alle 600 Karten – jeweils mit einem Bildfeld, einem Überschriftsfeld für die Verpackung, einem Preis sowie einer Bewertungszeile – erst Stil- und Layout-Einstellungen durchlaufen müssen, bevor der Käufer die erste Karte sieht. Der Käufer sieht vermutlich nur acht Produkte. Die anderen 592 sind vorerst nutzlos, doch der Browser hat keine Möglichkeit zu erkennen, ob der Besucher jemals nach unten scrollen wird; daher behandelt er sie standardmäßig als Inhalt, der sofort bereitstehen muss. Das ist der Verschwendung, die beseitigt werden sollte. Wenn Sie einen Überblick darüber möchten, wie sich diese Pipeline-Phasen hinsichtlich der Kosten unterscheiden, lesen Sie unsere Aufschlüsselung zu den Kosten für Reflow, Repaint und Composite für den Browser.

Die Lösung: Zwei Deklarationen für das wiederkehrende Element

Wenden Sie beide Eigenschaften auf das wiederholte Element an, in diesem Fall die Produktkarte. Die erste weist den Browser an, die Darstellung des Inhalts der Karte zu überspringen, wenn sie sich weit vom Sichtbereich entfernt befindet. Die zweite gibt eine Platzhaltergröße für Karten an, deren tatsächliche Größe noch nicht bekannt ist.

.product-card {
  content-visibility: auto;
  contain-intrinsic-size: auto 340px;
}

Mit content-visibility: auto bleibt eine Karte, die sich nicht in der Nähe des Sichtbereichs befindet, im DOM sowie im Zugänglichkeitsbaum erhalten, und „find-in-page“ kann weiterhin ihren Text finden. Was sich ändert, ist, dass der Browser keine Ressourcen für Stil, Layout und Darstellung des Inhalts aufwendet, solange sich die Karte noch vom Bildschirm entfernt befindet. Im Hintergrund wendet die Eigenschaft eine Einschränkung von Layout, Stil und Darstellung auf das Element an, wodurch der Browser den Unterbaum als unabhängig betrachten und ihn sicher überspringen kann.

Wie groß die Vorteile sein können

In einer auf web.dev veröffentlichten Demo hat Google eine umfangreiche Seite, die in Abschnitte unterteilt war, bearbeitet und die Ladezeit von 232 ms auf 30 ms reduziert – das entspricht einer Verbesserung um etwa das Siebenfache. Zu beachten ist, dass es sich dabei um eine speziell dafür erstellte Demo-Seite und nicht um eine Produktseite handelt. Bei einer echten Produktdarstellung wie der oben beschriebenen ist eine Verbesserung um etwa das Zweifache realistischer; selbst diese kann bereits den Unterschied zwischen einer Seite, die weiterhin lädt, und einer Seite ausmachen, die bereits beim ersten Zeichnen fertig erscheint.

Extreme Beispiele zeigen das maximale Potenzial. In einem Vortrag auf dem Chrome Dev Summit wurde diese Eigenschaft auf eine riesige, einseitige HTML-Spezifikation mit mehr als 270.000 DOM-Noden angewandt, wodurch die Layout-Zeit von etwa 50 Sekunden auf rund 400 Millisekunden sank. Nur wenige Seiten sehen so aus, doch sie veranschaulichen, wie viel Aufwand in Inhalte investiert wird, die niemand sehen kann.

Es ist hilfreich, genau zu beschreiben, was vor sich geht. CSS macht den Prozessor nicht schneller. Man teilt dem Browser mit, dass ein großer Teil der Arbeit nicht sofort ausgeführt werden muss. Wenn eine Seite 600 Karten enthält und der Ansichtsbereich nur acht anzeigt, ist das Vorausrendern aller Karten selten die beste Nutzung des Hauptthreads.

Warum „contain-intrinsic-size“ nicht optional ist

Führt man allein content-visibility: auto ein, beginnt der Scrollbalken beim Scrollen zu springen, was leicht fälschlicherweise als ein unabhängiger Fehler angesehen werden kann.

Der Grund ist einfach. Eine Karte, deren Layout übersprungen wurde, hat keine bekannte Höhe, weshalb sie als leer behandelt wird. Bei Hunderten übersprungener Karten ist die Gesamthöhe des Dokuments stark fehlerhaft, und der Scrollbalken spiegelt diese falsche Höhe wider. Sobald die Karten sichtbar werden und ihre tatsächliche Größe erhalten, wächst das Dokument an und der Scrollbalken verschiebt sich.

contain-intrinsic-size gibt die Größe an, die angenommen werden soll, wenn ein Element übersprungen wird. Der Wert 340px im Beispiel ist eine Schätzung für Karten, die noch nicht dargestellt wurden. Genauigkeit ist nicht erforderlich; eine angemessene Annäherung verhindert, dass der Scrollbalken sichtbar zuckt.

Was das Schlüsselwort auto hinzufügt

Das Schlüsselwort auto wird leicht übersehen, ist aber von großer Bedeutung. Bei auto speichert der Browser, sobald eine Karte dargestellt wurde, ihre tatsächliche Größe. Wenn die Karte später den Sichtbereich verlässt und erneut übersprungen wird, verwendet der Browser diese gespeicherte Größe anstelle Ihrer Schätzung. Ohne auto greift jede Karte jedes Mal, wenn sie außer Sichtweite scrollt, wieder auf die feste Schätzung zurück.

Die Karten auf dem Bildschirm werden in jedem Fall immer in ihrer tatsächlichen Höhe angezeigt. Der Unterschied zeigt sich bei Inhalten mit variabler Höhe: einem langen Produktnamen, der auf eine zusätzliche Zeile umgeleitet wird, oder einem Rabatt-Icon, das eine weitere Zeile hinzufügt. Ohne auto kehren diese Karten bei Verlassen des Sichtbereichs und bei einem Scrollen in die geschätzte Höhe zurück. Verwenden Sie immer auto.

Browserunterstützung und progressive Enhancement

Die Unterstützung ist nicht mehr nur auf Chrome beschränkt. Chrome unterstützt content-visibility bereits seit Version 85 (2020), Firefox seit Version 125 und Safari seit Version 18. Zum Zeitpunkt der Erstellung wird dieser Standard als „Baseline Newly Available“ geführt – ein Status, den er am 15. September 2025 erreicht hat, was bedeutet, dass er in allen drei großen Browsern funktioniert; überprüfen Sie die aktuellen Kompatibilitätsdaten, falls Sie ältere Versionen unterstützen.

Browser, die diese Eigenschaft nicht verstehen, ignorieren sie einfach und rendern alles wie gewohnt. Dadurch handelt es sich um eine progressive Verbesserung, die älteren Clients keinen Nachteil bringt.

Wie es mit Core Web Vitals und SEO zusammenhängt

Die Motivation hier ist die Leistung, doch Kategoriseiten sind genau die Art von URL-Adressen, auf die Suchteams besonders achten. Sie sind öffentlich, richten sich an wertvolle Abfragen, und Google misst deren Leistung für echte Nutzer.

Layout- und Paint-Aufgaben fließen in zwei der drei Core Web Vitals ein, die Google als Ranking-Signal verwendet:

  • Interaction to Next Paint (INP) profitiert direkt davon. Das Auslassen der Renderung von Karten außerhalb des Sichtbereichs befreit den Hauptthread, sodass Tippen und Klicken schneller eine Reaktion erhalten.
  • Largest Contentful Paint (LCP) profitiert eher indirekt. Auf langen Seiten ermöglicht weniger Layout vor der ersten Darstellung in der Regel, dass der große sichtbare Inhalt früher angezeigt wird.
  • Viele nicht-kommerzielle Seiten weisen dieses Muster auf – von Dokumentationen und Nachrichtenfeeds über Archivierungen von Blogbeiträgen bis hin zu langen Diskussionssträngen und mehrteiligen Artikeln. Überall dort, wo viele ähnliche Elemente vertikal angeordnet sind und die meisten zunächst außerhalb des Sichtbereichs liegen, sowie wenn die Seite öffentlich zugänglich ist, beeinflusst diese Veränderung die von Google gemessenen Metriken.

    Achten Sie darauf, keine Verbesserungen in der Suchrankung zu versprechen. Eine Beobachtung einer einzigen Website über einige Wochen sagt nur sehr wenig aus, und die Suchrankung hängt von weitaus mehr als nur einer Metrik ab. Was man vernünftigerweise erwarten kann, ist eine Bewegung in die richtige Richtung in den Felddaten – beispielsweise in PageSpeed Insights – sobald genügend echte Benutzerbeispiele vorliegen.

    Der Vorteil beschränkt sich nicht auf öffentliche Seiten. Dashboards, Admin-Tabellen und interne Tools leiden unter derselben Rechenlast von 600 Zeilen bei der Darstellung. Hinter einem Anmeldevorgang gibt es keinen zusätzlichen Suchvorteil, doch der Nutzererfahrungszuwachs bleibt derselbe und wird durch denselben CSS-Code erreicht.

    Versteckt das Auslassen der Darstellung Inhalte vor Crawlern?

    Das ist die erste Frage, die ein sorgfältiger SEO-Spezialist stellt – und sie ist durchaus berechtigt, angesichts der vielen Lazy-Loading-Methoden, die Inhalte für Bots unsichtbar machen. Der entscheidende Unterschied besteht darin, dass content-visibility: auto eine Optimierung der Darstellung ist und keine Änderung der Sichtbarkeit. Der Inhalt existiert bereits im HTML und im DOM vom Moment an, in dem die Seite geladen wird; nur die Layout- und Darstellungsprozesse werden aufgeschoben, bis das Element der Sichtbereich näherkommt.

    Googlebot scrollt nicht auf die gleiche Weise wie ein Mensch. Stattdessen verwendet er einen äußerst hohen Ansichtsbereich zur Darstellung und untersucht anschließend den entstandenen DOM. Karten, die übersprungen werden aber vorhanden sind, gehören zu diesem DOM, sodass jeder Produkttitel und jede Preisangabe wie jedes andere Inhaltsstück indiziert wird.

    Vergleichen Sie das mit dem älteren Verfahren, bei dem Inhalte erst dann eingefügt werden, wenn ein Scroll-Ereignis ausgelöst wird. Crawler erzeugen keine Scroll-Ereignisse, wodurch solche Inhalte tatsächlich aus dem Index fehlen könnten. content-visibility kann dieses Problem nicht verursachen, denn nichts wird später hinzugefügt; alles ist von Anfang an vorhanden.

    Eine Einschränkung hat nichts mit der Eigenschaft selbst zu tun. Wenn die Seite ihren Inhalt mithilfe von Client-Side-JavaScript erstellt, entsteht ein separates SEO-Problem. Googlebot führt zwar JavaScript aus, doch die Darstellung wird in der Warteschlange abgehandelt, was langsamer und weniger zuverlässig ist; zudem handhaben viele andere Crawler JavaScript schlecht. Für öffentlichen Inhalt sollte der HTML auf dem Server gerendert werden und zusätzlich content-visibility im CSS hinzugefügt werden. Diese Kombination sorgt für crawbaren Inhalt sowie bessere Leistungsindikatoren.

    Vergleich mit Endlosscrollen, Virtualisierung und benutzerdefinierten Observern

    Endlosscrollen, paginierte APIs und Virtualisierung beheben alle das gleiche Problem langsam arbeitender, langer Seiten – daher lohnt es sich, sie ehrlich miteinander zu vergleichen.

    Laden beim Scrollen und paginierte APIs

    Das Laden weiterer Elemente beim Scrollen des Benutzers löst das Problem auf der Datenebene. Es ist die richtige Wahl, wenn das Datenset tatsächlich sehr groß ist und niemals vollständig an den Browser übertragen werden sollte.

    Das hat seine Kosten. Es sind API-Änderungen, Ladezustände, Scroll-Listener sowie Zustandsverfolgung für bereits heruntergeladene Inhalte erforderlich. Auch die Benutzererfahrung ändert sich: Die Funktion „Suche in der Seite“ kann Elemente nicht finden, die noch nicht geladen wurden, und das Erreichen des Endes der Liste wird mühsam. Auf einer öffentlichen Kategoriseite entsteht außerdem eine zusätzliche SEO-Belastung, da Produkte, die erst nach Scrollen sichtbar werden, für Suchmaschinen nicht existieren; es sind paginierte Ersatz-URLs sowie zusätzliche Markup-Elemente nötig, um sie indexierbar zu halten. Für 600 Karten, die bereits im HTML vorhanden sind, bedeutet das eine Neuschreibung sowie zusätzliche SEO-Arbeit, um ein eigentliches Darstellungsproblem zu beheben.

    Virtualisierungsbibliotheken

    Durch Virtualisierung mit Bibliotheken wie react-window oder TanStack Virtual wird das gesamte Datensatz in Erinnerung gehalten, während DOM-Elemente für alles außerhalb des sichtbaren Fensters entfernt werden. Das funktioniert und ist bei sehr großen Datenmengen die bessere Wahl, wie im Folgenden erläutert.

    Der Preis hängt von einer JavaScript-Abhängigkeit, einem Neuschreiben der Komponente sowie der äußerst schwierigen Handhabung von Zeilen mit variabler Höhe ab. Da entfernte Elemente überhaupt nicht im DOM vorhanden sind, kann „find-in-page“ sie nicht erkennen, Bildschirmleser haben Schwierigkeiten damit, und auf öffentlichen Seiten übersehen sie die Crawler.

    Eine manuell implementierte IntersectionObserver-Lösung

    Das Eigenständige Rendern von Elementen, sobald ein IntersectionObserver sie als sichtbar meldet, bedeutet, im Hauptthread von JavaScript das zu wiederholen, was bereits content-visibility: auto leistet, sowie alte Probleme mit dem Scroll-Anchoring wieder einzuführen, die der Browser bereits nativ gelöst hat. Es gibt heute kaum einen Grund, so etwas zu schreiben.

    Auswahl zwischen den Ansätzen

    Der eigentliche Vorteil von content-visibility liegt nicht darin, dass es diesen Techniken überlegen ist, sondern darin, dass es weitaus günstiger ist. Es handelt sich dabei um eine einzige CSS-Eigenschaft: kein JavaScript, keine Änderungen an APIs, keine Neuimplementierung – und der Inhalt bleibt im DOM für Suchfunktionen, Assistenztechnologien sowie die Suche innerhalb der Seite erhalten.

    Der Kompromiss muss klar dargelegt werden. content-visibility spart Rechenleistung beim Rendern, nicht Speicher. Jeder DOM-Node existiert weiterhin. Bei 600 Karten ist das vernachlässigbar. Bei 50.000 oder 100.000 Elementen wird die Größe des DOMs zu einem eigenen Problem, und dann lohnt sich die Virtualisierung aufgrund ihrer Komplexität. Bestimmen Sie zunächst, welches der beiden Probleme vorliegt – Rechenkosten oder DOM-Größe –, bevor Sie ein Tool wählen.

    Wo es funktioniert und wo es heimlich Probleme verursacht

    Es handelt sich dabei nicht um eine Eigenschaft, die überall eingesetzt werden sollte. Sie ist am sinnvollsten dort, wo dieselbe Struktur sich häufig wiederholt – beispielsweise:

    • Karten in einem Katalog oder einer Auflistung
  • Beiträge in einem sozialen Netzwerk oder Feed
  • Spalten einer großen Datentabelle
  • Antworten unter einem Artikel
  • Abschnitte einer langen Dokumentenseite
  • Einträge auf einer Ergebnisseite
  • Jedes Element, das zu vielen ähnlichen Blöcken gehört, die vertikal gestapelt sind und von denen die meisten beim Laden außerhalb des Sichtbereichs liegen, eignet sich gut zum Testen.

    Messung von übersprungenem Inhalt liefert falsche Werte

    Diese Eigenschaft steht im Widerspruch zu Code, der genaue Geometriedaten eines Unterbaums benötigt, bevor dieser dargestellt wird. Ein typisches Beispiel ist das Ablesen der Höhe eines inneren Elements einer Spalte, die noch außerhalb des Sichtbereichs ist.

    const height = row
      .querySelector('.details')
      .getBoundingClientRect()
      .height;
    

    Die Messung des inneren Inhalts eines übersprungenen Elements mit getBoundingClientRect() bevor es überhaupt dargestellt wird, liefert Nullwerte oder sonstige fehlerhafte Werte. Der eigene Box-Objekt des Elements gibt die Größe des Platzhalters aus contain-intrinsic-size an, was ebenfalls nicht der Realität entsprechen kann. Solcher Code kommt in echten Benutzeroberflächen häufig vor, zum Beispiel dann, wenn Sie:

    • einen Tooltip neben einem Auslöser platzieren
    • Start- und Endwerte für eine Animation berechnen
    • entscheiden, wo ein Dropdown-Menü erscheint
    • Zeilen in einer virtuellen Liste dimensionieren
    • die Logik für ein festes Positionieren steuern
    • einen Komponenten neben einen anderen ausrichten

    Falls genaue Geometriedaten vor dem Sichtbarwerden des Inhalts wichtig sind, sollten Sie gründlich testen, bevor Sie diese Eigenschaft verwenden.

    Weitere ungeeignete Ansätze

    • Klebende Überschriften sowie Layouts, deren Berechnungen nur dann funktionieren, wenn alle Kinder gleichzeitig eine echte Geometrie haben.
    • Jeder Inhalt, der oberhalb des Sichtbereichs liegt. Dieser muss unabhängig davon sofort dargestellt werden, wodurch die Eigenschaft keinen Vorteil bringt und zusätzliche Verwaltungsaufwand verursacht.
    • Elemente, deren visuelle Effekte über ihren eigenen Rahmen hinausreichen. Da die Eigenschaft eine Einschränkung der Darstellung durch den Rahmen vornimmt, kann überlaufender Inhalt wie große Schatten oder Popovers, die innerhalb der Karte platziert sind, an den Rändern der Karte abgeschnitten werden.

    Zwei weniger bekannte Details

    Der versteckte Wert

    content-visibility: hidden überspringt die Darstellung ähnlich wie display: none, doch der Browser speichert den Darstellungsstatus des Elements. Es erneut anzuzeigen ist deutlich kostengünstiger als ein display: none-Element sichtbar zu machen, da die Arbeit nicht von vorne durchgeführt werden muss. Dadurch eignet es sich gut für Tab-Elemente, Menüs außerhalb des Sichtbereichs und virtuelle Scrollbalken. Im Gegensatz zu auto ist Inhalt unter hidden während dieser Einstellung nicht über „Finden in Seite“ erreichbar.

    Auf Änderungen des Überspring-Zustands reagieren

    Jedes Mal, wenn ein Element mit content-visibility: auto zwischen dem übersprungenen und dem dargestellten Zustand wechselt, sendet der Browser ein contentvisibilityautostatechange-Event. Durch das Abhören dieses Events können teure Skripte, wie zum Beispiel Zeichnungen in einem Canvas, für Inhalt pausiert werden, den der Browser ohnehin nicht darstellt.

    Die Wirkung auf eigenen Seiten überprüfen

    Ein schnelles Experiment macht den Unterschied deutlich. Erstellen Sie eine Testseite mit etwa 1.000 Karten sowie einem Schalter, der content-visibility: auto hinzufügt oder entfernt. Öffnen Sie die DevTools, gehen Sie zum Performance-Panel, nehmen Sie eine Neu laden-Aufzeichnung ohne Schalter vor und dann erneut mit aktiviertem Schalter, und vergleichen Sie die lila Layout-Blöcke in den beiden Aufzeichnungen.

    Anwenden Sie anschließend die gleiche Überprüfung auf Ihre längste Produktionsseite. Erstellen Sie eine Aufzeichnung, während sie lädt. Wenn der Layout-Anteil dominiert und die Interaktivität erst spät eintritt, ist das Hinzufügen von content-visibility: auto zu den wiederkehrenden Elementen oft die kostengünstigste wirkliche Verbesserung: eine Eigenschaft, keine Neuimplementierung, keine Migration in ein anderes Framework.

    Kernpunkte

    • Browser steuern den Stil und die Gestaltung für das gesamte Dokument; content-visibility: auto ermöglicht es ihnen, diese Aufgabe auf Elemente zu verschieben, die weit vom Sichtbereich entfernt sind, ohne etwas aus dem DOM zu entfernen.
    • Kombinieren Sie dies immer mit contain-intrinsic-size: auto <Schätzung> in derselben Änderung, sonst springt der Scrollbalken.
    • Der Inhalt bleibt indizierbar, suchbar und zugänglich – das unterscheidet ihn von Methoden wie „Load-on-Scroll“ und Virtualisierung.
    • Es spart Renderzeit, nicht Speicher; sobald der DOM selbst zu groß wird, ist Virtualisierung die richtige Lösung.
    • Vermeiden Sie diese Methode oberhalb des sichtbaren Bereichs, bei Elementen, deren Geometrie vor der Anzeige gemessen wird, sowie bei Komponenten, die außerhalb ihres eigenen Rahmens zeichnen.