Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Reset streams on BFCache events (#24950)
## **Description** Previously, Chrome's BFCache (Back Forward) strategy was to evict a page from cache if it received a message over any connected port streams. The port stream would remain open and the background script would NOT receive an onDisconnect. As long as the cached page did not receive a message, the port would still function when the page became active again. This was problematic because MetaMask was likely to send a message to the still connected cached page at some point due to the nature of notifications, which would evict the page from cache, neutralizing the performance benefit of the BFCache for the end user. Now, Chrome's BFCache strategy is to trigger an onDisconnect for the background script, but NOT the cached page. The port stream is invalid despite not being closed on the cached page side. This is problematic because we do not listen for events relevant to when a BFCached page becomes active and thus do not reset the invalid stream. To address both strategies, we now listen for the `pageshow` and `pagehide` events. When a page is entering a BFCached state, we preemptively end the port stream connection (even if the user is on an older version of chrome that would have kept it alive). When a BFCached page is restored to an active state, we establish a port stream connection. We know the port stream must be restored/reset because we were the ones responsible for preemptively ending it earlier in the lifecycle. Combining these two changes allows us to handle both the old and new BFCache strategies without having to target them by versions separately. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/24950?quickstart=1) ## **Related issues** See: https://developer.chrome.com/blog/bfcache-extension-messaging-changes?hl=en See: #13373 See: https://web.dev/articles/bfcache (useful links at bottom) See: w3c/webextensions#474 Fixes: MetaMask/MetaMask-planning#2582 ## **Manual testing steps** Steps are for macOS. Using chrome 123 or newer **Testing with old BFCache strategy** 1. Close the entire chrome app 1. run `open /Applications/Google\ Chrome.app --args --disable-features=DisconnectExtensionMessagePortWhenPageEntersBFCache` 1. Visit `http://www.brainjar.com/java/host/test.html` 1. Open console 1. Enter `await window.ethereum.request({method: 'eth_chainId'})`, which should be responsive 1. Visit `chrome://terms/` 1. Use the back button to go back to the brainjar test page 1. Enter `await window.ethereum.request({method: 'eth_chainId'})`, which should be responsive **Testing with the new BFCache strategy** Repeat the steps above, but use `--enable-features` instead of `disable` MetaMask Behavior should look the same regardless of browser's BFCache strategy ## **Screenshots/Recordings** BFCache Behavior https://github.com/MetaMask/metamask-extension/assets/918701/efeb1591-5fde-44c8-b0a3-3573dfb97806 Prerender Behavior (to show affected chromium browsers still reset streams correctly) https://github.com/MetaMask/metamask-extension/assets/918701/7461bf64-b5b0-4e70-96d5-416cf5bf6b7c ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Coding Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.
- Loading branch information