Skip to content

Disconnect circuit on beforeunload event #23224

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

Merged
merged 1 commit into from
Jun 24, 2020

Conversation

captainsafia
Copy link
Member

Closes #19050.

In the issue above, the user originally reported that they would see our reconnect modal when navigating away from Firefox. They pointed at inconsistent behavior through browser versions. They'll always see the reconnect modal on Firefox but only on a few version of Chrome.

While debugging this, I realized that this is because our clean-up handler that is registered to the unload event is never invoked in Chrome.

The unload event is not emitted and, consequently, the async request sent to /disconnect via navigator.sendBeaconis never emitted.

It turns out that Chrome is discouraging developers from using the unload event in favor of its new page navigation APIs (ref). Chrome made some changes to the unload and beforeunload APIs around Chrome 80, I suspect that this is when the regression happened.

I tried triggered the clean-up on a few other events (like pagehide and visibilitychange) but ultimately settled on beforeunload because:

  • It works on the widest set of browsers (validated on Chrome, Firefox, Safari, Edge)
  • The pagehide event isn't triggered all the time in some browsers depending on when the subsequent page is loaded
  • This visibilitychange is triggered for too many scenarios

@ghost ghost added the area-blazor Includes: Blazor, Razor Components label Jun 22, 2020
@captainsafia captainsafia force-pushed the safia/bug/ff-navigate branch from 059f0e3 to c6d4a2b Compare June 22, 2020 17:44
@captainsafia captainsafia requested a review from a team June 22, 2020 17:45
@javiercn
Copy link
Member

@captainsafia can onbeforeunload be cancelled?

Copy link
Member

@javiercn javiercn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

I assume you've done due diligence on testing it on various situations, so signing-off.

@pranavkm pranavkm added this to the 5.0.0-preview7 milestone Jun 22, 2020
@captainsafia
Copy link
Member Author

@captainsafia can onbeforeunload be cancelled?

Yes, if the user accepts the "Do you want to navigate away from this page?" prompt that the browser provides.

Copy link
Member

@SteveSandersonMS SteveSandersonMS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! Glad there was such a clean fix here!

Assuming there are no known drawbacks, this seems like a very strong patch candidate.

@captainsafia captainsafia force-pushed the safia/bug/ff-navigate branch 2 times, most recently from ecbc0fe to 6efa8b8 Compare June 24, 2020 05:56
@captainsafia captainsafia force-pushed the safia/bug/ff-navigate branch from 6efa8b8 to cc5d295 Compare June 24, 2020 05:58
@captainsafia captainsafia changed the base branch from master to release/5.0-preview7 June 24, 2020 07:00
@captainsafia
Copy link
Member Author

Made some modifications after testing a few more scenarios. Re-requesting reviews for this.

We register the same event handler on both the beforeunload and unload events. We track whether the /disconnect request has been successfully queued in the beforeunload. If not, we empty to send it again in the unload. We execute each event listener at most once.

@javiercn
Copy link
Member

Made some modifications after testing a few more scenarios. Re-requesting reviews for this.

We register the same event handler on both the beforeunload and unload events. We track whether the /disconnect request has been successfully queued in the beforeunload. If not, we empty to send it again in the unload. We execute each event listener at most once.

What motivated this change? It would be good to keep a record for the future

Copy link
Member

@javiercn javiercn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, interested in knowing the reason for subscribing to both events

@captainsafia
Copy link
Member Author

LGTM, interested in knowing the reason for subscribing to both events

Chrome won't fire the event if the user hasn't interact with the page. This ends up happening in our CI tests because we call Browser.Close() without interacting with the page.

Firefox allows users to set a disable_beforeunload flag to disable those navigate away alerts. However, that disables beforeunload events and immediately emits the unload event.

@captainsafia
Copy link
Member Author

@mkArtakMSFT Can you merge this?

@mkArtakMSFT mkArtakMSFT merged commit 4465a8e into release/5.0-preview7 Jun 24, 2020
@mkArtakMSFT mkArtakMSFT deleted the safia/bug/ff-navigate branch June 24, 2020 18:35
wtgodbe pushed a commit that referenced this pull request Aug 13, 2020
* Disconnect circuit on `beforeunload` event (#23224)

* Add delay before showing Reconnection UI (#24137)

* Add CSS delay before showing Reconnection UI

* rebuild yet again to try and get past the conflict

* Move reconnection delay mechanism into framework code (#24566)

Co-authored-by: SQL-MisterMagoo <[email protected]>
Co-authored-by: Steve Sanderson <[email protected]>
@alexclarkmusa
Copy link

Just curious but... what sort of QA/unit-testing does a patch like this go through before it's unleashed on the public as a release? This appears to have caused a fairly significant/fundamental issue with the NavigationManager opening links and it seems like this should have shown up in some simple tests. I'm trying to make a case for Blazor at work and things like this really scare the business away from it.

Can there be a bit more diligence before things like this get pushed to the production release please?

@pranavkm
Copy link
Contributor

@alexclarkmusa thank you for your feedback. Patches have a high bar for compatibility and go through a validation process before being released. We had tests that covered normal page navigations, but unfortunately we had a blind spot in our test \ scenario coverage for this particular use case. We will be reverting the patch shortly and we are filling the test hole. We are committed to making sure you're able to confidently pick up new patch releases without the risk of regression and we will be much more cautious making changes of this kind going forward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor Includes: Blazor, Razor Components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Circuit not disconnected properly on all browsers when navigating away from page
6 participants