Skip to content

refactor: PerpsSection performance improvements#26973

Merged
PatrykLucka merged 10 commits into
mainfrom
perps-section-perf-audit
Mar 6, 2026
Merged

refactor: PerpsSection performance improvements#26973
PatrykLucka merged 10 commits into
mainfrom
perps-section-perf-audit

Conversation

@PatrykLucka
Copy link
Copy Markdown
Contributor

@PatrykLucka PatrykLucka commented Mar 4, 2026

Description

Perpetuals section – performance and stability

Performance audit follow-up: fewer re-renders, no redundant subscriptions on the homepage, and safer selectors/hooks.

Homepage Perps

  • Carousel: static data only – Removed live price subscription from PerpsMarketTileCard. Tiles use the market snapshot from usePerpsMarkets() (price, change24hPercent). No WebSocket per symbol on the homepage; fewer subscriptions and re-renders.
  • Tile card – Dropped livePrices / disableLivePrices; component always uses static market data. Removed TileCardWithLivePrices and usePerpsLivePrices usage there.
  • Position rowsPositionCardItem with a positionDisplayKey (symbol, entryPrice, size, unrealizedPnl, takeProfitPrice, stopLossPrice) and custom React.memo compare so only cards whose display data changed re-render on stream updates.
  • Defensive defaults?? [] for watchlist/carousel arrays and carouselSymbols so selectors or partial state (e.g. E2E/minimal fixtures) never pass undefined into hooks or .map().
  • SparklinesuseHomepageSparklines: guard candleData?.candles (fixes E2E crash when candles is undefined), safeSymbols so symbols is never undefined, and microtask batching so multiple symbol callbacks trigger one state update.

Perps selectors & components

  • perpsController selectors – Try/catch and defaults when state is missing or partial (e.g. before Engine init or in E2E). Avoids calling package selectors with undefined and normalizes return values (?? [] / default prefs).
  • PerpsCard / PerpsPositionCard – Wrapped with React.memo to avoid unnecessary re-renders when parent updates.
  • usePerpsMarketListViewsavedSortPreference.optionId cast to SortOptionId for type safety.

Tests

  • PerpsSection – Tests for positionDisplayKey (stable key, optional fields, TP/SL, same key when only non-display fields differ).
  • PerpsMarketTileCard – Removed live-price mock and related test; added “displays market change24hPercent” for static data.
  • useHomepageSparklines – Async act where needed for microtask-flushed updates.
  • HomepageuseFocusEffect mock simplified (invoke callback once).

Changelog

CHANGELOG entry: null

Related issues

Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-512

Manual testing steps

Feature: Perpetuals section performance and data freshness

  Scenario: Homepage carousel shows static data and does not re-render on a timer
    Given the user is on the homepage with no open perps positions/orders
    When the trending perps carousel is visible
    Then the section title and carousel tiles show market data (symbol, price, 24h change)
    And the section does not re-render every few seconds (observe in React DevTools or logs)
    And navigating away and back to the homepage refreshes carousel data

  Scenario: Homepage positions list re-renders only when position data changes
    Given the user has open perps positions and is on the homepage
    When the positions stream emits updates (e.g. every 5s)
    Then the section title does not flicker or re-render
    And only position cards whose data actually changed re-render

  Scenario: Pull-to-refresh updates markets and sparklines
    Given the user is on the homepage with the Perps section visible
    When the user triggers the section refresh (e.g. pull-to-refresh if wired)
    Then market data and sparklines are refetched

Screenshots/Recordings

Before

After

Pre-merge author checklist

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

Medium Risk
Moderate risk because it changes rendering/memoization behavior and introduces a module-level TTL cache that could cause stale data or missed UI updates if the cache keys/comparators are wrong.

Overview
Perps homepage performance improvements. Position/order rows now avoid unnecessary re-renders via React.memo (including a new positionDisplayKey comparator) and null-safe carousel list handling; PerpsCard/PerpsPositionCard are also exported as memoized components.

Trending carousel simplification. PerpsMarketTileCard no longer subscribes to live prices and drops the disableLivePrices prop; it always renders from the passed market snapshot, and tests are updated accordingly.

Fewer update storms. useHomepageSparklines batches per-symbol candle callbacks into a single microtask-flushed state update, and related tests are adjusted.

Stability + networking. Perps Redux selectors now defensively default/guard against missing controller state, and useRampTokens adds a 5-minute, module-level cache that deduplicates identical requests (including in-flight), with comprehensive cache behavior tests.

Written by Cursor Bugbot for commit 49cecc3. This will update automatically on new commits. Configure here.

