Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discussion: What should be the correct behavior on hibernating browser tabs? #6810

Open
pubkey opened this issue Feb 1, 2025 · 3 comments
Open

Comments

@pubkey
Copy link
Owner

pubkey commented Feb 1, 2025

Context

Browser can "hibernate" browser tabs when they are not active. This ensures these tabs do not use any memory or CPU, the JavaScript process on these hibernated tabs is then stopped.

RxDB uses a leader-election for replication so that when many tabs are open, only one tab runs the replication. This saves a lot CPU power and bandwith.

People often reported that they had problems when the elected leader-tab became hibernated by the browser. This seemingly stopped the replication and caused problems.

To prevent this, RxDB added a hack to prevent tab hibernation if at least one replication is running: c2c7ea4
But this hack is not good as it stops the device from power saving when the tab is not in use.

Goal

I will remove this hack in the next release. From my testings, the default behavior of RxDB with hibernating tabs is correct: The hibernated tab dies and a new leader is elected. You can test this behavior with the broadcast channel test-page where the leading tab has a crown-icon in the title. You can manually send tabs to hibernation in chrome at chrome://discards/.

Question

Do you have any way to reproduce a case where the default behavior causes problem?
What do you think the default behavior of RxDB should be?

Related discussions:

@andreuka
Copy link

andreuka commented Feb 1, 2025

This issue is especially affects mobile devices.

I think need the mechanism to switch leader tab to latest active tab, since the latest active tab will have most longer lifecycle until its suspended and after user get backs to website, the new opened tab becomes leader again and this will make it not noticeable for end user and fix the issue.

@pubkey
Copy link
Owner Author

pubkey commented Feb 1, 2025

@andreuka But on mobile, if a tab is hibernated, doesnt it also elect a new tab as leader? Because in my testings it does.

@andreuka
Copy link

andreuka commented Feb 1, 2025

@andreuka But on mobile, if a tab is hibernated, doesnt it also elect a new tab as leader? Because in my testings it does.

I mostly testing at iOS and from my experience its not hibernating its immediately, its firstly put it in kind of slow mode and I had alot of complains from users that the application does not works well at mobile devices.

I do not using replication, but I had noticed that by my custom WebSocket connection which opened in both tabs and pushs same events to all tabs, but if only leader tab writes data to database and when tabs are switched, the leader was not changed, so I made a hack, that on mobile every tab with active WebSocket connection writing the data to the database and that works enough well, since only 1 tab will work fast.

That is my function to determine if tab should write data to database or not:

const elector = createLeaderElection(channel);

export async function isLeader(){
    if( isIOS() ){
        return true;
    }

    if( elector && ! await elector.hasLeader() ) return true;
    if( elector && await elector.hasLeader() && elector.isLeader ) return true;

    return false;
}

but thats not perfect solution as you can see and I hope that can be done other way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants