[Improvement]: Code-split Monaco, Marketplace, AI chat, terminal, and Settings via next/dynamic#177
Open
matiaspalmac wants to merge 1 commit intoTrixtyAI:mainfrom
Open
Conversation
…Settings The desktop shell was pulling every heavy surface into the initial JavaScript bundle even though most of them are only reachable after the user has made a deliberate choice (open a file, open the AI panel, open the terminal, open the marketplace, open Settings). Route heavy modules through `next/dynamic` and dynamic `import()` so they ship as their own chunks and arrive only when needed: - `page.tsx` — `EditorArea`, `BottomPanel`, `RightPanelSlot`, and `SettingsView` are now dynamic imports (`ssr: false` because this app is always client-rendered inside Tauri and several components touch `window` at module scope). - `EditorArea.tsx` — `MonacoEditor` and `MarketplaceView` are now dynamic imports. Monaco's loader config runs inside the lazy factory so the `/vs` path is still wired up before first mount. - `PluginManager.ts` — built-in addons (AI assistant, Git explorer, five language addons) switched from top-level `import * as` to `await import()` inside `bootstrap()`. AiChat (which pulls react-markdown + remark-gfm) and GitExplorer (picomatch + git dialogs) are the biggest wins; language addons are kicked off in parallel so one slow chunk doesn't block the rest. No behavior change for end users — same panels, same interactions, just smaller first-paint cost. `next build` still produces a clean static page. Closes TrixtyAI#81
|
Thanks for the contribution! I'll review it as soon as possible. If you have still changes, please mark this PR as draft and all reviews will be cancelled. Tests reviews will be re-run only when the PR is marked as ready for review. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The desktop shell was pulling every heavy surface into the initial JavaScript bundle even though most of them are only reachable after the user makes a deliberate choice — open a file, open the AI panel, open the terminal, open the marketplace, open Settings. The result is a larger-than-necessary first paint, especially on cold startups where nothing except the title bar and activity bar is actually visible.
This PR routes the heavy modules through
next/dynamicand plainawait import()so they land in their own chunks and arrive only when needed.Related Issue
Closes #81
Change
page.tsx—EditorArea,BottomPanel,RightPanelSlot, andSettingsVieware nownext/dynamic({ ssr: false })imports.ssr: falseis correct for this app: it's always client-rendered inside Tauri and several of these components touchwindowat module scope.EditorArea.tsx—MonacoEditor(the ~1.5 MB gzipped beast, plus language workers) andMarketplaceVieware now dynamic imports. Monaco'sloader.config({ paths: { vs: "/vs" } })is invoked inside the lazy factory so the asset path is wired up before the editor's first mount.PluginManager.ts— built-in addons (AI assistant, Git explorer, and the five language addons) switched from top-levelimport * astoawait import()insidebootstrap(). Language addons are kicked off in parallel so one slow chunk doesn't block the rest.Trade-offs
next/dynamicwithout aloadingfallback shows nothing for a beat while the chunk resolves. For panels that are conditionally rendered behind a user action this is consistent with how they already appeared (nothing → panel). Introducing bespoke skeletons would be a follow-up that belongs with the wider UX pass.ssr: falseeverywhere — intentional. Monaco'sloader.config, xterm's imports, and Tauri-specific APIs assume a real browser. A hybrid "sometimes SSR" path would save nothing here and cost complexity.Verification
pnpm --filter @trixty/desktop lintpasses clean.npx tsc --noEmitpasses clean.pnpm --filter @trixty/desktop build(Next 16 with Turbopack) compiles the production build and emits the static page without errors.Checklist