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

perf(cherry-pick): use an interstitial page to load popup.html; load scripts using defered script tags (#26555) #26822

Merged
merged 1 commit into from
Sep 3, 2024

Conversation

davidmurdoch
Copy link
Contributor

@davidmurdoch davidmurdoch commented Aug 30, 2024

This PR removes load-*.js helpers and load scripts using the defer property instead.

This change drastically improves the performance of the extension but greatly reduces perceived performance because the browser won't display the popup until the DOMContentLoaded event.

But improve perceived performance is mostly regained by initially loading an asset-less HTML file, popup-init.html, that then redirects to the slower (but much faster than before this PR) popup.html.

This was initially authored by @Gudahtt, I've just updated and optimized it to work with the both build systems.

One change I did not make was moving scripts to the head. I don't think putting the scripts in the head does anything in our case1 other than potentially require that we wait for DOMContentLoaded before querying for the app container.

Note: In Firefox we continue to use popup.html. Firefox is very slow to render the popup-init.html redirect, and it renders the page only partially anyway, making the UX feel very janky. It also doesn't delay opening the popup until DOMContentLoaded, like Chrome does, so the issue popup-init.html solves doesn't do anything anyway.


Here is side-by-side video comparison of develop vs popup-defer-scripts.

This video displays the elapsed time from clicking the MetaMask Fox to Lock Screen render.

The end of the video is a frame-by-frame comparison of the new "jank" this PR introduces. The develop branch renders the fox immediately, whereas the popup-defer-scripts branch renders an empty page for about 15 milliseconds.

These stats aren't representative of real world performance, but are intended to illustrate relative performance and perceived performance.

Both builds were created by running yarn build dist.

develop-vs-propup-defer-scripts.mp4

  1. build with yarn dist
  2. install into your browser and go through onboarding
  3. open MetaMask
  4. Marvel at how much faster it is

Closes
#25721

Description

Cherry picks the popup loading changes.

Warning

There was a conflict around webpack changes since those aren't included in v12.2.0

Specifically, the build's script and some html files changed in the webpack PR as well as in #26555.

Open in GitHub Codespaces

Related issues

Fixes:

Manual testing steps

  1. Go to this page...

Screenshots/Recordings

Before

After

Pre-merge author checklist

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.

Footnotes

  1. our HTML files are very tiny, and thus will be loaded all in one go, we don't have to worry about packets being lost and retransmitted over the network, delaying the browser's preload scanner.

@davidmurdoch davidmurdoch added team-extension-platform release-12.2.0 Issue or pull request that will be included in release 12.2.0 labels Aug 30, 2024
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.

@davidmurdoch davidmurdoch changed the title perf: use an interstitial page to load popup.html; load scripts using defered script tags (#26555) perf(cherry-pick): use an interstitial page to load popup.html; load scripts using defered script tags (#26555) Aug 30, 2024
@davidmurdoch davidmurdoch force-pushed the v12.2.0-popup-defer-scripts branch 3 times, most recently from 880bc3e to 5c7ada1 Compare August 30, 2024 18:39
Gudahtt added a commit that referenced this pull request Sep 3, 2024
## **Description**

Our CI was setup to compare each branch with `develop`, and run any
tests that have changed since `develop` extra times to catch new flaky
test regressions. Unfortunately this was happening even for PRs that do
not target develop, resulting in massive lists of "changed" tests that
ended up causing persistent test timeouts.

The quality gate should only impact PRs that target `develop`. PRs that
target other branches no longer repeat "changed" tests. This should fix
release PR e2e test timeouts caused by excessive e2e test runs.

You can see an example of this problem occurring here:
https://app.circleci.com/pipelines/github/MetaMask/metamask-extension/98357/workflows/b61a16b5-acfd-411f-b82e-7a31706ca658/jobs/3660843
Notice that
`/home/circleci/project/test/e2e/tests/request-queuing/ui.spec.js`
appears 6 times in the full test list, as to every other "changed" test.

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/26846?quickstart=1)

## **Related issues**

This quality gate was first introduced in #24556

## **Manual testing steps**

The script can be run locally if you setup "fake" CircleCI environment
variables to allow it to run properly. For example:

```
CIRCLE_PULL_REQUEST=#26822 yarn tsx ./.circleci/scripts/git-diff-develop.ts
```


The CI run for this PR can be viewed as well:
https://app.circleci.com/pipelines/github/MetaMask/metamask-extension/98369/workflows/e9de2170-a19e-433e-a83c-846eeb239842/jobs/3661034

## **Screenshots/Recordings**

N/A

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension 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
- [x] 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.
Gudahtt added a commit that referenced this pull request Sep 3, 2024
## **Description**

Our CI was setup to compare each branch with `develop`, and run any
tests that have changed since `develop` extra times to catch new flaky
test regressions. Unfortunately this was happening even for PRs that do
not target develop, resulting in massive lists of "changed" tests that
ended up causing persistent test timeouts.

The quality gate should only impact PRs that target `develop`. PRs that
target other branches no longer repeat "changed" tests. This should fix
release PR e2e test timeouts caused by excessive e2e test runs.

You can see an example of this problem occurring here:
https://app.circleci.com/pipelines/github/MetaMask/metamask-extension/98357/workflows/b61a16b5-acfd-411f-b82e-7a31706ca658/jobs/3660843
Notice that
`/home/circleci/project/test/e2e/tests/request-queuing/ui.spec.js`
appears 6 times in the full test list, as to every other "changed" test.

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/26846?quickstart=1)

## **Related issues**

This quality gate was first introduced in #24556

## **Manual testing steps**

The script can be run locally if you setup "fake" CircleCI environment
variables to allow it to run properly. For example:

```
CIRCLE_PULL_REQUEST=#26822 yarn tsx ./.circleci/scripts/git-diff-develop.ts
```


The CI run for this PR can be viewed as well:
https://app.circleci.com/pipelines/github/MetaMask/metamask-extension/98369/workflows/e9de2170-a19e-433e-a83c-846eeb239842/jobs/3661034

## **Screenshots/Recordings**

N/A

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension 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
- [x] 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.
Gudahtt added a commit that referenced this pull request Sep 3, 2024
…26856)

This is a cherry-pick of #26846 for v12.2.0. Original description:

## **Description**

Our CI was setup to compare each branch with `develop`, and run any
tests that have changed since `develop` extra times to catch new flaky
test regressions. Unfortunately this was happening even for PRs that do
not target develop, resulting in massive lists of "changed" tests that
ended up causing persistent test timeouts.

The quality gate should only impact PRs that target `develop`. PRs that
target other branches no longer repeat "changed" tests. This should fix
release PR e2e test timeouts caused by excessive e2e test runs.

You can see an example of this problem occurring here:
https://app.circleci.com/pipelines/github/MetaMask/metamask-extension/98357/workflows/b61a16b5-acfd-411f-b82e-7a31706ca658/jobs/3660843
Notice that
`/home/circleci/project/test/e2e/tests/request-queuing/ui.spec.js`
appears 6 times in the full test list, as to every other "changed" test.

