Skip to content

Transactions freeze on page navigation in Safari #180

@zubiden

Description

@zubiden

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 get takes more than a few seconds to resolve (hopefully you don't have anything important in there 😉)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions