4.1 KiB
Bundle Size Optimization
Overview
This document describes the bundle size optimization strategies implemented in CodeForge, focusing on lazy-loading heavy components like Monaco Editor.
Heavy Dependencies Identified
Monaco Editor (~2.5MB)
Monaco Editor is one of the largest dependencies in the application. It's used in:
- CodeEditor component (main code editor)
- LambdaDesigner component (lambda function editor)
- WorkflowDesigner component (inline script editors)
Optimization Strategy
1. Lazy Loading Monaco Editor
Created lazy-loaded wrappers for Monaco Editor:
LazyMonacoEditor (src/components/molecules/LazyMonacoEditor.tsx)
- Full-featured Monaco Editor wrapper for main code editor
- Used in: CodeEditor component
- Includes loading fallback with spinner and status text
- Exports
preloadMonacoEditor()function for manual preloading
LazyInlineMonacoEditor (src/components/molecules/LazyInlineMonacoEditor.tsx)
- Lightweight Monaco Editor wrapper for inline editors
- Used in: LambdaDesigner and WorkflowDesigner components
- Smaller loading fallback for inline contexts
- Configurable height, language, and options
2. Component Registry Integration
Updated src/lib/component-registry.ts to automatically preload Monaco Editor when components that use it are loaded:
CodeEditor: lazyWithPreload(
() => {
preloadMonacoEditor()
return import('@/components/CodeEditor').then(m => ({ default: m.CodeEditor }))
},
'CodeEditor'
)
This ensures Monaco Editor starts loading as soon as the CodeEditor component is requested, improving perceived performance.
3. Suspense Boundaries
All lazy-loaded Monaco Editor instances are wrapped in React Suspense with custom fallback components:
- Shows loading spinner
- Displays "Loading editor..." status text
- Prevents layout shift during loading
Performance Impact
Before Optimization
- Monaco Editor loaded eagerly with initial bundle
- ~2.5MB added to main bundle size
- Slower initial page load for all users
After Optimization
- Monaco Editor loaded only when needed
- Main bundle size reduced by ~2.5MB
- Faster initial page load
- Slight delay when first opening editor (mitigated by preloading)
Usage
For New Components Using Monaco Editor
If you need to add Monaco Editor to a new component:
- For full-page editors, use
LazyMonacoEditor:
import { LazyMonacoEditor } from '@/components/molecules'
<LazyMonacoEditor
file={file}
onChange={handleChange}
/>
- For inline editors, use
LazyInlineMonacoEditor:
import { LazyInlineMonacoEditor } from '@/components/molecules'
<LazyInlineMonacoEditor
height="300px"
defaultLanguage="javascript"
value={code}
onChange={handleChange}
/>
- Update component registry to preload Monaco:
MyComponent: lazyWithPreload(
() => {
preloadMonacoEditor()
return import('@/components/MyComponent').then(m => ({ default: m.MyComponent }))
},
'MyComponent'
)
Other Optimization Opportunities
Future Optimizations
- Chart libraries (recharts, d3) - Consider lazy loading
- react-router-dom - Already using route-based code splitting
- Three.js - If 3D visualization is added, lazy load it
- Heavy utility libraries - Audit lodash/date-fns usage
Monitoring
Use the bundle metrics system to track bundle sizes:
import { bundleMetrics } from '@/lib/bundle-metrics'
// Check current bundle size
const metrics = bundleMetrics.getMetrics()
console.log('Bundle size:', metrics.bundleSize)
Related Files
src/components/molecules/LazyMonacoEditor.tsxsrc/components/molecules/LazyInlineMonacoEditor.tsxsrc/components/molecules/MonacoEditorPanel.tsxsrc/components/CodeEditor.tsxsrc/components/LambdaDesigner.tsxsrc/components/WorkflowDesigner.tsxsrc/lib/component-registry.tssrc/lib/lazy-loader.ts
Best Practices
- Always wrap lazy-loaded components in Suspense
- Provide meaningful loading fallbacks
- Preload heavy components when parent component loads
- Test loading states in slow network conditions
- Monitor bundle size changes in CI/CD