Commit d0795b6
authored
perf(bridge): migrate token selector to FlashList (#33230)
## **Description**
<!-- mms-check: type=text required=true -->
SWAPS-4672 tracks a medium-severity performance audit finding in the
bridge asset picker. Potentially large popular-token and paginated
search-result lists were rendered with the gesture-handler `FlatList`,
even though each token row contains avatars, badges, multiple views, and
per-row hooks. Pagination was also driven by a manual scroll handler
with `scrollEventThrottle={400}`, so the near-bottom check ran only a
few times per second and could trigger late or feel janky.
Network-filter changes compounded that cost by changing the list `key`,
forcing the entire list to remount and discard its recycled cells.
`extraData` only tracked the list length, while FlatList-specific
windowing and clipping props added more manual tuning around a rich,
variable dataset.
This PR:
- Migrates the token selector to FlashList v2 so rich rows are recycled
across long popular-token and search-result lists.
- Increases scroll sampling from 400 ms to 16 ms so the existing
near-bottom pagination check responds promptly.
- Removes the keyed network-change remount, length-only `extraData`, and
FlatList-specific rendering/windowing props.
- Keeps the list mounted across network filters, disables
visible-content position maintenance for replacement datasets, and
resets to row zero through FlashList's recycler-aware `scrollToIndex`
after the new data commits.
- Removes the redundant token-address key inside each recycled row.
- Adds regression coverage for list configuration, retained mounting,
and network-switch scroll resets.
During manual validation, the migration exposed two recycler timing
cases: All → Ethereum → All could show an empty list until scrolling,
and switching networks after scrolling could leave the first asset
blank. The final reset and visible-content-position configuration
address both cases while preserving FlashList recycling.
## **Changelog**
<!-- mms-check: type=changelog required=true blocking=true -->
CHANGELOG entry: Improved bridge asset picker scrolling, pagination, and
token rendering when switching networks
## **Related issues**
<!-- mms-check: type=issue-link required=true -->
Fixes: #31365
Refs:
[SWAPS-4672](https://consensyssoftware.atlassian.net/browse/SWAPS-4672)
## **Manual testing steps**
<!-- mms-check: type=manual-testing required=true -->
```gherkin
Feature: Bridge asset picker list performance and network switching
Background:
Given I am logged into MetaMask Mobile
And I open the bridge source or destination asset picker
Scenario: scroll and paginate a long token search result list
Given my search returns enough tokens to exceed the visible list
When I scroll toward the bottom of the search results
Then additional results should begin loading promptly
And the list should scroll without blank or flashing token rows
Scenario: switch from All to Ethereum and back to All
Given the asset picker is showing the All network tab
When I tap the Ethereum network tab
And I tap the All network tab
Then the All-network asset list should render immediately without additional scrolling
Scenario: switch networks after scrolling the asset list
Given the asset picker is showing the All network tab
When I scroll down the asset list
And I tap another network tab
Then the list should reset to the top
And the first asset for the selected network should render without additional scrolling
When I switch to a different network tab
Then the first asset for that network should render without additional scrolling
```
## **Screenshots/Recordings**
<!-- mms-check: type=screenshot required=true -->
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of this change. -->
### **Before**
N/A
### **After**
N/A
## **Pre-merge author checklist**
<!-- mms-check: type=checklist required=true -->
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.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-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [x] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [x] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [x] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!-- mms-check: type=checklist required=true -->
- [ ] 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.
<!-- Generated with the help of the pr-description AI skill -->
[SWAPS-4672]:
https://consensyssoftware.atlassian.net/browse/SWAPS-4672?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ1 parent 687f807 commit d0795b6
3 files changed
Lines changed: 113 additions & 20 deletions
File tree
- app/components/UI/Bridge/components
- BridgeTokenSelector
Lines changed: 84 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
476 | 476 | | |
477 | 477 | | |
478 | 478 | | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
479 | 483 | | |
480 | 484 | | |
481 | 485 | | |
| |||
580 | 584 | | |
581 | 585 | | |
582 | 586 | | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
583 | 612 | | |
584 | 613 | | |
585 | 614 | | |
| |||
965 | 994 | | |
966 | 995 | | |
967 | 996 | | |
| 997 | + | |
| 998 | + | |
| 999 | + | |
| 1000 | + | |
| 1001 | + | |
| 1002 | + | |
| 1003 | + | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
| 1007 | + | |
| 1008 | + | |
| 1009 | + | |
| 1010 | + | |
| 1011 | + | |
| 1012 | + | |
| 1013 | + | |
| 1014 | + | |
| 1015 | + | |
| 1016 | + | |
| 1017 | + | |
| 1018 | + | |
| 1019 | + | |
| 1020 | + | |
| 1021 | + | |
| 1022 | + | |
| 1023 | + | |
| 1024 | + | |
| 1025 | + | |
| 1026 | + | |
| 1027 | + | |
| 1028 | + | |
| 1029 | + | |
| 1030 | + | |
| 1031 | + | |
968 | 1032 | | |
969 | 1033 | | |
970 | 1034 | | |
| |||
1053 | 1117 | | |
1054 | 1118 | | |
1055 | 1119 | | |
| 1120 | + | |
| 1121 | + | |
| 1122 | + | |
| 1123 | + | |
| 1124 | + | |
| 1125 | + | |
| 1126 | + | |
| 1127 | + | |
| 1128 | + | |
| 1129 | + | |
| 1130 | + | |
| 1131 | + | |
| 1132 | + | |
| 1133 | + | |
| 1134 | + | |
| 1135 | + | |
| 1136 | + | |
| 1137 | + | |
| 1138 | + | |
| 1139 | + | |
1056 | 1140 | | |
1057 | 1141 | | |
1058 | 1142 | | |
| |||
Lines changed: 29 additions & 19 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | | - | |
12 | | - | |
| 8 | + | |
13 | 9 | | |
14 | 10 | | |
15 | 11 | | |
| |||
19 | 15 | | |
20 | 16 | | |
21 | 17 | | |
22 | | - | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| |||
144 | 144 | | |
145 | 145 | | |
146 | 146 | | |
147 | | - | |
| 147 | + | |
148 | 148 | | |
149 | 149 | | |
150 | 150 | | |
| |||
231 | 231 | | |
232 | 232 | | |
233 | 233 | | |
234 | | - | |
| 234 | + | |
235 | 235 | | |
236 | 236 | | |
237 | 237 | | |
| |||
284 | 284 | | |
285 | 285 | | |
286 | 286 | | |
287 | | - | |
| 287 | + | |
288 | 288 | | |
289 | 289 | | |
290 | 290 | | |
| |||
348 | 348 | | |
349 | 349 | | |
350 | 350 | | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
351 | 366 | | |
352 | 367 | | |
353 | 368 | | |
| |||
474 | 489 | | |
475 | 490 | | |
476 | 491 | | |
477 | | - | |
478 | | - | |
| 492 | + | |
| 493 | + | |
479 | 494 | | |
480 | 495 | | |
481 | 496 | | |
| |||
644 | 659 | | |
645 | 660 | | |
646 | 661 | | |
647 | | - | |
| 662 | + | |
648 | 663 | | |
649 | | - | |
650 | 664 | | |
651 | 665 | | |
652 | 666 | | |
653 | 667 | | |
654 | 668 | | |
655 | 669 | | |
656 | | - | |
657 | 670 | | |
658 | 671 | | |
659 | 672 | | |
660 | | - | |
| 673 | + | |
661 | 674 | | |
662 | 675 | | |
663 | 676 | | |
664 | 677 | | |
665 | | - | |
666 | | - | |
667 | | - | |
668 | | - | |
| 678 | + | |
669 | 679 | | |
670 | 680 | | |
671 | 681 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
359 | 359 | | |
360 | 360 | | |
361 | 361 | | |
362 | | - | |
363 | 362 | | |
364 | 363 | | |
365 | 364 | | |
| |||
0 commit comments