Scroll restoration listeners are never removed, so every created router stays in memory
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 42/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Stack tecnologico
- typescript
- Ambito
- frontend
Direzione di ricerca
Start with packages/router-core/src/scroll-restoration.ts and the RouterCore constructor, where setup is called; trace the listeners and router subscriptions that need cleanup. Then inspect existing router lifecycle tests and add coverage for repeated dispose() calls and multiple routers sharing scroll restoration. Done means disposing a router removes its listeners and subscriptions without changing history.scrollRestoration while another router still uses it.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Which project does this relate to?
Router
Describe the bug
When scrollRestoration is on, setupScrollRestoration (packages/router-core/src/scroll-restoration.ts) runs once per router, from the RouterCore constructor. It adds three global listeners:
document.addEventListener('scroll', …, true)addEventListener('pagehide', …)addEventListener('pageshow', …)
It keeps no reference to them, and the router has no method to remove them. Each listener closes over the router, so the router (its stores, matches, and the elements in trackedScrollTargets) cannot be garbage collected.
With one router for the life of the page this is fine. It is a leak when an app creates routers more than once, for example:
- an app that renders some views in their own router instance and creates one per view (our case: each page in a stack of sliding panels has its own router, so the page under a panel stays mounted)
- micro-frontends that mount and unmount a router
- tests and HMR that create a new router each time
In our app, after opening and closing 20 panels, getEventListeners(document).scroll.length goes from 1 to 21. Each pagehide listener also writes the scroll cache to sessionStorage, so N routers write it N times on unload.
Steps to reproduce
import { createMemoryHistory, createRootRoute, createRouter } from '@tanstack/react-router'
for (let i = 0; i < 20; i++) {
createRouter({
routeTree: createRootRoute(),
history: createMemoryHistory(),
scrollRestoration: true,
})
}
// Chrome DevTools console:
getEventListeners(document).scroll.length // 20
getEventListeners(window).pagehide.length // 20
Expected behavior
There is a way to release a router that is no longer used: its global listeners are removed and it can be garbage collected.
Proposed fix
setupScrollRestorationkeeps the listeners (and the router subscriptions it adds), and returns a cleanup function.RouterCorestores that cleanup and exposes it as a public method, for examplerouter.dispose(). It is idempotent and does not touchhistory.scrollRestorationif another router still uses scroll restoration.RouterProviderdoes not call it automatically, because the app creates the router outside React and may render it again.
I can open a PR with this and tests. Is dispose() an acceptable name and shape, or do you prefer something else (for example destroy(), or a cleanup returned from router.mount())?
Your environment
@tanstack/react-router1.170.41 (also present onmain, seescroll-restoration.ts)- Chrome 155, macOS
Related: #8024 (bare addEventListener for pagehide), #7956 (history.scrollRestoration mode).
- Lingua principale
- TypeScript
- Stelle
- 15.2k
- Fork
- 1.9k
- Merge medio
- 1g 13h
- PR unite (30g)
- 76
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di TanStack/router
-
router.startViewTransition leaves the ready/finished promises unhandled, so a skipped transition throws an unhandled AbortErrorForse già presa @unjica l’ha presa 3 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
TanStack/router#8776 · 3 commenti · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
Router devtools crash when search params contain a BigInt (JSON.stringify in history tracking)Forse già presa @A-Raphie l’ha presa 7 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 1 giorno
-
docs: `createLink` has no API reference page; 3 how-to guides link to a missing `#createlink` anchorForse già presa @A-Raphie l’ha presa 7 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
I maintainer di solito rispondono entro 1 giorno
-
Inline scripts are duplicated after hydration when the CSP nonce is sent in a headerForse già presa @gabriel-le l’ha presa 27 giorni fa. Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
I maintainer di solito rispondono entro 1 giorno
-
start-plugin-core: sitemap lastmod and pages.json lastBuilt are stamped with the build's wall clock (no SOURCE_DATE_EPOCH support)Forse già presa @treadnot l’ha presa 29 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di TanStack/router
Issue simili
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
outline/outline#14348 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
bug needs-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
I maintainer di solito rispondono entro 1 giorno
-
[Bug]: Agent import retains quotes in .env API keys followed by inline commentsForse già presa @yxr-2025 l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
elie222/rakazo#2322 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
awslabs/visual-asset-management-system#804 ·
I maintainer di solito rispondono entro 1 giorno
-
用户目录有单引号时,热加载时YAML解析崩溃Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
dsh-market/dsh-market#1027 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno