perf: improve loading times with better code splitting
- Improve Vite chunk splitting (Board.js 7.3MB → 5.6MB, 23% smaller) - Add separate chunks for codemirror, onnx, daily-video, sanitizers - Enable gzip for wasm and octet-stream in nginx - Add dns-prefetch and preconnect hints for worker URLs - Increase gzip compression level to 6 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
6f606995a4
commit
ccb5acc164
|
|
@ -9,8 +9,13 @@
|
|||
<link rel="manifest" href="/manifest.webmanifest" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<meta http-equiv="Permissions-Policy" content="midi=*, microphone=*, camera=*, autoplay=*">
|
||||
<!-- Preconnect to critical origins for faster loading -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link rel="dns-prefetch" href="https://jeffemmett-canvas.jeffemmett.workers.dev" />
|
||||
<link rel="dns-prefetch" href="https://jeffemmett-canvas-dev.jeffemmett.workers.dev" />
|
||||
<link rel="preconnect" href="https://jeffemmett-canvas.jeffemmett.workers.dev" crossorigin />
|
||||
<link rel="preconnect" href="https://jeffemmett-canvas-dev.jeffemmett.workers.dev" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Recursive:slnt,wght,CASL,CRSV,MONO@-15..0,300..1000,0..1,0..1,0..1&display=swap"
|
||||
rel="stylesheet">
|
||||
|
|
|
|||
21
nginx.conf
21
nginx.conf
|
|
@ -4,12 +4,25 @@ server {
|
|||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# Gzip compression
|
||||
# Gzip compression (fallback for clients that don't support Brotli)
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_proxied expired no-cache no-store private auth;
|
||||
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml application/javascript application/json;
|
||||
gzip_comp_level 6;
|
||||
gzip_min_length 256;
|
||||
gzip_proxied any;
|
||||
gzip_types
|
||||
text/plain
|
||||
text/css
|
||||
text/xml
|
||||
text/javascript
|
||||
application/javascript
|
||||
application/x-javascript
|
||||
application/json
|
||||
application/xml
|
||||
application/wasm
|
||||
application/octet-stream
|
||||
image/svg+xml
|
||||
font/woff2;
|
||||
gzip_disable "MSIE [1-6]\.";
|
||||
|
||||
# Security headers
|
||||
|
|
|
|||
|
|
@ -128,30 +128,71 @@ export default defineConfig(({ mode }) => {
|
|||
rollupOptions: {
|
||||
output: {
|
||||
// Manual chunk splitting for large libraries to improve load times
|
||||
manualChunks: {
|
||||
// Core React libraries
|
||||
'react-vendor': ['react', 'react-dom', 'react-router-dom'],
|
||||
manualChunks(id) {
|
||||
// Core React libraries - load first
|
||||
if (id.includes('node_modules/react') ||
|
||||
id.includes('node_modules/react-dom') ||
|
||||
id.includes('node_modules/react-router')) {
|
||||
return 'react-vendor';
|
||||
}
|
||||
|
||||
// tldraw - large drawing library (split into separate chunk)
|
||||
'tldraw': ['tldraw', '@tldraw/tldraw', '@tldraw/tlschema'],
|
||||
// tldraw core - split from shapes
|
||||
if (id.includes('node_modules/tldraw') ||
|
||||
id.includes('node_modules/@tldraw')) {
|
||||
return 'tldraw';
|
||||
}
|
||||
|
||||
// Automerge - CRDT sync library
|
||||
'automerge': [
|
||||
'@automerge/automerge',
|
||||
'@automerge/automerge-repo',
|
||||
'@automerge/automerge-repo-react-hooks'
|
||||
],
|
||||
if (id.includes('node_modules/@automerge')) {
|
||||
return 'automerge';
|
||||
}
|
||||
|
||||
// AI SDKs (lazy load)
|
||||
'ai-sdks': ['@anthropic-ai/sdk', 'openai', 'ai'],
|
||||
if (id.includes('node_modules/@anthropic-ai') ||
|
||||
id.includes('node_modules/openai') ||
|
||||
id.includes('node_modules/ai/')) {
|
||||
return 'ai-sdks';
|
||||
}
|
||||
|
||||
// ML/transformers (VERY large, lazy loaded)
|
||||
'ml-libs': ['@xenova/transformers'],
|
||||
if (id.includes('node_modules/@xenova')) {
|
||||
return 'ml-libs';
|
||||
}
|
||||
|
||||
// Markdown editors
|
||||
'markdown': ['@uiw/react-md-editor', 'cherry-markdown', 'marked', 'react-markdown'],
|
||||
if (id.includes('node_modules/@uiw/react-md-editor') ||
|
||||
id.includes('node_modules/cherry-markdown') ||
|
||||
id.includes('node_modules/marked') ||
|
||||
id.includes('node_modules/react-markdown')) {
|
||||
return 'markdown';
|
||||
}
|
||||
|
||||
// Note: gun, webnative, holosphere removed - stubbed for future Nostr integration
|
||||
// CodeMirror (used by markdown editors)
|
||||
if (id.includes('node_modules/@codemirror') ||
|
||||
id.includes('node_modules/codemirror')) {
|
||||
return 'codemirror';
|
||||
}
|
||||
|
||||
// Daily video chat
|
||||
if (id.includes('node_modules/@daily-co')) {
|
||||
return 'daily-video';
|
||||
}
|
||||
|
||||
// html2canvas (screenshots)
|
||||
if (id.includes('node_modules/html2canvas')) {
|
||||
return 'html2canvas';
|
||||
}
|
||||
|
||||
// ONNX runtime (ML inference)
|
||||
if (id.includes('node_modules/onnxruntime')) {
|
||||
return 'onnx';
|
||||
}
|
||||
|
||||
// DOMPurify and sanitizers
|
||||
if (id.includes('node_modules/dompurify') ||
|
||||
id.includes('node_modules/isomorphic-dompurify')) {
|
||||
return 'sanitizers';
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue