* perf: drastically improve cold-start, bundle size, and streaming performance
Cold-start optimizations:
- main.tsx: Remove blocking await on prefs I/O — render immediately with
defaults, hydrate persisted settings asynchronously. Cuts 50-200ms from
time-to-first-paint.
- bootstrap.ts: Split directory bootstrap into 3 phases:
* Phase 1 (blocking): path, config, provider, session status — minimum
data needed to render UI. Mark status complete after this phase.
path.get and session.status must both succeed; they have no fallback.
* Phase 2 (deferred): agents, commands, mcp, lsp, vcs, questions,
permissions — fetched after first paint without blocking.
* Phase 3 (lazy): session messages — loaded without blocking init.
- App.tsx: Keep identical provider tree before/after init to prevent
full subtree remount when isInitialized flips. FireworksProvider and
VoiceProvider are lightweight shells; overlays deferred until init.
Bundle-size optimizations:
- App.tsx + MainLayout.tsx + VSCodeLayout.tsx: Code-split heavy views
(SettingsView, GitView, DiffView, TerminalView, FilesView, PlanView,
OnboardingScreen, SettingsWindow, MultiRunWindow) with React.lazy.
Views load on demand when user switches panels.
- vite.config.ts: Lower chunkSizeWarningLimit from 1200KB to 500KB.
Streaming render optimizations:
- streaming.ts: Throttle streaming store writes ~60Hz → ~1Hz. Busy-session
only scan (Set, O(1)).
- MessageList.tsx: Lower virtualization threshold 40 → 15.
- ChatMessage.tsx: React.memo with areRenderRelevantMessagesEqual.
- MarkdownRenderer.tsx: React.memo with explicit prop comparators.
* fix: address Greptile review feedback on bootstrap and provider tree
- bootstrap.ts: Tighten Phase 1 error guard. path.get and session.status
must both succeed; they have no global fallback.
- bootstrap.ts: Replace dead .catch() on Promise.allSettled() with .then()
that inspects individual results for errors.
- App.tsx: Keep identical provider tree before/after init to prevent full
subtree remount when isInitialized flips.
* perf: lazy-load heavy dependencies (MarkdownRenderer + CodeMirror languages)
MarkdownRenderer dynamic import:
- Move heavy implementation (marked, react-markdown, beautiful-mermaid,
react-syntax-highlighter, ~1500 lines) to MarkdownRendererImpl.tsx
- Replace MarkdownRenderer.tsx with thin lazy wrapper using React.lazy
- All 11 existing imports work unchanged — no consumer code modified
- Full markdown stack loads on first render of markdown content
CodeMirror language lazy loading:
- languageByExtension.ts: remove static imports for 10+ less-common
language packages (@codemirror/lang-go, lang-rust, lang-sql, etc.)
- Keep only 6 most common languages static: javascript, json, css, html,
markdown, python, shell
- Less common languages return null from languageByExtension, causing
callers to fall back to loadLanguageByExtension which dynamically
loads from @codemirror/language-data
- Reduces initial bundle by ~200KB+ of language parsers
---------
Co-authored-by: Shyamalan Kannan <yabuku@Shyamalans-MacBook-Pro.local>
32 lines
1.1 KiB
TypeScript
32 lines
1.1 KiB
TypeScript
import React from 'react';
|
|
|
|
// Thin lazy wrapper around the heavy MarkdownRenderer implementation.
|
|
// The full implementation (marked, react-markdown, beautiful-mermaid,
|
|
// react-syntax-highlighter, etc.) is loaded on demand, keeping the
|
|
// initial bundle lean.
|
|
|
|
export type { MarkdownVariant } from './MarkdownRendererImpl';
|
|
|
|
|
|
const MarkdownRendererLazy = React.lazy(() =>
|
|
import('./MarkdownRendererImpl').then((m) => ({ default: m.MarkdownRenderer }))
|
|
);
|
|
|
|
const SimpleMarkdownRendererLazy = React.lazy(() =>
|
|
import('./MarkdownRendererImpl').then((m) => ({ default: m.SimpleMarkdownRenderer }))
|
|
);
|
|
|
|
const fallback = <div className="break-words w-full min-w-0" />;
|
|
|
|
export const MarkdownRenderer: React.FC<React.ComponentPropsWithoutRef<typeof MarkdownRendererLazy>> = (props) => (
|
|
<React.Suspense fallback={fallback}>
|
|
<MarkdownRendererLazy {...props} />
|
|
</React.Suspense>
|
|
);
|
|
|
|
export const SimpleMarkdownRenderer: React.FC<React.ComponentPropsWithoutRef<typeof SimpleMarkdownRendererLazy>> = (props) => (
|
|
<React.Suspense fallback={fallback}>
|
|
<SimpleMarkdownRendererLazy {...props} />
|
|
</React.Suspense>
|
|
);
|