Skip to content

perf: add React.lazy to the Routes #28172

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 6 commits into from
Nov 25, 2024
Merged

perf: add React.lazy to the Routes #28172

merged 6 commits into from
Nov 25, 2024

Conversation

HowardBraham
Copy link
Contributor

@HowardBraham HowardBraham commented Oct 30, 2024

Description

Note: I would really appreciate quick reviews here mostly based on "did I break anything." It's not really worth our time to nit-pick about the style or the details because every line of this is going to be changed by me again in the near future. Still to do in later PRs that are going to completely re-write what I did here:

  • Convert routes.component.js to TypeScript
  • Convert routes.component.js to Hooks
  • Convert routes.component.js to react-router v6
  • Eliminate routes.container.js

All this has to be done in sequential PRs based on top of this one, so while I wait for reviews I can only work on a non-Routes topic.

This is the first PR to add React.lazy to the codebase. The meat of the changes are in ui/pages/routes/routes.component.js.

Every other file changed is just a reaction to those changes. Much of this is caused by the fact that React.lazy only works on default exports (see the documentation here), so I had to change a few named exports to default exports.

I don't think this PR has much of an impact on loading times, but it sets up further work that should have an impact.

There was one component (ConfirmTransaction) that needed some extra attention to work with React.lazy. I had to remove the history.replace(mostRecentOverviewPage);, which I'm pretty sure was an unnecessary statement, and remove the Unit Test related to it.

UPDATE: I changed all of the Integration Tests to convert getBy... to await findBy... to wait for the React.lazy component to load.

Open in GitHub Codespaces

Related issues

Progresses: MetaMask/MetaMask-planning#3302

@HowardBraham HowardBraham added area-performance Issues relating to slowness of app, cpu usage, and/or blank screens. type-tech-debt Technical debt team-tiger Tiger team (for tech debt reduction + performance improvements) labels Oct 30, 2024
@HowardBraham HowardBraham self-assigned this Oct 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.

@metamaskbot metamaskbot added the INVALID-PR-TEMPLATE PR's body doesn't match template label Oct 30, 2024
@HowardBraham HowardBraham removed the INVALID-PR-TEMPLATE PR's body doesn't match template label Oct 30, 2024
@metamaskbot
Copy link
Collaborator

