Skip to content

frontend: code-split TON Connect out of the entry chunk (672 kB → 237 kB) - #314

Merged
chiliec merged 1 commit into
mainfrom
perf/frontend-code-split
Sep 9, 2026
Merged

frontend: code-split TON Connect out of the entry chunk (672 kB → 237 kB)#314
chiliec merged 1 commit into
mainfrom
perf/frontend-code-split

Conversation

@chiliec

@chiliec chiliec commented Sep 9, 2026

Copy link
Copy Markdown
Member

What

The @tonconnect/{ui,sdk} stack was ~430 kB of the 672 kB entry bundle, downloaded on every boot even though the boot path (title → login → hub) never touches a wallet. Vite warned about the 500 kB chunk on every build.

  • TonConnectUIProvider moves out of main.tsx into a lazy TonConnectGate, mounted by App.tsx only around the screens that need it (wallet, earn, scan without a bound wallet). Sticky once mounted — unmounting the provider would destroy the TonConnectUI instance and the wallet connection with it.
  • WalletScreen and EarnPanel are lazy too: a single static import of either re-inlines the whole stack.
  • shortAddress moved to format.tsPassScan and HeroTab imported it from WalletScreen, which was a hidden bridge back into the entry chunk.
  • The chunk is prefetched right after login resolves, so pressing CONNECT doesn't wait on a cold fetch.

Numbers

before after
entry 672.60 kB 236.65 kB
entry gzip 200.42 kB 73.09 kB

Async chunks: lib 428.67 kB, WalletScreen 3.59, EarnPanel 3.29, useWalletBind 1.04, TonConnectGate 0.27.

Guard

scripts/check-bundle.mjs fails the build if the entry chunk exceeds 320 kB. build:frontend runs it, so build:all (already in CI) picks it up — vite only warns at 500 kB and a warning doesn't fail anything. Mutation-tested: restoring the static EarnPanel import pushes the entry to 653.6 kB and the guard exits 1.

Testing

lint / typecheck / build:all / 628 backend tests green. No frontend test infra exists — the lazy provider mount wants a manual pass on staging (connect wallet, scan pass, EARN tab).

… kB)

The @tonconnect/{ui,sdk} stack was ~430 kB of the 672 kB entry bundle, loaded
on every boot even though the title → login → hub path never touches a wallet.

TonConnectUIProvider moves out of main.tsx into a lazy TonConnectGate that
App.tsx mounts only around the screens that need it (wallet, earn, scan
without a bound wallet), sticky once mounted so the TonConnectUI instance and
its connection survive navigation. WalletScreen and EarnPanel are lazy too —
a single static import of either re-inlines the whole stack. shortAddress
moved to format.ts for the same reason: PassScan and HeroTab imported it from
WalletScreen, which was a bridge back into the entry chunk.

The chunk is prefetched right after login resolves, so pressing CONNECT does
not wait on a cold fetch.

scripts/check-bundle.mjs guards the split in CI (build:frontend runs it,
build:all picks it up) — vite only warns at 500 kB and a warning does not
fail a build.

Entry 672.60 → 236.65 kB (gzip 200.42 → 73.09).
@chiliec
chiliec merged commit 7e243a1 into main Sep 9, 2026
3 checks passed
@chiliec
chiliec deleted the perf/frontend-code-split branch September 9, 2026 05:23
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.

1 participant