Files
Maestro/vite.config.mts
Pedram Amini 03d157ee54 perf: improve startup and runtime performance
Tier 1 performance optimizations for snappier app experience:

1. Lazy-load SettingsModal in App.tsx
   - SettingsModal is ~2.6K lines, now only loaded when settings opened
   - Wrapped in Suspense with conditional rendering

2. Add manual chunk splitting to vite.config.mts
   - Split vendor chunks: react, xterm, markdown, syntax, mermaid, charts, flow, diff
   - Enables better browser caching and smaller initial bundle
   - Heavy visualization libs (mermaid ~500KB, recharts ~400KB, etc.) now in separate chunks

3. Cache static files in web server (staticRoutes.ts)
   - index.html, manifest.json, sw.js now read once and cached
   - Eliminates blocking sync file reads on every web request
   - Improves web/mobile interface responsiveness
2026-02-02 20:46:25 -06:00

124 lines
4.0 KiB
TypeScript

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
import { readFileSync } from 'fs';
import { execSync } from 'child_process';
// Read version from package.json as fallback
const packageJson = JSON.parse(readFileSync(path.join(__dirname, 'package.json'), 'utf-8'));
// Use VITE_APP_VERSION env var if set (during CI builds), otherwise use package.json
const appVersion = process.env.VITE_APP_VERSION || packageJson.version;
// Get the first 8 chars of git commit hash for dev mode
function getCommitHash(): string {
try {
// Note: execSync is safe here - no user input, static git command
return execSync('git rev-parse HEAD', { encoding: 'utf-8' }).trim().slice(0, 8);
} catch {
return '';
}
}
const disableHmr = process.env.DISABLE_HMR === '1';
export default defineConfig(({ mode }) => ({
plugins: [react({ fastRefresh: !disableHmr })],
root: path.join(__dirname, 'src/renderer'),
base: './',
define: {
__APP_VERSION__: JSON.stringify(appVersion),
// Show commit hash only in development mode
__COMMIT_HASH__: JSON.stringify(mode === 'development' ? getCommitHash() : ''),
// Explicitly define NODE_ENV for React and related packages
'process.env.NODE_ENV': JSON.stringify(mode),
},
resolve: {
alias: {
// In development, use wdyr.dev.ts which loads why-did-you-render
// In production, use wdyr.ts which is empty (prevents bundling the library)
'./wdyr':
mode === 'development'
? path.join(__dirname, 'src/renderer/wdyr.dev.ts')
: path.join(__dirname, 'src/renderer/wdyr.ts'),
},
},
esbuild: {
// Strip console.* and debugger in production builds
drop: mode === 'production' ? ['console', 'debugger'] : [],
},
build: {
outDir: path.join(__dirname, 'dist/renderer'),
emptyOutDir: true,
rollupOptions: {
output: {
// Manual chunking for better caching and code splitting
manualChunks: (id) => {
// React core in its own chunk for optimal caching
if (id.includes('node_modules/react-dom')) {
return 'vendor-react';
}
if (id.includes('node_modules/react/') || id.includes('node_modules/react-is')) {
return 'vendor-react';
}
if (id.includes('node_modules/scheduler')) {
return 'vendor-react';
}
// Terminal (xterm) in its own chunk - large and not immediately needed
if (id.includes('node_modules/xterm')) {
return 'vendor-xterm';
}
// Markdown processing libraries
if (
id.includes('node_modules/react-markdown') ||
id.includes('node_modules/remark-') ||
id.includes('node_modules/rehype-') ||
id.includes('node_modules/unified') ||
id.includes('node_modules/unist-') ||
id.includes('node_modules/mdast-') ||
id.includes('node_modules/hast-') ||
id.includes('node_modules/micromark')
) {
return 'vendor-markdown';
}
// Syntax highlighting (large)
if (
id.includes('node_modules/react-syntax-highlighter') ||
id.includes('node_modules/prismjs') ||
id.includes('node_modules/refractor')
) {
return 'vendor-syntax';
}
// Heavy visualization libraries (lazy-loaded components)
if (id.includes('node_modules/mermaid')) {
return 'vendor-mermaid';
}
if (id.includes('node_modules/recharts') || id.includes('node_modules/d3-')) {
return 'vendor-charts';
}
if (id.includes('node_modules/reactflow') || id.includes('node_modules/@reactflow')) {
return 'vendor-flow';
}
// Diff viewer
if (id.includes('node_modules/react-diff-view') || id.includes('node_modules/diff')) {
return 'vendor-diff';
}
// Return undefined to let Rollup handle other modules automatically
return undefined;
},
},
},
},
server: {
port: process.env.VITE_PORT ? parseInt(process.env.VITE_PORT, 10) : 5173,
hmr: !disableHmr,
// Disable file watching entirely when HMR is disabled to prevent any reloads
watch: disableHmr ? null : undefined,
},
}));