refactor: unapproved transaction count selector
Description
Optimize the getNumberOfAllUnapprovedTransactionsAndMessages selector
Changelog
CHANGELOG entry: null
Related issues
Fixes: https://github.com/MetaMask/MetaMask-planning/issues/6380
Manual testing steps
- Go to this page...
Screenshots/Recordings
Before
After
Pre-merge author checklist
- [ ] I've followed MetaMask Contributor Docs and MetaMask Extension 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.
[!NOTE] Rewrites
getNumberOfAllUnapprovedTransactionsAndMessagesas a memoized selector using specific unapproved message selectors and sums their counts.
- Selectors:
- Refactor
getNumberOfAllUnapprovedTransactionsAndMessagesto a memoizedcreateDeepEqualSelectorcomposinggetAllUnapprovedTransactions,unapprovedDecryptMsgsSelector,unapprovedPersonalMsgsSelector,unapprovedEncryptionPublicKeyMsgsSelector, andunapprovedTypedMessagesSelector; returns summed counts with safe fallbacks.- Add imports for the new unapproved message selectors in
ui/selectors/selectors.js.Written by Cursor Bugbot for commit 860c158b2d482b5854df4b49f3c266d70187d6c6. This will update automatically on new commits. Configure here.
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.
Builds ready [860c158]
- builds: chrome, firefox
- builds (beta): chrome, firefox
- builds (flask): chrome, firefox
- builds (test): chrome, firefox
- builds (test-flask): chrome, firefox
- bundle size: Bundle Size Stats
- user-actions-benchmark: User Actions Stats
- storybook: Storybook
- typescript migration: Dashboard
- all artifacts
UI Startup Metrics (1239 ± 120 ms)
| Platform | BuildType | Page | Metric | Mean (ms) | Min (ms) | Max (ms) | Std Dev (ms) | P 75 (ms) | P 95 (ms) |
|---|---|---|---|---|---|---|---|---|---|
| Chrome | Browserify | Standard Home | uiStartup | 1239 | 986 | 1686 | 120 | 1306 | 1429 |
| load | 1016 | 837 | 1403 | 103 | 1067 | 1173 | |||
| domContentLoaded | 1010 | 832 | 1396 | 102 | 1061 | 1165 | |||
| domInteractive | 25 | 14 | 104 | 19 | 21 | 79 | |||
| firstPaint | 471 | 79 | 1184 | 386 | 980 | 1135 | |||
| backgroundConnect | 209 | 189 | 260 | 12 | 214 | 234 | |||
| firstReactRender | 44 | 31 | 87 | 13 | 48 | 77 | |||
| getState | 37 | 18 | 140 | 17 | 40 | 64 | |||
| initialActions | 1 | 0 | 3 | 1 | 1 | 2 | |||
| loadScripts | 807 | 637 | 1160 | 96 | 860 | 964 | |||
| setupStore | 11 | 7 | 35 | 5 | 13 | 22 | |||
| numNetworkReqs | 14 | 6 | 85 | 21 | 6 | 75 | |||
| Browserify | Power User Home | uiStartup | 1919 | 1588 | 2300 | 155 | 2024 | 2224 | |
| load | 1091 | 917 | 1383 | 116 | 1177 | 1287 | |||
| domContentLoaded | 1081 | 909 | 1374 | 116 | 1163 | 1281 | |||
| domInteractive | 31 | 17 | 156 | 23 | 27 | 95 | |||
| firstPaint | 580 | 103 | 1402 | 427 | 1068 | 1260 | |||
| backgroundConnect | 250 | 201 | 579 | 82 | 241 | 517 | |||
| firstReactRender | 50 | 41 | 73 | 6 | 52 | 62 | |||
| getState | 214 | 149 | 752 | 118 | 203 | 671 | |||
| initialActions | 1 | 0 | 3 | 1 | 1 | 2 | |||
| loadScripts | 865 | 700 | 1155 | 114 | 945 | 1071 | |||
| setupStore | 16 | 8 | 56 | 8 | 15 | 36 | |||
| numNetworkReqs | 73 | 58 | 214 | 22 | 68 | 128 | |||
| Webpack | Standard Home | uiStartup | 839 | 686 | 1110 | 89 | 892 | 1026 | |
| load | 673 | 581 | 891 | 79 | 725 | 814 | |||
| domContentLoaded | 668 | 575 | 884 | 78 | 721 | 808 | |||
| domInteractive | 27 | 16 | 103 | 19 | 23 | 85 | |||
| firstPaint | 260 | 86 | 851 | 199 | 235 | 767 | |||
| backgroundConnect | 12 | 5 | 64 | 9 | 12 | 31 | |||
| firstReactRender | 54 | 34 | 192 | 31 | 58 | 125 | |||
| getState | 29 | 15 | 87 | 13 | 38 | 54 | |||
| initialActions | 1 | 0 | 4 | 1 | 1 | 2 | |||
| loadScripts | 664 | 573 | 882 | 77 | 719 | 806 | |||
| setupStore | 12 | 6 | 35 | 6 | 14 | 29 | |||
| numNetworkReqs | 14 | 6 | 86 | 20 | 6 | 71 | |||
| Webpack | Power User Home | uiStartup | 1413 | 1061 | 2015 | 212 | 1574 | 1816 | |
| load | 720 | 590 | 985 | 104 | 816 | 914 | |||
| domContentLoaded | 712 | 583 | 977 | 104 | 809 | 904 | |||
| domInteractive | 30 | 17 | 135 | 25 | 25 | 97 | |||
| firstPaint | 279 | 93 | 910 | 203 | 284 | 729 | |||
| backgroundConnect | 105 | 7 | 676 | 185 | 91 | 590 | |||
| firstReactRender | 50 | 40 | 71 | 5 | 52 | 65 | |||
| getState | 180 | 84 | 332 | 33 | 187 | 248 | |||
| initialActions | 1 | 0 | 3 | 1 | 1 | 2 | |||
| loadScripts | 709 | 581 | 974 | 103 | 801 | 902 | |||
| setupStore | 15 | 7 | 39 | 8 | 14 | 36 | |||
| numNetworkReqs | 72 | 59 | 227 | 24 | 67 | 128 | |||
| Firefox | Browserify | Standard Home | uiStartup | 1329 | 1067 | 2569 | 218 | 1433 | 1730 |
| load | 1068 | 904 | 2253 | 155 | 1117 | 1239 | |||
| domContentLoaded | 1067 | 904 | 2253 | 155 | 1111 | 1239 | |||
| domInteractive | 70 | 31 | 1147 | 115 | 78 | 170 | |||
| firstPaint | - | - | - | - | - | - | |||
| backgroundConnect | 53 | 20 | 299 | 50 | 52 | 169 | |||
| firstReactRender | 39 | 31 | 69 | 9 | 41 | 62 | |||
| getState | 12 | 7 | 96 | 10 | 11 | 25 | |||
| initialActions | 1 | 0 | 2 | 0 | 2 | 2 | |||
| loadScripts | 1039 | 883 | 2146 | 141 | 1089 | 1204 | |||
| setupStore | 19 | 5 | 216 | 35 | 12 | 59 | |||
| numNetworkReqs | 16 | 6 | 89 | 22 | 8 | 80 | |||
| Browserify | Power User Home | uiStartup | 2675 | 1647 | 3760 | 557 | 3138 | 3476 | |
| load | 1657 | 998 | 2636 | 509 | 2103 | 2380 | |||
| domContentLoaded | 1657 | 998 | 2636 | 509 | 2103 | 2380 | |||
| domInteractive | 120 | 33 | 983 | 173 | 96 | 425 | |||
| firstPaint | - | - | - | - | - | - | |||
| backgroundConnect | 230 | 25 | 1162 | 252 | 251 | 975 | |||
| firstReactRender | 57 | 38 | 182 | 18 | 61 | 88 | |||
| getState | 140 | 57 | 361 | 51 | 161 | 242 | |||
| initialActions | 4 | 0 | 63 | 9 | 2 | 32 | |||
| loadScripts | 1554 | 981 | 2477 | 471 | 2001 | 2282 | |||
| setupStore | 53 | 5 | 1041 | 114 | 59 | 225 | |||
| numNetworkReqs | 76 | 56 | 137 | 24 | 68 | 131 | |||
| Webpack | Standard Home | uiStartup | 1671 | 1311 | 2291 | 188 | 1781 | 2023 | |
| load | 1354 | 1126 | 1782 | 118 | 1425 | 1611 | |||
| domContentLoaded | 1353 | 1126 | 1781 | 118 | 1425 | 1611 | |||
| domInteractive | 82 | 28 | 190 | 41 | 115 | 163 | |||
| firstPaint | - | - | - | - | - | - | |||
| backgroundConnect | 63 | 17 | 187 | 41 | 80 | 157 | |||
| firstReactRender | 44 | 32 | 112 | 10 | 48 | 58 | |||
| getState | 22 | 7 | 190 | 32 | 17 | 76 | |||
| initialActions | 1 | 0 | 3 | 1 | 2 | 2 | |||
| loadScripts | 1321 | 1110 | 1751 | 109 | 1389 | 1509 | |||
| setupStore | 20 | 6 | 129 | 24 | 18 | 74 | |||
| numNetworkReqs | 16 | 6 | 92 | 22 | 8 | 78 | |||
| Webpack | Power User Home | uiStartup | 2677 | 1798 | 4039 | 518 | 3126 | 3439 | |
| load | 1893 | 1198 | 2671 | 487 | 2336 | 2574 | |||
| domContentLoaded | 1892 | 1198 | 2670 | 487 | 2335 | 2574 | |||
| domInteractive | 191 | 29 | 1033 | 302 | 114 | 987 | |||
| firstPaint | - | - | - | - | - | - | |||
| backgroundConnect | 160 | 24 | 978 | 196 | 204 | 922 | |||
| firstReactRender | 58 | 38 | 127 | 17 | 62 | 114 | |||
| getState | 129 | 74 | 266 | 46 | 161 | 228 | |||
| initialActions | 4 | 1 | 73 | 10 | 2 | 32 | |||
| loadScripts | 1799 | 1168 | 2619 | 470 | 2237 | 2469 | |||
| setupStore | 39 | 5 | 1014 | 106 | 35 | 154 | |||
| numNetworkReqs | 76 | 58 | 134 | 22 | 69 | 127 |
📊 Page Load Benchmark Results
Current Commit: 860c158 | Date: 12/9/2025
📄 Localhost MetaMask Test Dapp
Samples: 100
Summary
- pageLoadTime-> current mean value: 1.05s (±53ms) 🟡 | historical mean value: 1.05s ⬆️ (historical data)
- domContentLoaded-> current mean value: 733ms (±50ms) 🟢 | historical mean value: 733ms ⬇️ (historical data)
- firstContentfulPaint-> current mean value: 77ms (±13ms) 🟢 | historical mean value: 83ms ⬇️ (historical data)
📈 Detailed Results
| Metric | Mean | Std Dev | Min | Max | P95 | P99 |
|---|---|---|---|---|---|---|
| pageLoadTime | 1.05s | 53ms | 1.02s | 1.45s | 1.07s | 1.45s |
| domContentLoaded | 733ms | 50ms | 708ms | 1.12s | 748ms | 1.12s |
| firstPaint | 77ms | 13ms | 60ms | 196ms | 84ms | 196ms |
| firstContentfulPaint | 77ms | 13ms | 60ms | 196ms | 84ms | 196ms |
| largestContentfulPaint | 0ms | 0ms | 0ms | 0ms | 0ms | 0ms |
Bundle size diffs [🚨 Warning! Bundle size has increased!]
- background: 58 Bytes (0%)
- ui: 0 Bytes (0%)
- common: 160 Bytes (0%)
Builds ready [181d210]
- builds: chrome, firefox
- builds (beta): chrome, firefox
- builds (flask): chrome, firefox
- builds (test): chrome, firefox
- builds (test-flask): chrome, firefox
- bundle size: Bundle Size Stats
- user-actions-benchmark: User Actions Stats
- storybook: Storybook
- typescript migration: Dashboard
- all artifacts
UI Startup Metrics (1349 ± 100 ms)
| Platform | BuildType | Page | Metric | Mean (ms) | Min (ms) | Max (ms) | Std Dev (ms) | P 75 (ms) | P 95 (ms) |
|---|---|---|---|---|---|---|---|---|---|
| Chrome | Browserify | Standard Home | uiStartup | 1349 | 1139 | 1713 | 100 | 1415 | 1484 |
| load | 1095 | 891 | 1377 | 88 | 1157 | 1235 | |||
| domContentLoaded | 1089 | 884 | 1372 | 88 | 1150 | 1228 | |||
| domInteractive | 29 | 15 | 112 | 22 | 24 | 94 | |||
| firstPaint | 521 | 80 | 1285 | 411 | 1055 | 1180 | |||
| backgroundConnect | 227 | 208 | 274 | 13 | 236 | 256 | |||
| firstReactRender | 54 | 33 | 146 | 21 | 62 | 97 | |||
| getState | 40 | 17 | 171 | 26 | 45 | 74 | |||
| initialActions | 1 | 0 | 11 | 1 | 1 | 2 | |||
| loadScripts | 868 | 670 | 1118 | 85 | 920 | 1024 | |||
| setupStore | 13 | 7 | 33 | 5 | 13 | 27 | |||
| numNetworkReqs | 13 | 6 | 82 | 20 | 6 | 72 | |||
| Browserify | Power User Home | uiStartup | 1911 | 1632 | 2650 | 186 | 1999 | 2221 | |
| load | 1069 | 871 | 1472 | 124 | 1165 | 1276 | |||
| domContentLoaded | 1059 | 866 | 1455 | 123 | 1157 | 1255 | |||
| domInteractive | 30 | 17 | 144 | 25 | 26 | 102 | |||
| firstPaint | 561 | 98 | 1471 | 421 | 993 | 1255 | |||
| backgroundConnect | 249 | 195 | 825 | 111 | 228 | 609 | |||
| firstReactRender | 48 | 39 | 89 | 6 | 49 | 59 | |||
| getState | 196 | 148 | 687 | 74 | 198 | 268 | |||
| initialActions | 1 | 0 | 2 | 0 | 1 | 1 | |||
| loadScripts | 849 | 668 | 1240 | 119 | 950 | 1040 | |||
| setupStore | 15 | 7 | 45 | 7 | 14 | 34 | |||
| numNetworkReqs | 72 | 58 | 203 | 22 | 67 | 129 | |||
| Webpack | Standard Home | uiStartup | 798 | 652 | 1060 | 82 | 845 | 932 | |
| load | 643 | 553 | 803 | 73 | 695 | 786 | |||
| domContentLoaded | 636 | 547 | 797 | 72 | 688 | 779 | |||
| domInteractive | 25 | 14 | 90 | 19 | 21 | 80 | |||
| firstPaint | 314 | 74 | 814 | 224 | 570 | 744 | |||
| backgroundConnect | 12 | 5 | 33 | 6 | 15 | 28 | |||
| firstReactRender | 50 | 31 | 175 | 27 | 53 | 130 | |||
| getState | 27 | 12 | 62 | 11 | 35 | 47 | |||
| initialActions | 1 | 0 | 3 | 1 | 1 | 2 | |||
| loadScripts | 633 | 545 | 793 | 71 | 686 | 775 | |||
| setupStore | 11 | 5 | 42 | 6 | 12 | 27 | |||
| numNetworkReqs | 14 | 6 | 78 | 20 | 6 | 74 | |||
| Webpack | Power User Home | uiStartup | 1410 | 1061 | 2013 | 200 | 1596 | 1712 | |
| load | 735 | 579 | 1034 | 112 | 842 | 906 | |||
| domContentLoaded | 727 | 574 | 1023 | 110 | 834 | 896 | |||
| domInteractive | 31 | 17 | 128 | 24 | 27 | 110 | |||
| firstPaint | 363 | 89 | 951 | 260 | 650 | 886 | |||
| backgroundConnect | 62 | 7 | 569 | 129 | 38 | 541 | |||
| firstReactRender | 51 | 42 | 78 | 6 | 53 | 62 | |||
| getState | 205 | 149 | 668 | 62 | 235 | 299 | |||
| initialActions | 1 | 0 | 4 | 1 | 1 | 2 | |||
| loadScripts | 724 | 572 | 1021 | 110 | 831 | 893 | |||
| setupStore | 15 | 8 | 43 | 9 | 13 | 37 | |||
| numNetworkReqs | 72 | 59 | 217 | 26 | 67 | 142 | |||
| Firefox | Browserify | Standard Home | uiStartup | 1332 | 1076 | 2190 | 180 | 1413 | 1675 |
| load | 1076 | 910 | 1975 | 130 | 1128 | 1269 | |||
| domContentLoaded | 1075 | 910 | 1975 | 130 | 1127 | 1269 | |||
| domInteractive | 77 | 31 | 1000 | 100 | 91 | 157 | |||
| firstPaint | - | - | - | - | - | - | |||
| backgroundConnect | 44 | 20 | 178 | 30 | 49 | 112 | |||
| firstReactRender | 38 | 31 | 74 | 8 | 40 | 60 | |||
| getState | 12 | 6 | 144 | 14 | 11 | 27 | |||
| initialActions | 1 | 0 | 2 | 0 | 1 | 2 | |||
| loadScripts | 1050 | 895 | 1956 | 125 | 1099 | 1252 | |||
| setupStore | 14 | 6 | 127 | 18 | 11 | 41 | |||
| numNetworkReqs | 15 | 6 | 84 | 22 | 8 | 77 | |||
| Browserify | Power User Home | uiStartup | 2629 | 1638 | 3621 | 545 | 3067 | 3395 | |
| load | 1625 | 1041 | 2566 | 497 | 2099 | 2373 | |||
| domContentLoaded | 1625 | 1041 | 2566 | 497 | 2099 | 2373 | |||
| domInteractive | 144 | 33 | 1171 | 251 | 90 | 952 | |||
| firstPaint | - | - | - | - | - | - | |||
| backgroundConnect | 244 | 24 | 1131 | 279 | 260 | 1026 | |||
| firstReactRender | 56 | 36 | 104 | 10 | 60 | 73 | |||
| getState | 142 | 77 | 397 | 54 | 172 | 224 | |||
| initialActions | 3 | 0 | 51 | 6 | 2 | 7 | |||
| loadScripts | 1490 | 1002 | 2375 | 455 | 1928 | 2288 | |||
| setupStore | 47 | 5 | 469 | 76 | 46 | 239 | |||
| numNetworkReqs | 74 | 58 | 132 | 22 | 68 | 127 | |||
| Webpack | Standard Home | uiStartup | 1709 | 1427 | 2372 | 170 | 1801 | 2063 | |
| load | 1385 | 1184 | 1670 | 107 | 1465 | 1597 | |||
| domContentLoaded | 1385 | 1184 | 1669 | 107 | 1465 | 1597 | |||
| domInteractive | 84 | 30 | 179 | 39 | 118 | 145 | |||
| firstPaint | - | - | - | - | - | - | |||
| backgroundConnect | 64 | 20 | 289 | 43 | 76 | 147 | |||
| firstReactRender | 46 | 36 | 81 | 7 | 50 | 58 | |||
| getState | 24 | 7 | 216 | 37 | 17 | 124 | |||
| initialActions | 1 | 0 | 3 | 1 | 2 | 2 | |||
| loadScripts | 1350 | 1164 | 1598 | 98 | 1422 | 1537 | |||
| setupStore | 16 | 7 | 91 | 13 | 14 | 50 | |||
| numNetworkReqs | 15 | 6 | 80 | 21 | 8 | 75 | |||
| Webpack | Power User Home | uiStartup | 2734 | 1759 | 3551 | 524 | 3214 | 3427 | |
| load | 1852 | 1121 | 2849 | 515 | 2339 | 2533 | |||
| domContentLoaded | 1851 | 1120 | 2848 | 515 | 2338 | 2532 | |||
| domInteractive | 256 | 29 | 999 | 358 | 251 | 983 | |||
| firstPaint | - | - | - | - | - | - | |||
| backgroundConnect | 155 | 26 | 1000 | 174 | 189 | 495 | |||
| firstReactRender | 54 | 37 | 119 | 12 | 60 | 68 | |||
| getState | 130 | 82 | 249 | 43 | 161 | 218 | |||
| initialActions | 3 | 0 | 41 | 6 | 2 | 5 | |||
| loadScripts | 1790 | 1106 | 2821 | 495 | 2250 | 2506 | |||
| setupStore | 49 | 4 | 1083 | 120 | 39 | 232 | |||
| numNetworkReqs | 71 | 47 | 131 | 24 | 67 | 124 |
📊 Page Load Benchmark Results
Current Commit: 181d210 | Date: 12/10/2025
📄 Localhost MetaMask Test Dapp
Samples: 100
Summary
- pageLoadTime-> current mean value: 1.03s (±140ms) 🟡 | historical mean value: 1.03s ⬆️ (historical data)
- domContentLoaded-> current mean value: 725ms (±145ms) 🟢 | historical mean value: 718ms ⬆️ (historical data)
- firstContentfulPaint-> current mean value: 95ms (±212ms) 🟢 | historical mean value: 77ms ⬆️ (historical data)
📈 Detailed Results
| Metric | Mean | Std Dev | Min | Max | P95 | P99 |
|---|---|---|---|---|---|---|
| pageLoadTime | 1.03s | 140ms | 1.00s | 2.39s | 1.03s | 2.39s |
| domContentLoaded | 725ms | 145ms | 692ms | 2.14s | 720ms | 2.14s |
| firstPaint | 95ms | 212ms | 56ms | 2.20s | 84ms | 2.20s |
| firstContentfulPaint | 95ms | 212ms | 56ms | 2.20s | 84ms | 2.20s |
| largestContentfulPaint | 0ms | 0ms | 0ms | 0ms | 0ms | 0ms |
Bundle size diffs [🚀 Bundle size reduced!]
- background: 137 Bytes (0%)
- ui: 4.2 KiB (0.05%)
- common: -236 Bytes (0%)