Skip to content

Handling beforeunload / pending state when moving to FROZEN & DISCARDED #5

Open
@spanicker

Description

@spanicker

Filling in some context from companion email thread:
There are 2 types of usecases here for handling of pending state during FROZEN / STOPPED (note recent rename here):

  1. The background page hasn't finished some action eg. in the midst of persisting user state
    onfreeze alone works fine for this case, there is no need for beforeunload. the app should finish persisting the state in onfreeze, we plan to support waitUntil to make this reliable.

  2. The background page has pending user state: eg. unsaved edits in a photo editor
    The app cannot really persist this state as "user state", because the user has not committed the changes, they are pending edits - that the user would have to decide whether to commit or throw away.

Options for addressing case 2:
a. If the page has a beforeunload handler present then do NOT move it to FROZEN and consequently DISCARDED. This is what bfcache does today. The downside is that very large number of pages have the handler 80+% -- so this opts out bulk of pages from ever going to FROZEN or DISCARDED.

b. Regardless of beforeunload handler move the page to FROZEN.
Later if the page is being considered for DISCARDED then run beforeunload at that time. If beforeunload returns string (i.e. has pending state) then do NOT move the tab to DISCARDED.
This would be effective -- only 0.03% of beforeunload calls actually return string - indicating pending state. The downside is that the page would need to be woken up to run beforeunload.

c. [@ojanvafai's suggestion] When moving the page to FROZEN - proactively run beforeunload and note if it returns string i.e. has pending state. Then move the page to FROZEN.
Later if the page is being considered for DISCARDED then use this info to decide: if there is pending state then don't discard and remain in FROZEN.
This addresses the downside of b. -- no need to wake up the page after it is in FROZEN, and it can be directly DISCARDED.
The issue here is that running beforeunload at this point could cause some compat issues and will potentially mess up analytics. Running beforeunload before onfreeze could be surprising for web developers.

We should probably try out Option c. and if that doesn't work then fallback to Option b.
\cc @smaug---- @ojanvafai @philipwalton @fmeawad

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions