Blog

React use() und Suspense: Daten-Streaming ohne Wasserfälle

Sechs Karten auf einem Dashboard, sechs Spinner, und sie erscheinen nicht zusammen – sie erscheinen eine nach der anderen, wie Dominosteine, weil jede erst anfing, Daten zu laden, nachdem die darüberliegende fertig war. Das ist ein Wasserfall, und die Gesamtwartezeit ist nicht die langsamste Anfrage, sondern die Summe aller. use() und Suspense unterbrechen die Kette – aber das Interessanteste ist die Maschinerie darunter: Was ein suspendiertes Komponente tatsächlich wirft, und wie HTML, das nicht in der richtigen Reihenfolge ankommt, trotzdem an der richtigen Stelle landet.

Scroll-Animationen: animation-timeline statt IntersectionObserver

Es gibt einen Grund, warum JavaScript-Parallax immer leicht falsch aussieht – ein bisschen losgelöst, als würden die Ebenen einen halben Frame hinter der Seite schwimmen. Es ist kein nachlässiger Code. Es liegt daran, dass Scroll-Ereignisse JavaScript erst erreichen, nachdem der Browser das Scrollen bereits gerendert hat. Der Browser hat das schon einmal gelöst, als er klebende Header in position: sticky verwandelte. Scroll-driven Animations sind derselbe Schritt, auf alle scroll-gebundenen Effekte gleichzeitig angewendet.

View Transitions in Next.js: Seitenanimationen ohne Animationsbibliothek

Zehn Jahre lang bedeutete das Animieren einer Miniatur zu einem Hero-Bild eine einzige Technik: vor dem Element messen, danach messen, den Unterschied mit einem Transform vortäuschen und abspielen. FLIP. Jede Animationsbibliothek macht das so – und jede zahlt dafür mit JavaScript auf dem Hauptthread im denkbar schlechtesten Moment. Die View Transitions API verlagert diesen Trick in den Browser – und seit React 19.2 und Next.js 16 besteht der gesamte Vertrag aus einem einzigen Prop namens name.

Core Web Vitals: was INP wirklich misst, und wie scheduler.yield() den Hauptthread rettet

Im Artikel über Mikrointeraktionen schrieb ich, dass transform und opacity auf dem Compositor-Thread animiert werden, sodass selbst eine schwere Seite die Button-Animation nicht zum Stocken bringen sollte. Das stimmt weiterhin – mit einer Einschränkung, über die jener Artikel schwieg: Ist der Hauptthread durch eine lange JS-Aufgabe blockiert, bekommt die Animation womöglich nie die Chance zu starten, weil schon der Klick-Handler in der Warteschlange wartet. INP ist die Metrik, die genau diese Lücke misst – und scheduler.yield() ist eines der wenigen Mittel, sie wirklich zu schließen.

content-visibility: Offscreen-Rendering ohne Listen-Virtualisierung

Eine Liste mit tausend Kommentaren rendert langsam, also greifst du zu react-window – und tauschst dafür flüssiges Scrollen gegen Strg+F, den Seitendruck und teilweise die Navigation von Screenreadern ein, weil Elemente außerhalb des sichtbaren Bereichs physisch aufhören, im DOM zu existieren. content-visibility löst dasselbe Problem anders: Die Elemente bleiben im DOM, der Browser überspringt für sie nur die teure Layout- und Malarbeit, solange sie nicht in der Nähe des sichtbaren Bereichs sind – und kann sie, überraschenderweise, vorübergehend wieder sichtbar machen, wenn du in ihnen nach Text suchst.

Popover API und natives <dialog>: Schluss mit von Hand gebauten Modals

Im Artikel über Barrierefreiheit war ein Modal mit display:none, das trotzdem noch im Accessibility-Baum existierte, ein Beispiel für einen Fehler, der beim Bau eines Modals von Grund auf mit Divs entsteht. Die eigentliche Frage lautet: Warum musste man es überhaupt von Grund auf bauen? Ich schaue mir an, was das native <dialog> und das popover-Attribut kostenlos mitbringen – Top Layer, Fokusfalle, Light Dismiss – und wo sich diese beiden Mechanismen so sehr unterscheiden, dass eine Verwechslung schnell zu einer unzugänglichen Oberfläche führt.