Prevent JavaScript Memory Leaks with URL.revokeObjectURL
In modern web applications, handling binary data like images, PDFs,
and video streams directly in the browser is common. The
URL.createObjectURL() method allows developers to create
temporary URLs referencing Blob or File
objects stored in browser memory. However, because the browser retains
strong internal references to these objects for the lifetime of the
document, failing to release them leads to significant memory leaks.
Calling URL.revokeObjectURL() explicitly releases these
references, allowing the JavaScript garbage collector to reclaim unused
memory and maintain optimal application performance.
How Object URLs Work
When you invoke URL.createObjectURL(blob), the browser
creates a unique blob: URL that acts as an internal pointer
to the underlying binary data. This allows you to treat local binary
objects like standard URL resources in elements such as
<img>, <video>, or
<a> download links without uploading them to a server
first.
const blob = new Blob([largeDataArray], { type: 'application/octet-stream' });
const blobUrl = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = blobUrl;
link.download = 'file.bin';
link.click();The Cause of the Memory Leak
JavaScript relies on automatic garbage collection (GC) to free memory that is no longer reachable. However, object URLs create an exception to standard scope-based GC rules:
- Persistent Internal Mapping: The browser maintains
an internal mapping from the generated
blob:URL string to the in-memoryBlobobject. - Document-Bound Lifetime: This internal reference
remains alive until the current document is completely unloaded, even if
your application’s JavaScript variables referencing the
Blobgo out of scope. - Single Page Application (SPA) Vulnerability: In traditional multi-page websites, navigation unloads the document and clears the memory. In SPAs, the document remains open indefinitely, meaning every unrevoked object URL continues to consume RAM across user sessions.
If a user generates previews for high-resolution images or downloads multiple files over time, unrevoked object URLs will continuously consume RAM, eventually leading to UI lag, tab crashes, or performance degradation on memory-constrained mobile devices.
The Role of URL.revokeObjectURL
URL.revokeObjectURL() informs the browser that the
internal URL mapping is no longer needed. Once revoked, the browser
removes the association, allowing the garbage collector to safely free
the memory allocated to the Blob (provided no other active
JavaScript references exist).
URL.revokeObjectURL(blobUrl);Once revoked, attempting to load or fetch the blob: URL
will result in a 404 (Not Found) error.
Best Practices for Revoking Object URLs
To prevent leaks without breaking media rendering or file operations, apply revocation at the right time in your application lifecycle:
1. Immediately After Image or Media Loads
When generating URLs for media elements, revoke the URL as soon as the element finishes loading:
const img = document.createElement('img');
const objectUrl = URL.createObjectURL(imageBlob);
img.onload = () => {
URL.revokeObjectURL(objectUrl);
};
img.src = objectUrl;
document.body.appendChild(img);2. Immediately After Triggering Downloads
When generating dynamic files for download, revoke the URL immediately after triggering the synthetic click event:
function downloadData(data, filename) {
const blob = new Blob([data], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
}3. During Component Unmount (SPA Frameworks)
In modern frameworks like React, Vue, or Angular, ensure object URLs are revoked in lifecycle cleanup hooks:
useEffect(() => {
const url = URL.createObjectURL(file);
setPreviewUrl(url);
return () => {
URL.revokeObjectURL(url);
};
}, [file]);Summary
URL.revokeObjectURL provides essential manual memory
management within JavaScript’s garbage-collected environment. By
promptly revoking every created object URL, you prevent silent memory
accumulation and ensure your web applications remain fast, stable, and
responsive.