[![Open in GitHub

Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/26846?quickstart=1)

## **Related issues**

This quality gate was first introduced in #24556

## **Manual testing steps**

The script can be run locally if you setup "fake" CircleCI environment
variables to allow it to run properly. For example:

```
CIRCLE_PULL_REQUEST=#26822 yarn tsx ./.circleci/scripts/git-diff-develop.ts
```


The CI run for this PR can be viewed as well:

https://app.circleci.com/pipelines/github/MetaMask/metamask-extension/98369/workflows/e9de2170-a19e-433e-a83c-846eeb239842/jobs/3661034

## **Screenshots/Recordings**

N/A

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension 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
- [x] 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.
…ng `defer`ed script tags (#26555)

This PR removes `load-*.js` helpers and load scripts using the `defer`
property instead.

This change drastically improves the performance of the extension but
greatly reduces perceived performance because the browser won't display
the popup until the DOMContentLoaded event.

But improve perceived performance is mostly regained by initially
loading an asset-less HTML file, `popup-init.html`, that then redirects
to the slower (but much faster than before this PR) `popup.html`.

This was initially authored by @Gudahtt, I've just updated and optimized
it to work with the both build systems.

One change I did not make was moving scripts to the `head`. I don't
think putting the scripts in the head does anything in our case[^1]
other than potentially require that we wait for `DOMContentLoaded`
before querying for the app container.

Note: In Firefox we continue to use `popup.html`. Firefox is very slow
to render the `popup-init.html` redirect, and it renders the page only
partially anyway, making the UX feel very janky. It also doesn't delay
opening the popup until `DOMContentLoaded`, like Chrome does, so the
issue `popup-init.html` solves doesn't do anything anyway.

---

Here is side-by-side video comparison of `develop` vs
`popup-defer-scripts`.

This video displays the elapsed time from clicking the MetaMask Fox to
Lock Screen render.

The end of the video is a frame-by-frame comparison of the new "jank"
this PR introduces. The develop branch renders the fox immediately,
whereas the popup-defer-scripts branch renders an empty page for about
15 milliseconds.

These stats aren't representative of real world performance, but are
intended to illustrate relative performance and perceived performance.

Both builds were created by running `yarn build dist`.

https://github.com/user-attachments/assets/38b856ca-d269-48f7-b305-19f4b9c6dce8

---

1. build with `yarn dist`
2. install into your browser and go through onboarding
3. open MetaMask
4. Marvel at how much faster it is

---

Closes
[#25721](#25721)

[^1]: our HTML files are very tiny, and thus will be loaded all in one
go, we don't have to worry about packets being lost and retransmitted
over the network, delaying the browser's preload scanner.

Co-authored-by: Mark Stacey <[email protected]>
@metamaskbot
Copy link
Collaborator

Builds ready [d1a0c12]
Page Load Metrics (1619 ± 37 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint1493179616247335
domContentLoaded1485178316037436
load1492179316197637
domInteractive146533147

Copy link

codecov bot commented Sep 3, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 70.41%. Comparing base (945b77c) to head (d1a0c12).
Report is 19 commits behind head on Version-v12.2.0.

Additional details and impacted files
@@                 Coverage Diff                 @@
##           Version-v12.2.0   #26822      +/-   ##
===================================================
+ Coverage            70.16%   70.41%   +0.25%     
===================================================
  Files                 1402     1398       -4     
  Lines                49435    49476      +41     
  Branches             13585    13588       +3     
===================================================
+ Hits                 34685    34837     +152     
+ Misses               14750    14639     -111     

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

@davidmurdoch davidmurdoch marked this pull request as ready for review September 3, 2024 15:34
@davidmurdoch davidmurdoch requested review from kumavis and a team as code owners September 3, 2024 15:34
@Gudahtt
Copy link
Member

Gudahtt commented Sep 3, 2024

The "blank screen" portion of the popup UI page load is much more pronounced when I am testing this locally. Here are some videos for comparison (production v12.1.1 versus the most recent build on this PR)

Before

Edit: Updated to show a video of the wallet in a locked state, to match the "After" video

Screen.Recording.2024-09-03.at.14.17.38.mov

After

Screen.Recording.2024-09-03.at.13.24.53.mov

<head>
<meta http-equiv="refresh" content="0;url=/popup.html">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: If this screen has no content, do we need these two extra meta tags?

Copy link
Member

@Gudahtt Gudahtt left a comment

Choose a reason for hiding this comment

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

LGTM! After consulting about the blank popup UI impact, we've decided to fix that in a future release

@danjm danjm merged commit 226d9a4 into Version-v12.2.0 Sep 3, 2024
66 checks passed
@danjm danjm deleted the v12.2.0-popup-defer-scripts branch September 3, 2024 18:27
@github-actions github-actions bot locked and limited conversation to collaborators Sep 3, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
release-12.2.0 Issue or pull request that will be included in release 12.2.0 team-extension-platform
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants