--- title: "Blog" description: "Read about the background of our monitoring solution, new features and case studies" canonical: "https://www.rumvision.com/blog/time-to-unload-your-unload-events/" --- Breadcrumbs: [Home](https://www.rumvision.com/?format=md) > Blog # Time to unload your unload events If you're still depending on unload events in your code, you need to act NOW. Chrome is starting to kill these handlers this month, potentially breaking your website's analytics and data-saving features. These events were never reliable on mobile, Safari already ignores them, and soon desktop Chrome will too. Here's why moving to better alternatives won't just save your code—it'll actually improve your site's performance. As a full-stack developer who's been in the trenches for over two decades (I'm old people!), I've seen browser APIs come and go. Today, I want to talk about an old friend that's on its way out: the `unload` event. If you've been hanging onto this event in your codebase, it's time we had a chat about why you should say goodbye to the `unload` event ([in case you didn't do so already](https://developer.chrome.com/docs/web-platform/page-lifecycle-api#legacy_lifecycle_apis_to_avoid)). ## What's happening with the unload event? Google Chrome is gradually phasing out the `unload` event starting this month (March 2025). The rollout begins with just google.com, then expands to more top sites, and eventually reaches all websites by April 2026. This isn't a sudden change - Chrome has been telegraphing this move since 2019 when they announced their back/forward cache implementation plans. ## Why I won't miss the unload event Let's be honest - the `unload` event has been more trouble than it's worth for years now. Here's why I'm happy to see it go: ### It was never reliable to begin with We've all been there. You add an `unload` handler to save some critical user data, only to discover later that it didn't fire half the time on mobile devices. The reason? Mobile browsers often don't trigger `unload` when tabs are backgrounded and killed by the OS. What seemed like a safety net was actually full of holes. ### It kills performance optimizations The back/forward cache (bfcache) is one of the best performance improvements browsers have implemented in recent years. It creates an instant back/forward navigation experience by freezing a page in memory. The problem? Pages with `unload` handlers can't use this cache, forcing users to wait for a full page reload when navigating. ### Modern browsing patterns have changed Think about how you use browsers today compared to 15 years ago. We have dozens of tabs open across multiple windows. We leave tabs dormant for days. We switch devices mid-session. The idea that there's a clean "unload" moment when a user leaves your page is a relic of a simpler web. ## The deprecation schedule Chrome is [taking it slow](https://developer.chrome.com/docs/web-platform/deprecating-unload#deprecation_timeline), which gives us time to adapt: - **March 2025**: Just google.com loses `unload` support (Chrome 135) - **April-June 2025**: Expanding to 50 top websites (Chrome 136-138) - **August 2025-April 2026**: Gradual rollout to all sites (Chrome 140-147) ## Better ways to handle page exits So what should you use instead? Here are three better options I've adopted in my own projects: ### The visibilitychange event The `visibilitychange` event (part of **[Page Visibility API](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API)**) is my go-to replacement. It fires when a user switches tabs or minimizes the browser - often the last reliable chance to save data: ``` document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'hidden') { // Last chance to save data - the user is navigating away saveUserProgress(); // Don't count on getting more execution time after this } }); ``` ### The pagehide event Similar to `unload` but compatible with the back/forward cache, the `pagehide` event (part of **PageTransitionEvent**) can be used: ``` window.addEventListener('pagehide', (event) => { // Clean up things that would break if the page gets frozen and restored later // event.persisted tells you if the page might be restored from bfcache later if (event.persisted) { console.log('This page *might* be entering the bfcache.'); } else { console.log('This page will unload normally and be discarded.'); } }); ``` This code can be found in the [bfcache article on web.dev](https://web.dev/articles/bfcache#observe-page-enters). ### Selective use of beforeunload The `beforeunload` event (which shows a [browser native](https://developer.mozilla.org/en-US/docs/Web/API/BeforeUnloadEvent/returnValue) "Leave site?" dialog) isn't being deprecated, but you should still use it sparingly as [`beforeunload` is still unreliable](http://web.dev/articles/bfcache#beforeunload-caution). That's because the `beforeunload `event might [never be fired in some scenarios](https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event#usage_notes). and suggests to avoid using it unless absolutely necessary. ``` function updateLeaveWarning(hasUnsavedChanges) { // Only add the warning when there are unsaved changes if (hasUnsavedChanges) { window.addEventListener('beforeunload', showWarning); } else { window.removeEventListener('beforeunload', showWarning); } } function showWarning(e) { // Browsers standardize the dialog message regardless of what text we provide e.preventDefault(); return e.returnValue = 'Are you sure you want to exit?'; } // Add listeners to track changes formElement.addEventListener('change', () => { updateLeaveWarning(true); }); saveButton.addEventListener('click', () => { updateLeaveWarning(false); }); ``` ### fetchLater API Another promising alternative, particularly for analytics and monitoring use cases, is the [fetchLater API](https://developer.chrome.com/blog/fetch-later-api-origin-trial). Coming out of [origin trial](https://www.rumvision.com/blog/a-step-in-to-the-future-of-the-web-what-are-origin-trials/?format=md) phase, this (Chromium >= 135) API directly addresses one of the most common `unload` event use cases. Back in the days, performance monitoring solutions like New Relic and Dynatrace ended up using the `unload` event as a means to dispatch analytics data by sending a beacon when `unload` was fired. This approach created a difficult trade-off: despite being performance monitoring solutions, they were either actively impacting site performance (by blocking the back/forward cache) or having their data collection silently fail when `unload` events didn't fire. The fetchLater API solves this by allowing developers to queue network requests that will be sent even after a page is closed: ``` // Queue an analytics request that will be sent even if the page is closed navigator.fetchLater.fetch('https://analytics.example.com/collect', { body: JSON.stringify({event: 'page_exit', duration: pageSessionTime}), method: 'POST', keepalive: true }); ``` Unlike the unload event, the fetchLater API approach allows the browser to optimize page transitions while still ensuring your analytics data gets sent reliably. ## Finding unload usage in your codebase Before you can fix the problem, you need to find it. Here's how I hunt down `unload` usage: ### Look for direct event handlers Search your codebase for: - `addEventListener('unload'` - `onunload` - `.unload(` (for jQuery) ### Check for back/forward cache eligibility Open Chrome DevTools, navigate to Application > Background services > Back/forward cache, and click "Test back/forward cache". If your page fails the test due to an `unload` handler, Chrome will tell you. ### Disabling and reporting As a site owner, you can choose to disable the use of the `unload` event altogether. This will keep your site eligible for the back/forward cache, even if existing or newly added (third-party) scripts start to use the `unload` handler again. Alternatively, you can already start detecting which scripts are still actively using the `unload` handler. This can be achieved by using the Reporting API and sending data to an endpoint of your choice. [This GitHub explainer document](http://github.com/fergald/docs/blob/master/explainers/permissions-policy-deprecate-unload.md#testing-with-chrome) covers both scenarios. ## Options while you migrate If you need more time, Chrome offers several ways to postpone the inevitable: ### For developers testing locally Enable the Chrome flag at `chrome://flags/#deprecate-unload` to simulate the future behavior now and test your fixes. ### For website owners Use the Permissions Policy header to explicitly opt-in to keep using `unload` during the transition: ``` Permissions-Policy: unload=self ``` ### For enterprise IT If you manage a corporate environment with legacy applications, look into the `ForcePermissionPolicyUnloadDefaultEnabled` enterprise policy to delay the deprecation. ## Let's face reality The deprecation of `unload` is actually a helpful reminder that we never had as much control over the web page lifecycle as we thought. Users have always been able to kill our pages without warning - by force-quitting browsers, running out of battery, or losing network connections. Good web development means designing for resilience. Save data early and often. Use client-side storage wisely. Sync to servers when connections are available. These practices have always been better than relying on an `unload` event that might never come. So while it might be annoying to update your code now, it's pushing us toward more reliable patterns that better match how people actually use the web today. That's something we can all get behind, right?