MetaMask / metamask-mobile

Mobile web browser providing access to websites that use the Ethereum blockchain
https://metamask.io
Other
2.18k stars 1.12k forks source link

perf: Remove costly reduce operation for generating Engine context #12374

Closed MajorLift closed 3 days ago

MajorLift commented 4 days ago

Overview

Optimizes an expensive operation from the Engine initialization process.

A custom span for measuring this process was added in https://github.com/MetaMask/metamask-mobile/pull/11579.

Motivation

Currently, the Engine's context object is created using a Array.prototype.reduce() operation on a large controllers array. This reduce call is also written to create a temporary object on every iteration.

Benchmarks show that this particular implementation of reduce runs significantly slower than other means of creating an object, and compared to reduce calls that are written to re-use the output object the difference is in four orders of magnitude (1555.6 Ops/sec vs. 0.2 Ops/sec).

https://www.measurethat.net/Benchmarks/Show/21554/0/objectfromentries-vs-reduce-vs-assign

A simple fix would be to refactor the reduce operation so it doesn't rely on temporary objects and spreading:

diff --git a/app/core/Engine.ts b/app/core/Engine.ts
index decf28da51..1ba63ed106 100644
--- a/app/core/Engine.ts
+++ b/app/core/Engine.ts
@@ -1738,10 +1738,10 @@ export class Engine {
       this.controllerMessenger,
     );
     this.context = controllers.reduce<Partial<typeof this.context>>(
-      (context, controller) => ({
-        ...context,
-        [controller.name]: controller,
-      }),
+      (context, controller) => {
+        context[controller.name] = controller;
+        return context;
+      },
       {},
     ) as typeof this.context;

However, we can also avoid the cost of running reduce altogether simply by creating a controller name-keyed object to assign to the Engine's context field. This is also the approach taken in the Extension MetamaskController.

Description

Related issues

Manual testing steps

Screenshots/Recordings

Pre-merge author checklist

Pre-merge reviewer checklist

github-actions[bot] commented 4 days ago

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.

github-actions[bot] commented 4 days ago

https://bitrise.io/ Bitrise

🔄🔄🔄 pr_smoke_e2e_pipeline started on Bitrise...🔄🔄🔄

Commit hash: 2c345471738a96719fa86d58e03a6a0f54efd648 Build link: https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/d2c35a05-5104-4eb1-860d-0ff113c32b79

[!NOTE]

  • This comment will auto-update when build completes
  • You can kick off another pr_smoke_e2e_pipeline on Bitrise by removing and re-applying the Run Smoke E2E label on the pull request
github-actions[bot] commented 4 days ago

https://bitrise.io/ Bitrise

🔄🔄🔄 pr_smoke_e2e_pipeline started on Bitrise...🔄🔄🔄

Commit hash: 87744830e57fcb7e2f432aca0ec8f63489c41312 Build link: https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/8fe73c04-76bb-4248-9834-03d19340af7a

[!NOTE]

  • This comment will auto-update when build completes
  • You can kick off another pr_smoke_e2e_pipeline on Bitrise by removing and re-applying the Run Smoke E2E label on the pull request
github-actions[bot] commented 4 days ago

https://bitrise.io/ Bitrise

✅✅✅ pr_smoke_e2e_pipeline passed on Bitrise! ✅✅✅

Commit hash: 0c662ae85cb4c2024ef06ddf9ef15a7fc9dae297 Build link: https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/11d7cf96-828d-4136-8582-ed7a120b0624

[!NOTE]

  • You can kick off another pr_smoke_e2e_pipeline on Bitrise by removing and re-applying the Run Smoke E2E label on the pull request
codecov-commenter commented 4 days ago

Codecov Report

Attention: Patch coverage is 83.33333% with 1 line in your changes missing coverage. Please review.

Project coverage is 56.46%. Comparing base (22a4989) to head (0c662ae). Report is 29 commits behind head on main.

Files with missing lines Patch % Lines
app/core/Engine.ts 83.33% 0 Missing and 1 partial :warning:
Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #12374 +/- ## ========================================== + Coverage 56.41% 56.46% +0.04% ========================================== Files 1797 1808 +11 Lines 40586 40724 +138 Branches 5097 5131 +34 ========================================== + Hits 22896 22993 +97 - Misses 16134 16159 +25 - Partials 1556 1572 +16 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.


🚨 Try these New Features:

sonarcloud[bot] commented 4 days ago

Quality Gate Passed Quality Gate passed

Issues
1 New issue
0 Accepted issues

Measures
0 Security Hotspots
87.5% Coverage on New Code
0.0% Duplication on New Code

See analysis details on SonarQube Cloud