MetaMask / MetaMask/metamask-mobile
Memoize selectCustomNetworkConfigurationsByCaipChainId filter result
- Dominant language
- TypeScript
- Stars
- 3k
- Forks
- 1.7k
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 669
Description
> **Performance audit finding** · Severity: **Medium** · Effort: Easy · Fix risk: Simple · Test safety net: Partial
> Owner: `@MetaMask/mobile-core-ux (suggested)`
> File: `app/selectors/networkController.ts:274`
### What is this about?
`selectCustomNetworkConfigurationsByCaipChainId` is a plain `createSelector` whose result function returns `Object.values(...).filter(...)`, building a new array every recompute. Its input `selectNetworkConfigurationsByCaipChainId` is a plain `createSelector` that builds a fresh object (via `getNetworkConfigurationsByCaipChainId` spreads) whenever either network slice changes, so this selector reruns and yields a new array on any network-slice mutation.
**Why it matters**
Custom network lists feed network management/picker UI. A new array reference forces consumers to re-render even when the custom networks are unchanged.
### Scenario
N/A — see Technical Details.
### Design
N/A — internal performance change; no UI/design impact.
### Technical Details
**Evidence**
`app/selectors/networkController.ts:274`
```ts
export const selectCustomNetworkConfigurationsByCaipChainId = createSelector(
selectNetworkConfigurationsByCaipChainId,
(networkConfigurationsByChainId) =>
Object.values(networkConfigurationsByChainId).filter(
(networkConfiguration) =>
(networkConfiguration.chainId.startsWith('0x') &&
!POPULAR_NETWORK_CHAIN_IDS.has(networkConfiguration.chainId as Hex)) ||
NON_EVM_TESTNET_IDS.includes(networkConfiguration.caipChainId),
),
);
```
**Fix**
Switch to `createDeepEqualSelector` so the filtered array is referentially stable when contents are unchanged.
### Threat Modeling Framework
N/A — performance-only change; behavior is preserved, no new data flow / trust boundary / attack surface.
### Acceptance Criteria
- `app/selectors/networkController.test.ts:177` asserts values but not referential stability. Add a test asserting `toBe` across two equal-content states. Profiler: confirm network-management consumers stop re-rendering on unrelated network-state changes.
### References
- File: `app/selectors/networkController.ts:274`
- Source: MetaMask Mobile performance audit — finding `selector-custom-network-configs-by-caip`
- Owner (CODEOWNERS / best-effort): @MetaMask/mobile-core-ux (suggested)
- Status: **UNVALIDATED**
Contributor guide
Research direction
Start with app/selectors/networkController.ts:274 and inspect how selectCustomNetworkConfigurationsByCaipChainId derives its result. Then read app/selectors/networkController.test.ts:177 and add coverage for referential stability across equal-content states. Done means the selector preserves the array reference when contents are unchanged and the selector tests pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend, performance
- Issue type
- Refactor
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100