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

fix: Reset streams on BFCache events #24950

Merged
merged 31 commits into from
Nov 22, 2024
Merged

Conversation

jiexi
Copy link
Contributor

@jiexi jiexi commented May 31, 2024

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

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: https://github.com/MetaMask/MetaMask-planning/issues/2582

Manual testing steps

Steps are for macOS. Using chrome 123 or newer

Testing with old BFCache strategy

  1. Close the entire chrome app
  2. run open /Applications/Google\ Chrome.app --args --disable-features=DisconnectExtensionMessagePortWhenPageEntersBFCache
  3. Visit http://www.brainjar.com/java/host/test.html
  4. Open console
  5. Enter await window.ethereum.request({method: 'eth_chainId'}), which should be responsive
  6. Visit chrome://terms/
  7. Use the back button to go back to the brainjar test page
  8. 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

bfcache.new.behavior.mov

Prerender Behavior (to show affected chromium browsers still reset streams correctly)

targeted.prerender.still.working.correctly.mov

Pre-merge author checklist

  • I’ve followed MetaMask Coding Standards.
  • I've completed the PR template to the best of my ability
  • I’ve included tests if applicable
  • I’ve documented my code using JSDoc format if applicable
  • I’ve applied the right labels on the PR (see labeling guidelines). 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.

Copy link
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@jiexi jiexi changed the title Reset streams on BFCache events fix: Reset streams on BFCache events May 31, 2024
@jiexi jiexi marked this pull request as ready for review May 31, 2024 18:50
@jiexi jiexi requested a review from a team as a code owner May 31, 2024 18:50
Copy link

codecov bot commented Jun 3, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 65.65%. Comparing base (d8e0cd1) to head (7ae24c3).
Report is 15 commits behind head on develop.

Current head 7ae24c3 differs from pull request most recent head 9856738

Please upload reports for the commit 9856738 to get more accurate results.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop   #24950      +/-   ##
===========================================
+ Coverage    65.61%   65.65%   +0.04%     
===========================================
  Files         1372     1376       +4     
  Lines        54519    54569      +50     
  Branches     14282    14293      +11     
===========================================
+ Hits         35770    35822      +52     
+ Misses       18749    18747       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@metamaskbot
Copy link
Collaborator

Builds ready [dec9f77]
Page Load Metrics (137 ± 170 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint6911587126
domContentLoaded9201232
load441680137354170
domInteractive9201232

@metamaskbot
Copy link
Collaborator

Builds ready [7ae24c3]
Page Load Metrics (51 ± 5 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint681058594
domContentLoaded9341252
load428051105
domInteractive9341252
Bundle size diffs
  • background: 0 Bytes (0.00%)
  • ui: 0 Bytes (0.00%)
  • common: 0 Bytes (0.00%)

@metamaskbot
Copy link
Collaborator

Builds ready [6592fe6]
Page Load Metrics (1933 ± 66 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint29322811845380183
domContentLoaded17292193189912962
load17382287193313866
domInteractive17178734421
backgroundConnect8150353517
firstReactRender541691112914
getState55710126
initialActions01000
loadScripts12681670141611555
setupStore55713157
uiStartup19422540214815072
Bundle size diffs
  • background: 0 Bytes (0.00%)
  • ui: 0 Bytes (0.00%)
  • common: 0 Bytes (0.00%)

HowardBraham
HowardBraham previously approved these changes Nov 22, 2024
Copy link
Contributor

@HowardBraham HowardBraham left a comment

Choose a reason for hiding this comment

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

LGTM. I also ran the new E2E test on the develop version of the Extension, and it failed as expected.

@metamaskbot
Copy link
Collaborator

Builds ready [2f1000c]
Page Load Metrics (1850 ± 60 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint16642133185912660
domContentLoaded16512110181812560
load16662140185012660
domInteractive18194413718
backgroundConnect9145383215
firstReactRender503031256531
getState593232512
initialActions01000
loadScripts1163146213168541
setupStore55612147
uiStartup18592602211718187
Bundle size diffs
  • background: 0 Bytes (0.00%)
  • ui: 0 Bytes (0.00%)
  • common: 0 Bytes (0.00%)

@metamaskbot
Copy link
Collaborator

Builds ready [e4d55a5]
Page Load Metrics (2086 ± 116 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint32427932011452217
domContentLoaded170527762054237114
load175428012086242116
domInteractive27129492713
backgroundConnect978342010
firstReactRender922921294220
getState474202110
initialActions00000
loadScripts122821341527210101
setupStore660202010
uiStartup195030682346270130
Bundle size diffs
  • background: 0 Bytes (0.00%)
  • ui: 0 Bytes (0.00%)
  • common: 0 Bytes (0.00%)

@jiexi jiexi added this pull request to the merge queue Nov 22, 2024
@jiexi jiexi removed this pull request from the merge queue due to a manual request Nov 22, 2024
@jiexi jiexi enabled auto-merge November 22, 2024 19:52
@jiexi jiexi added this pull request to the merge queue Nov 22, 2024
@metamaskbot
Copy link
Collaborator

Builds ready [149c240]
Page Load Metrics (1907 ± 78 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint17232454190415072
domContentLoaded16632411186615374
load17202507190716378
domInteractive20167453115
backgroundConnect9156433517
firstReactRender493021478038
getState487292914
initialActions01000
loadScripts12141819136512359
setupStore686202512
uiStartup192428102226228110
Bundle size diffs
  • background: 0 Bytes (0.00%)
  • ui: 0 Bytes (0.00%)
  • common: 0 Bytes (0.00%)

Merged via the queue into develop with commit ad9a748 Nov 22, 2024
75 checks passed
@jiexi jiexi deleted the jl/reset-streams-on-bfcache-pageshow branch November 22, 2024 20:31
@github-actions github-actions bot locked and limited conversation to collaborators Nov 22, 2024
@metamaskbot metamaskbot added the release-12.9.0 Issue or pull request that will be included in release 12.9.0 label Nov 22, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
release-12.9.0 Issue or pull request that will be included in release 12.9.0 team-extension-platform team-wallet-api-platform
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants