pendulum-chain / pendulum-chain/vortex
[Chore] Eliminate blockchain vendors from landing page initial load
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 6
- Forks
- 5
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 33
Description
User Story
As a first-time visitor to the Vortex landing page
I want the page to load and animate quickly
So that I get a smooth first impression of the product without waiting for blockchain infrastructure I haven't asked for yet
Acceptance Criteria
- Landing page initial JS payload is ≤ 400 kB gzip (entry chunk + all eagerly-loaded chunks combined)
- No static import chain from
main.tsxreacheswagmi,@polkadot,stellar-sdk,@walletconnect, or@reownat build time — verified via bundle analyser (rollup-plugin-visualizeris already configured invite.config.ts) -
@vortexfi/sharedbrowser export resolves to a pre-built ESM artifact, not raw TypeScript source (./src/index.ts) - Landing page animations are visually smooth on a simulated mid-tier mobile device (Chrome DevTools 4× CPU throttle, no jank on hero section)
Additional Context
Size: M
Findings
The landing page currently eagerly loads ~7 MB of blockchain vendor code (wagmi, @walletconnect, @polkadot, stellar-sdk) on every visit, including users who never open the widget. This causes sluggish initial render and janky hero animations.
Investigation revealed five root causes:
-
manualChunksmakesvendor-evma shared runtime host. Splitting vendors by package name forces Rollup to assign any internally-shared utility to the matched vendor chunk. Every marketing page route ends up with a staticimporttovendor-evmat build time — including components likeAnimatedTitle— even though they have no real wagmi dependency in source. This is a Rollup artifact of the chunking strategy, not a source-level problem. -
manualChunksincreases total size vs the original monolith. Before chunking, Rollup deduplicated everything once. Named chunks introduce cross-chunk import overhead and prevent deduplication, making total bytes larger than the original 8 MB bundle. -
@vortexfi/sharedresolves to raw TypeScript source. Thebrowserexport condition inpackages/shared/package.jsonpoints to./src/index.ts— a fullexport *barrel that includesservices/(polkadot, stellar, wagmi helpers). Even withsideEffects: false, the barrel is too wide for Rollup to tree-shake effectively when used from the landing page. -
services/api/index.tsis an unguarded barrel. It re-exportsmoonbeam.service,polkadot.service, andpendulum.service. Any landing page component that imports from this barrel (e.g.useFeeComparisonData→PriceService) transitively pulls in wagmi and polkadot. -
The lazy boundary is on the React component, not the module graph.
widget.lazy.tsxdefers the component render but the heavy vendor transitive deps remain statically reachable from the entry chunk via shared Rollup intermediate chunks.
Hints
FeeComparisonon the landing page importsuseNetwork(→contexts/network→wagmi) anduseEventsContext(→contexts/events→ same chain). These should be removed —FeeComparisononly needs EVM rates and has no real dependency on wallet state.useFeeComparisonDataimportsPriceServicevia theservices/apibarrel. Changing it to import directly fromservices/api/price.servicesevers the polkadot/moonbeam chain for that component.packages/shared/package.jsonshould have"sideEffects": falseto allow Rollup to tree-shake the barrel. Combined with pointingbrowserto./dist/browser/index.js(pre-built ESM), this should eliminate the raw source barrel problem.rollup-plugin-visualizeris already configured invite.config.ts— use it after each change to verify the import graph.
Desired Approach
- Remove
manualChunksentirely fromvite.config.ts. Let Rollup manage chunking automatically once the module graph is clean. - Audit the static import graph from
main.tsx— trace every path that reacheswagmi,@polkadot,stellar-sdk,@walletconnect, or@reownand cut each one. - Sever context imports from marketing components — no file outside
widget.lazy.tsxand its descendants should importuseNetwork,useEventsContext, or any hook that chains to a blockchain SDK. - Replace barrel imports with direct imports in any file reachable from the landing page (e.g.
services/api/price.serviceinstead ofservices/api). - Fix
@vortexfi/sharedbrowser export — point it to./dist/browser/index.jsand add"sideEffects": false. Rebuild shared before testing the frontend. - Validate with the bundle analyser — the landing page preload manifest should list zero chunks that transitively import a blockchain vendor.
Affected surfaces (per CONTEXT.md): Initial bundle tier, widget.lazy.tsx boundary, MarketingLayout, FeeComparison section, @vortexfi/shared package exports.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with vite.config.ts and trace the static import graph from main.tsx, including MarketingLayout, FeeComparison, useFeeComparisonData, and widget.lazy.tsx. Inspect packages/shared/package.json and use the configured rollup-plugin-visualizer to compare the landing-page graph before and after changes. Done means the stated vendor imports are absent from eager chunks, the shared browser export uses its built ESM artifact, the payload is at most 400 kB gzip, and hero animations remain smooth under 4× CPU throttling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, rollup, typescript, vite
- Domain
- build-system, frontend, performance
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 42/100