Back

ResizeObserver vs. Window Resize: Wann welche Methode verwenden

ResizeObserver vs. Window Resize: Wann welche Methode verwenden

Sie entwickeln eine Diagrammkomponente, die neu gezeichnet werden muss, wenn ihr Container schrumpft. Sie greifen zu window.addEventListener('resize', ...) und es funktioniert größtenteils – bis sich das Panel aufgrund einer einklappenden Seitenleiste verändert und nichts ausgelöst wird. Das ist das Kernproblem, das dieser Artikel behandelt.

Wichtigste Erkenntnisse

  • Das window Resize-Event wird nur ausgelöst, wenn sich die Größe des Browser-Viewports ändert. Es weiß nichts über einzelne DOM-Elemente.
  • ResizeObserver überwacht spezifische Elemente und wird ausgelöst, wenn sich deren Dimensionen ändern, unabhängig von der Ursache.
  • Das Abfragen von Elementgrößen nach einer Viewport-Größenänderung ist fehleranfällig – es übersieht Änderungen durch CSS-Toggles, dynamischen Content, Schriftarten-Laden und mehr.
  • Für container-basiertes Styling ohne JavaScript sind CSS Container Queries das bevorzugte Werkzeug.

Was jede API tatsächlich beobachtet

Das window Resize-Event wird ausgelöst, wenn sich die Größe des Browser-Viewports ändert. Das ist sein gesamter Geltungsbereich. Es weiß nichts über einzelne DOM-Elemente.

ResizeObserver überwacht spezifische Elemente und wird ausgelöst, wenn sich deren Dimensionen ändern – unabhängig davon, was die Änderung verursacht hat. Eine Viewport-Größenänderung, eine DOM-Einfügung, ein CSS-Klassen-Toggle, ein Reflow des übergeordneten Flexbox-Containers – all dies löst den Observer aus, wenn sich die Größe des Elements ändert.

Das ist der grundlegende Unterschied. Sie beobachten unterschiedliche Dinge und werden normalerweise für unterschiedliche Aufgaben gewählt.

Wann das Window Resize-Event zu verwenden ist

Das window Resize-Event ist das richtige Werkzeug, wenn Ihre Logik tatsächlich von den Viewport-Dimensionen abhängt, nicht von der Größe eines bestimmten Elements:

  • Umschalten eines mobilen Navigationslayouts bei einem Viewport-Breakpoint
  • Größenanpassung eines ganzseitigen Canvas oder WebGL-Kontexts an window.innerWidth / window.innerHeight
  • Anpassung des globalen Layout-Zustands, der vom verfügbaren Bildschirmplatz abhängt
window.addEventListener('resize', () => {
  canvas.width = window.innerWidth
  canvas.height = window.innerHeight
  render()
})

Für rein visuelle, CSS-gesteuerte Reaktionen auf die Viewport-Größe sollten Sie Media Queries anstelle von JavaScript bevorzugen.

Wann ResizeObserver zu verwenden ist

ResizeObserver-Anwendungsfälle konzentrieren sich auf Verhalten auf Komponentenebene, das auf die tatsächliche gerenderte Größe eines Elements reagieren muss:

  • Ein Diagramm, das Achsenskalierungen neu berechnet, wenn sich die Breite seines Containers ändert
  • Ein Texteditor, der das Toolbar-Layout basierend auf dem verfügbaren Platz anpasst
  • Ein Widget mit veränderbarer Größe oder ein Split-Pane-Widget
  • Jedes eingebettete Widget, das seinen eigenen Container nicht kontrolliert
const ro = new ResizeObserver((entries) => {
  for (const entry of entries) {
    const { inlineSize, blockSize } = entry.contentBoxSize[0]
    chart.resize(inlineSize, blockSize)
  }
})

ro.observe(document.querySelector('.chart-container'))

Die moderne API-Struktur verstehen

Die aktuelle ResizeObserver-API stellt contentBoxSize- und borderBoxSize-Arrays für jeden Eintrag bereit – jedes enthält inlineSize (Breite bei horizontalen Schreibmodi) und blockSize (Höhe). Die ältere contentRect-Eigenschaft funktioniert noch, existiert aber hauptsächlich aus Gründen der Abwärtskompatibilität. Bevorzugen Sie contentBoxSize[0] in neuem Code.

Warum nicht einfach nach einem Window Resize abfragen?

Ein gängiges Muster – auf das window Resize-Event zu hören und dann getBoundingClientRect() auf Elementen aufzurufen – ist fehleranfällig. Es übersieht Größenänderungen, die nichts mit dem Viewport zu tun haben: dynamisches Laden von Inhalten, umgeschaltete CSS-Klassen, eingefügte Kindelemente, Schriftarten-Laden. ResizeObserver erfasst all dies. Das Abfragen nach einer Viewport-Größenänderung tut dies nicht.

Performance und Feedback-Schleifen

ResizeObserver-Callbacks werden nach dem Layout und vor dem Paint ausgeführt, was bedeutet, dass DOM-Lesevorgänge innerhalb des Callbacks das aktuelle Layout widerspiegeln, ohne einen Reflow zu erzwingen. Dies ist strukturell sicherer als das Lesen von Layout-Eigenschaften innerhalb eines resize-Event-Handlers.

Ein Stolperstein: Wenn Sie die Größe eines beobachteten Elements innerhalb seines eigenen Callbacks ändern, lösen Sie eine weitere Beobachtung aus. ResizeObserver handhabt dies, indem Beobachtungen bei progressiv tieferen DOM-Tiefen innerhalb desselben Frames verarbeitet werden und schließlich ein Fehler gemeldet wird, wenn sich der Zyklus nicht auflöst – um Endlosschleifen zu verhindern. Sie sollten dennoch bewusst damit umgehen, was Sie innerhalb des Callbacks schreiben.

Der Performance-Vorteil von ResizeObserver wird bedeutsam, wenn Ihr Callback das Layout berührt oder wenn Größenänderungen von Elementen unabhängig von Viewport-Größenänderungen auftreten.

Die Alternative: CSS Container Queries

Wenn Ihr Ziel das Styling eines Elements basierend auf der Größe seines Containers ist, sind CSS Container Queries das richtige Werkzeug – kein JavaScript erforderlich. Reservieren Sie ResizeObserver für Fälle, in denen Laufzeit-Logik, nicht Styling, auf Größenänderungen reagieren muss.

SzenarioBestes Werkzeug
Viewport-weite Layout-Änderungenwindow Resize-Event
Element-Dimensionen steuern JS-LogikResizeObserver
Nur container-basiertes StylingCSS Container Queries

Fazit

Verwenden Sie das window Resize-Event, wenn Sie sich für den Viewport interessieren. Verwenden Sie ResizeObserver, wenn Sie sich für ein Element interessieren. Verwenden Sie CSS Container Queries, wenn Sie nur Styles ändern müssen. Diese drei Werkzeuge decken den gesamten Bereich des responsiven Verhaltens ab – wählen Sie dasjenige, das zu dem passt, was Sie tatsächlich messen.

FAQs

ResizeObserver wird ausgelöst, wenn sich die Dimensionen eines Elements ändern, sodass das Zusammenklappen eines Elements auf null Breite oder Höhe es auslöst. Es wird jedoch nicht bei Sichtbarkeits- oder Deckkraft-Änderungen ausgelöst, die die Dimensionen intakt lassen. Für echte Sichtbarkeitserkennung verwenden Sie stattdessen IntersectionObserver.

Der Observer stoppt automatisch die Verfolgung eines Elements, sobald es vom Garbage Collector erfasst wird. Allerdings ist das explizite Aufrufen von unobserve oder disconnect eine gute Praxis, insbesondere in Single-Page-Anwendungen oder Framework-Komponenten mit Mount- und Unmount-Lebenszyklen, um veraltete Referenzen und unerwartete Callbacks zu vermeiden.

Ja. ResizeObserver hat breite Unterstützung in Chrome, Firefox, Safari und Edge. Wenn Sie ältere Browser unterstützen müssen, ist ein Polyfill verfügbar, obwohl es intern auf Polling und Mutation Observers basiert und daher nicht die native Performance erreicht.

Normalerweise nicht für leichtgewichtige UI-Updates. ResizeObserver bündelt Benachrichtigungen bereits effizient innerhalb der Rendering-Pipeline. Wenn Ihr Callback jedoch teure nachgelagerte Arbeiten wie Netzwerkanfragen oder aufwändige Berechnungen auslöst, sollten Sie diese spezifische Arbeit debouncen, anstatt den gesamten Callback.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay