-
Notifications
You must be signed in to change notification settings - Fork 149
Description
Some of my users reported that, when changing accounts, Safari showed them a blank page. After some digging, it turns out that performing an app state save right before navigating to a new page can lock up transactions on that page.
The Problem
My app tries to save its state on the 'beforeunload' event. This works fine in Chrome and Firefox, but can cause IndexedDB to freeze in Safari when performing same origin navigation.
I've created a simple reproduction of the bug at https://zubiden.dev/demo/idbbug.html. In order to reproduce the bug, DevTools must first be closed. After the database has frozen, they can be opened again.
In case you are reading this in the distant future and the page is no longer available, here's a short gist:
window.addEventListener('beforeunload', () => {
const largeValue = ...; // I've used 15MB string to simulate the real world use
set('myState', largeValue);
});It can be unreliable on iOS Safari, so I've added an additional click handler to a link.
Sometimes the 'get' transaction is resolved, but the 'set' transaction is stuck. This is arguably even worse, as most apps do not handle such cases, which can lead to data loss.
Potential Workarounds
- Avoid large write transactions on page unload or right before the same origin navigation
- Destroy the database in case if
gettakes more than a few seconds to resolve (hopefully you don't have anything important in there 😉)