@PatrykLucka PatrykLucka self-assigned this Mar 4, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 4, 2026

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 team-mobile-ux Mobile UX team label Mar 4, 2026
@github-actions github-actions Bot added the size-L label Mar 4, 2026
@PatrykLucka PatrykLucka marked this pull request as ready for review March 4, 2026 11:01
@PatrykLucka PatrykLucka requested review from a team as code owners March 4, 2026 11:01
Comment thread app/components/Views/Homepage/Sections/Perpetuals/PerpsSection.tsx
Comment thread app/components/UI/Ramp/hooks/useRampTokens.ts Outdated
@PatrykLucka PatrykLucka force-pushed the perps-section-perf-audit branch 4 times, most recently from 9663f9c to 8b07253 Compare March 5, 2026 09:11
Comment thread app/components/Views/Homepage/Sections/Perpetuals/PerpsSection.tsx Outdated
@PatrykLucka PatrykLucka force-pushed the perps-section-perf-audit branch from 8b07253 to d547c40 Compare March 5, 2026 12:36
@github-actions github-actions Bot added size-XL and removed size-L labels Mar 5, 2026
@github-actions github-actions Bot added size-L and removed size-XL labels Mar 5, 2026
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Comment thread app/components/Views/Homepage/Sections/Perpetuals/PerpsSection.tsx
Comment thread app/components/Views/Homepage/Homepage.test.tsx Outdated
gambinish
gambinish previously approved these changes Mar 5, 2026
@PatrykLucka PatrykLucka enabled auto-merge March 5, 2026 15:44
@amitabh94
Copy link
Copy Markdown
Contributor

Ramps team already has caching on the controller for all ramp endpoints getting hit through the client.
It is currently sitting behind a feature flag which we plan to launch in the coming week.

Do you think we still want to do this as this might be redundant in a week?

@PatrykLucka PatrykLucka removed the request for review from a team March 6, 2026 09:30
@PatrykLucka
Copy link
Copy Markdown
Contributor Author

Ramps team already has caching on the controller for all ramp endpoints getting hit through the client. It is currently sitting behind a feature flag which we plan to launch in the coming week.

Do you think we still want to do this as this might be redundant in a week?

Nope, it's a very small improvement, so it can easily wait for a more refined solution from your team 👍

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 6, 2026

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokePerps, SmokeWalletPlatform
  • Selected Performance tags: @PerformancePreps
  • Risk Level: medium
  • AI Confidence: 90%
click to see 🤖 AI reasoning details

E2E Test Selection:
This PR contains performance optimizations and defensive coding improvements for the Perps (Perpetuals) feature:

  1. Perps Controller Selectors (CRITICAL): Added defensive try-catch wrappers and null checks to prevent crashes when PerpsController state is missing or partial. This is a safety improvement that shouldn't change behavior but protects against edge cases.

  2. React.memo Optimizations: Added React.memo to PerpsCard, PerpsPositionCard, and PerpsMarketTileCard components to reduce unnecessary re-renders.

  3. PerpsMarketTileCard: Removed live price WebSocket subscription - now uses static market data only. This is a significant change that simplifies the component but changes its behavior (no more live price updates in tile cards).

  4. PerpsSection: Added memoized PositionCardItem with custom comparison function and null-safe array operations.

  5. useHomepageSparklines: Added microtask-based flush to batch state updates for better performance.

Tag Selection Rationale:

  • SmokePerps: Required because changes directly affect Perps components (PerpsCard, PerpsPositionCard, PerpsMarketTileCard), Perps selectors, and Perps hooks. The Add Funds flow and balance verification tests will validate the core functionality still works.
  • SmokeWalletPlatform: Required because PerpsSection is embedded in the Trending tab on the homepage. Per the tag description: "Perps is also a section inside the Trending tab (SmokeWalletPlatform); changes to Perps views affect Trending."

The changes are defensive and performance-focused, but the removal of live prices from PerpsMarketTileCard is a behavioral change that warrants testing. The defensive null checks in selectors could affect how the app behaves during initialization or with minimal E2E fixtures.

Performance Test Selection:
The PR contains multiple performance optimizations specifically for Perps components: React.memo wrappers on PerpsCard, PerpsPositionCard, and PerpsMarketTileCard; a memoized PositionCardItem with custom comparison function; and microtask-based state batching in useHomepageSparklines. These changes are designed to reduce re-renders and improve rendering performance of the Perps UI. The @PerformancePreps tag covers perps market loading, position management, and add funds flow - all areas affected by these optimizations.

View GitHub Actions results

@github-actions github-actions Bot added size-M and removed size-L labels Mar 6, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 6, 2026

⚠️ E2E Fixture Validation — Structural changes detected

Category Count
New keys 68
Missing keys 11
Type mismatches 1
Value mismatches 9 (informational)

The committed fixture schema is out of date. To update, comment:

@metamaskbot update-mobile-fixture

View full details | Download diff report

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Mar 6, 2026

@PatrykLucka PatrykLucka added this pull request to the merge queue Mar 6, 2026
Merged via the queue into main with commit a290214 Mar 6, 2026
97 checks passed
@PatrykLucka PatrykLucka deleted the perps-section-perf-audit branch March 6, 2026 11:48
@github-actions github-actions Bot locked and limited conversation to collaborators Mar 6, 2026
@metamaskbot metamaskbot added the release-7.70.0 Issue or pull request that will be included in release 7.70.0 label Mar 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.70.0 Issue or pull request that will be included in release 7.70.0 size-M team-mobile-ux Mobile UX team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants