🔧 Programmierung 🕛 vor 2 Monaten 5 Min Lesezeit
0

Browser Scroll Restoration Is Broken on SPAs. Here's How a Chrome Extension Fixes It.

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

Chrome has had scroll restoration support since 2015. You can even control it: history.scrollRestoration = 'manual'. But if you've ever tried to reliably restore a user's position on a React or Next.js app, you know it doesn't work the way you'd expect.



Here's what breaks, why it breaks, and how a browser extension can sidestep the entire problem.









What the Browser Actually Does



The default behavior is history.scrollRestoration = 'auto'. When you navigate back to a page, the browser tries to scroll to where you were.



This works fine for static pages. It falls apart for:





  • SPAs where content is injected into the DOM after navigation


  • Infinite scroll pages where the content at a given Y position changes depending on what was previously loaded


  • Lazy-loaded images that push content down after the scroll restore fires



The fundamental problem: the browser fires scroll restoration when the page HTML is parsed, not when the page content is fully rendered. A React app that loads a skeleton → fetches data → renders actual content will restore scroll into a partially-rendered DOM.






The history.scrollRestoration = 'manual' Trap



If you set manual, you own scroll restoration completely. Most Next.js apps do this. The typical approach:




CODE
// Save position before navigation
router.beforeEach((to, from) => {
savedPositions[from.path] = window.scrollY;
});

// Restore after navigation
router.afterEach((to) => {
const position = savedPositions[to.path];
if (position !== undefined) {
nextTick(() => window.scrollTo(0, position));
}
});






The nextTick is the problem. It fires after the Vue/React render cycle, but before async data fetching completes. The page renders empty containers, scroll restores to Y=800, then data loads and pushes everything down. User ends up at Y=800 in a now-different page position.



The correct fix is to wait until the content that was at Y=800 actually exists. There's no clean hook for this — you'd need to observe the DOM until the expected content is present.






How Extensions Can Solve What the Framework Can't



A Chrome extension operates outside the app's JavaScript context. It has access to:





  • window.scrollY at any point


  • MutationObserver to detect when DOM content stabilizes


  • chrome.storage.local to persist positions across sessions without touching the app's state



The approach is the extension I built for this. Free for up to 5 saved positions, unlimited with Pro.



What approach are you using for scroll restoration on your SPAs? The MutationObserver quiescence pattern has some obvious failure cases (sites that continuously mutate the DOM for animation) — curious what others have run into.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
CVE-2026-9176 | IBM WebSphere Application Server 8.5/9.0 improper authentication (WID-SEC-2026-3255)
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Browser Scroll Restoration Is Broken on SPAs. Here's How a Chrome Extension Fixes It.

Thematisch verwandte Begriffe: Browser, Scroll, Restoration, Broken · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...