Memory leaks when navigating between documents -- blob URLs never revoked #202
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
The frontend creates blob URLs via
URL.createObjectURL()to display document file previews (PDFs, images). These blob URLs are never cleaned up withURL.revokeObjectURL().Affected files:
frontend/src/routes/documents/[id]/+page.svelte(line 40)frontend/src/routes/enrich/[id]/+page.svelte(line 42)A grep for
revokeObjectURLacross the entirefrontend/src/directory returns zero results.Impact
Each navigation to a document page creates a new blob URL that holds the entire file contents in memory. For a typical PDF (1-5 MB), navigating through 20 documents leaks 20-100 MB of browser memory that is never freed until the tab is closed.
The enrich workflow is especially affected since users navigate through documents sequentially, accumulating blob URLs with every page visit.
Root Cause
Both
loadFile()functions callURL.createObjectURL(blob)and assign the result tofileUrl, but:$effectre-fires (e.g. navigating to a different document), the old blob URL is overwritten without being revoked.Proposed Fix
Add cleanup in two places:
loadFile()-- revoke the previous URL before creating a new one:onDestroyor$effectcleanup:Both files need the same fix.
Already fixed as part of the
createFileLoaderhook refactor.What's in place:
frontend/src/lib/hooks/useFileLoader.svelte.ts— the hook revokes the previous blob URL before creating a new one (on everyloadFile()call) and exposes adestroy()method that revokes the current URL on component teardown.documents/[id]/+page.svelte— callsonDestroy(() => fileLoader.destroy())DocumentEditLayout.svelte(covers/documents/[id]/editand/documents/new) — same patternenrich/[id]/+page.svelte— no longer uses file loading directly; the concern from the original report is goneFull test coverage in
src/lib/hooks/__tests__/useFileLoader.svelte.test.ts(5 tests, all green):No
createObjectURLcalls remain outside the hook.