Builds ready [7637683]
Page Load Metrics (1709 ± 68 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint13831948170613967
domContentLoaded13721939168313364
load13831949170914168
domInteractive28135543115
backgroundConnect681262311
firstReactRender167130199
getState47012147
initialActions04010
loadScripts9311428121211857
setupStore1192472713
uiStartup15532326193418086
Bundle size diffs
  • background: 0 Bytes (0.00%)
  • ui: -644 Bytes (-0.01%)
  • common: 0 Bytes (0.00%)

@metamaskbot
Copy link
Collaborator

Builds ready [3a1b168]
Page Load Metrics (1890 ± 136 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint30228671796450216
domContentLoaded159227751858277133
load160328481890282136
domInteractive217851178
backgroundConnect979272211
firstReactRender16103342713
getState574202411
initialActions01000
loadScripts111619951347220106
setupStore1185402713
uiStartup180630612120290139
Bundle size diffs
  • background: 0 Bytes (0.00%)
  • ui: -644 Bytes (-0.01%)
  • common: 0 Bytes (0.00%)

@HowardBraham HowardBraham marked this pull request as ready for review October 30, 2024 08:37
@HowardBraham HowardBraham requested review from a team as code owners October 30, 2024 08:37
@metamaskbot
Copy link
Collaborator

Builds ready [ca01e2a]
Page Load Metrics (1627 ± 38 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint1535182116297938
domContentLoaded1481181116058039
load1533181816277838
domInteractive278146157
backgroundConnect85223168
firstReactRender1594422713
getState412721
initialActions00000
loadScripts1065137311757737
setupStore1172262211
uiStartup16872177182612058
Bundle size diffs
  • background: 0 Bytes (0.00%)
  • ui: -644 Bytes (-0.01%)
  • common: 0 Bytes (0.00%)

matthewwalsh0
matthewwalsh0 previously approved these changes Nov 4, 2024
@@ -1 +1 @@
export { Connections } from './connections';
Copy link
Member

Choose a reason for hiding this comment

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

I hit this in my POC also, is there definitely no workaround for this as we tend to prefer non-default exports for auto-complete and extensibility?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay I found this method and it seems to work: https://dev.to/iamandrewluca/react-lazy-without-default-export-4b65

So we would write it as

const Connections = React.lazy(() =>
  import('../../components/multichain/pages/connections').then((module) => ({
    default: module.Connections,
  })),
);

But I'm not totally convinced we should do that. For one thing, it's kind of hard to follow. And second, people say it may limit tree-shaking.

@@ -122,6 +96,66 @@ import {
showOnboardingHeader,
} from './utils';

// Begin Lazy Routes
const OnboardingFlow = React.lazy(() =>
Copy link
Member

Choose a reason for hiding this comment

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

Given the volume of changes here and limited readability, is it worth listing these in alphabetical order?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hah, I guess it looked a little chaotic to you, but actually I was following an order. The lazy route imports are in the same order as the <Switch> component.

const OnboardingFlow = React.lazy(() =>
import('../onboarding-flow/onboarding-flow'),
);
const Lock = React.lazy(() => import('../lock'));
Copy link
Member

Choose a reason for hiding this comment

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

Minor, but something I did in my POC was create a helper function for this so we had an easy injection point for logging and timing.

develop...poc/react-lazy-load#diff-2466ed85b744b657eb0b324376eef5486080bf2b897eaa3af9b8c3ed0184ebeaR117

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a fascinating thought, and maybe the helper function could even handle the non-default-export thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is done

@metamaskbot
Copy link
Collaborator

Builds ready [52d363f]
Page Load Metrics (1949 ± 56 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint43521761875350168
domContentLoaded16822108191411555
load17492179194911656
domInteractive329157188
backgroundConnect775302311
firstReactRender1899622713
getState771232411
initialActions01000
loadScripts1142149813549847
setupStore127922178
uiStartup19612576223815775
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 0 Bytes (0.00%)
  • ui: 953 Bytes (0.01%)
  • common: 42 Bytes (0.00%)

@metamaskbot
Copy link
Collaborator

Builds ready [035d2f1]
Page Load Metrics (1995 ± 74 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint17732380199515173
domContentLoaded17612359196515172
load17712378199515374
domInteractive29111512010
backgroundConnect11114302311
firstReactRender155326126
getState56149104178
initialActions00000
loadScripts13451796150313364
setupStore64714136
uiStartup19962714227417584
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 0 Bytes (0.00%)
  • ui: 979 Bytes (0.01%)
  • common: 42 Bytes (0.00%)

@metamaskbot
Copy link
Collaborator

Builds ready [580162d]
Page Load Metrics (1680 ± 87 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint34222731630343165
domContentLoaded14832264165717785
load14852275168018187
domInteractive277341147
backgroundConnect583242210
firstReactRender14115292713
getState47214953919
initialActions01000
loadScripts11021496122210751
setupStore68511178
uiStartup167426101930261126
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 0 Bytes (0.00%)
  • ui: 979 Bytes (0.01%)
  • common: 42 Bytes (0.00%)

@HowardBraham HowardBraham force-pushed the react.lazy branch 7 times, most recently from 5ba5204 to ff86b44 Compare November 22, 2024 22:19
@metamaskbot
Copy link
Collaborator

Builds ready [a5e2bd5]
Page Load Metrics (1778 ± 57 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint35920581567502241
domContentLoaded15982033174611756
load16462062177811857
domInteractive257940178
backgroundConnect974362210
firstReactRender1873362010
getState67121199
initialActions01000
loadScripts11511518128010751
setupStore75315157
uiStartup18212451199215976
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 0 Bytes (0.00%)
  • ui: 972 Bytes (0.01%)
  • common: 42 Bytes (0.00%)

@HowardBraham HowardBraham force-pushed the react.lazy branch 2 times, most recently from 9c266ef to 8f4e4a4 Compare November 23, 2024 09:37
… set, and then do it by Math.random probability
@metamaskbot
Copy link
Collaborator

Builds ready [17fed26]
Page Load Metrics (1474 ± 34 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint43816481439241116
domContentLoaded1347155214465928
load1354164114747134
domInteractive167033189
backgroundConnect884282311
firstReactRender1597292311
getState55519178
initialActions01000
loadScripts974115310695627
setupStore610711
uiStartup1522192016489244
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 0 Bytes (0.00%)
  • ui: 1.21 KiB (0.02%)
  • common: 110 Bytes (0.00%)

@metamaskbot
Copy link
Collaborator

Builds ready [17fed26]
Page Load Metrics (1698 ± 56 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint25119251639343165
domContentLoaded14771902166911254
load15281907169811856
domInteractive23653094
backgroundConnect772322211
firstReactRender16102432713
getState495182110
initialActions00000
loadScripts10501398121910048
setupStore65114157
uiStartup16772360190015876
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 0 Bytes (0.00%)
  • ui: 1.21 KiB (0.02%)
  • common: 110 Bytes (0.00%)

@metamaskbot
Copy link
Collaborator

Builds ready [1152c05]
Page Load Metrics (1729 ± 90 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint15132335173118086
domContentLoaded14992244169317182
load15152350172918790
domInteractive2583452110
backgroundConnect9101372613
firstReactRender1696302311
getState591242411
initialActions01000
loadScripts10571669124014469
setupStore672202110
uiStartup167926351936232111
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 0 Bytes (0.00%)
  • ui: 1.21 KiB (0.02%)
  • common: 110 Bytes (0.00%)

@@ -133,9 +133,7 @@ const ConfirmTransaction = () => {
});

useEffect(() => {
if (!totalUnapproved && !sendTo) {
history.replace(mostRecentOverviewPage);
Copy link
Contributor

@jonybur jonybur Nov 25, 2024

Choose a reason for hiding this comment

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

We seem to be losing this redirect this is intended

@HowardBraham HowardBraham added this pull request to the merge queue Nov 25, 2024
Merged via the queue into develop with commit bf1455b Nov 25, 2024
75 checks passed
@HowardBraham HowardBraham deleted the react.lazy branch November 25, 2024 14:30
@github-actions github-actions bot locked and limited conversation to collaborators Nov 25, 2024
@metamaskbot metamaskbot added the release-12.9.0 Issue or pull request that will be included in release 12.9.0 label Nov 25, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-performance Issues relating to slowness of app, cpu usage, and/or blank screens. release-12.9.0 Issue or pull request that will be included in release 12.9.0 team-tiger Tiger team (for tech debt reduction + performance improvements) type-tech-debt Technical debt
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants