Skip to content

perf(web): keep react-virtualized out of the entry chunk - #14566

Open
dylanjeffers wants to merge 1 commit into
perf/icon-raster-optimizationfrom
perf/lazy-react-virtualized
Open

perf(web): keep react-virtualized out of the entry chunk#14566
dylanjeffers wants to merge 1 commit into
perf/icon-raster-optimizationfrom
perf/lazy-react-virtualized

Conversation

@dylanjeffers

Copy link
Copy Markdown
Contributor

2 of 4 in a stack reducing the web entry chunk. Based on #14565 — review that first, or use the "Files changed" view which shows only this PR's diff.

What

react-virtualized is ~638 KB of source and was landing in the entry chunk for every visitor through two unrelated edges, neither of which needs it at first paint.

1. FilterButton imported it statically

It only renders VirtualizedOptionsList behind the opt-in virtualized prop — 3 call sites in the whole web app. Split into its own module, loaded on demand behind a Suspense boundary. The menu only renders while open, so the import starts when a virtualized filter menu is actually opened.

FilterButton is reachable from the eager app shell via PaymentMethod, which is why this landed in the entry chunk rather than a lazy page.

Note the as typeof import(...) on the lazy const: React.lazy erases the component's <Value extends string> generic, so it would otherwise resolve to the string instantiation and lose type safety at call sites.

2. A five-line predicate

TransactionDetailsContent imported isChangePositive — a function that checks two enum values — from AudioTransactionsTable. That module imports components/table, which imports react-virtualized. Because the TransactionDetails modal is registered eagerly in registerNiceModals, the entire virtualized table came along for this:

export const isChangePositive = (tx: TransactionDetails) => {
  return (
    tx.transactionType === TransactionType.PURCHASE ||
    tx.method === TransactionMethod.RECEIVE
  )
}

Moved to its own module, re-exported from the table for backwards compatibility.

Verification

react-virtualized confirmed absent from the entry chunk via sourcemap attribution. Web tests pass (152), typecheck and lint clean.

🤖 Generated with Claude Code

react-virtualized is ~638 KB of source and was landing in the entry chunk for
every visitor through two unrelated edges, neither of which needs it at first
paint.

1. harmony's FilterButton imported it statically, but only renders
   VirtualizedOptionsList behind the opt-in `virtualized` prop -- 3 call sites
   across the whole web app. Split into its own module and loaded on demand
   behind a Suspense boundary. The menu only renders while open, so the import
   starts when a virtualized filter menu is actually opened.

   Note the `as typeof import(...)` on the lazy const: React.lazy erases the
   component's `<Value extends string>` generic, so it would otherwise resolve
   to the `string` instantiation and lose type safety at call sites.

2. TransactionDetailsContent imported `isChangePositive` -- a five-line
   predicate over two enum values -- from AudioTransactionsTable. That module
   imports components/table, which imports react-virtualized. Because the
   TransactionDetails modal is registered eagerly in registerNiceModals, the
   whole virtualized table came along for a function that checks whether a
   transaction increases a balance. Moved the predicate to its own module and
   re-exported it from the table for backwards compatibility.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Aug 18, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 19a8e48

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant