Skip to content

perf(mask): cut popup startup latency - #12469

Merged
guanbinrui merged 2 commits into
developfrom
perf/popup-startup
Sep 8, 2026
Merged

perf(mask): cut popup startup latency#12469
guanbinrui merged 2 commits into
developfrom
perf/popup-startup

Conversation

@swkatmask

Copy link
Copy Markdown
Contributor

Summary

Popup cold-start optimization for the browser-action popup:

  • Code-split the popup app: Wallet/Friends/Trader frames load via route-level lazy, with their route tables moved into lightweight routes.tsx modules so the main chunk no longer pulls the heavy page graphs; routed modals and React Query devtools are lazy as well.
  • Drop React DevTools from the popups entry (kept on long-lived surfaces — dashboard/content script).
  • Parallelize init imports in popups/initialization/index.ts and stop blocking startup on the telemetry ID round-trip.
  • Defer Flow/Solana wallet state init on popup pages until after the EVM state is ready (initWallet({ deferNonEVM }) returns separate initialStateReady / allStatesReady handles; render gates on the former when deferral is active).

Deferral safety (from code review)

  • A persisted non-EVM site provider (Solana/Flow) disables deferral — the root web3 context reads that state before first paint, so rendering ahead of it crashes the popup (getActivatedPluginWeb3Statestate!).
  • The connect-provider check now decodes the query (from=%2Fselect-provider, modal=…) instead of matching raw location.hash, so the fast path actually fires for the wallet-connect onboarding popup.
  • The modal readiness gate (use() in modals.tsx) suspends on a settling variant of allStatesReady — an init failure no longer rethrows during render and nukes the whole popup; modal crashes are contained by an ErrorBoundary.
  • Modals (SingletonModal hosts) stays statically imported: openAndWaitForClose callers hang forever if a host registers late.
  • Trader sub-route paths derive from RoutePaths (const enum, zero runtime cost) instead of duplicated literals; PersonaHeader imports NormalHeader directly instead of the components barrel so WalletBalance/TokenPicker stay out of the main chunk.

Test plan

  • tsc -b packages/mask/popups (full reference graph) passes
  • eslint on all changed files passes
  • CI

Lazy-load route frames, routed modals, and React Query devtools; split the
Wallet/Friends/Trader route tables into lightweight modules; stop loading
React DevTools into the popup entry; parallelize popup init imports and
stop blocking startup on telemetry; defer Flow/Solana wallet state init on
popup pages until after the EVM state is ready.

Deferral safety: keep initializing all states up front when the persisted
site provider is non-EVM or the connect-wallet modal is requested (decode
the percent-encoded modal param first), settle the modal readiness gate
instead of rethrowing during render, keep the SingletonModal hosts mounted
with the first commit, and contain modal crashes in an error boundary.
Derive trader sub-route paths from RoutePaths and import NormalHeader
directly in PersonaHeader so the main chunk stays light.
@vercel

vercel Bot commented Sep 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
book Skipped Skipped Sep 8, 2026 11:00am UTC

Request Review

@guanbinrui
guanbinrui merged commit 4b8ef2a into develop Sep 8, 2026
11 checks passed
@guanbinrui
guanbinrui deleted the perf/popup-startup branch September 8, 2026 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants