-
Notifications
You must be signed in to change notification settings - Fork 16
Memory leaks from unrevoked URL.createObjectURL across multiple tools #189
Description
Summary
There are several places in the codebase where URL.createObjectURL() is used without a corresponding URL.revokeObjectURL().
This can retain large Blob / File objects in memory (especially PDFs and images), leading to increasing memory usage during repeated tool usage.
In one flow, a blob URL is also stored in localStorage, which is not appropriate for object URLs and can cause accumulated memory retention.
Affected Areas
1️⃣ Metadata Viewer (High Impact)
File: app/dashboard/metadata-viewer/page.tsx
URL.createObjectURL(file)is used inline for previews.- Object URLs are created during render.
- No cleanup or
revokeObjectURLon file change or component unmount.
Risk:
Repeated re-renders or file changes can accumulate object URLs in memory.
2️⃣ PDF Compress Preview (High Impact)
File: app/dashboard/pdf-compress/page.tsx
- Preview URL is created and stored in state.
- Previous object URLs are never revoked when a new file is selected.
- No cleanup on unmount.
Risk:
Repeated file replacements increase memory usage over time.
3️⃣ Processing Flow (Critical)
File: app/tool/[id]/processing/page.tsx
- Blob URL created via
URL.createObjectURL(blob) - Stored in
localStorage(e.g.,compressedPDF) - Never revoked
Risk:
- Blob URLs are document-lifetime scoped and should not be persisted.
- Repeated compression runs can retain large PDFs in memory until tab close.
- May cause performance degradation or tab crashes in long sessions.
Reproduction Steps
- Run the app (
pnpm dev). - Open Metadata Viewer or PDF Compress tool.
- Upload a large PDF (50MB+).
- Replace file multiple times.
- Observe memory usage increasing in Chrome Task Manager.
- Repeat compression process multiple times.
- Memory does not stabilize due to unrevoked object URLs.
Expected Behavior
- Object URLs should be created only when needed.
- All object URLs should be revoked:
- On file replacement
- On component unmount
- After download is triggered
- Blob URLs should not be stored in
localStorage.
Suggested Fix
- Introduce a shared utility or hook (e.g.,
useObjectUrl) to manage object URL lifecycle safely. - Replace inline
createObjectURLusage with controlled creation insideuseEffect. - Ensure
URL.revokeObjectURL()is called in cleanup. - Remove blob URL persistence in
localStorage.
Instead:
- Trigger download immediately and revoke URL, or
- Store blob data temporarily in React state and clean up on unmount.
Impact
Fixing this will:
- Prevent memory growth during long sessions
- Improve performance and stability for large PDFs
- Reduce risk of browser tab crashes
- Improve architectural consistency across tools
I’m happy to work on a refactor to standardize object URL handling across all PDF tools if this approach is acceptable.