Compiler Optimization
Refract's lightweight compiler transforms your code at build time to optimize performance, bundle size, and runtime behavior. The compiler performs static analysis to eliminate unused code, optimize reactivity patterns, and generate efficient JavaScript.
How the compiler works
The Refract compiler operates in three phases:
- Parse phase: Analyzes JSX, component structure, and optic usage
- Transform phase: Applies optimizations and generates efficient code
- Bundle phase: Eliminates dead code and optimizes imports
The compiler integrates with popular build tools like Vite, Webpack, and esbuild through plugins.
Compiler configuration
Configure the compiler through refract.config.js:
export default {
compiler: {
// Enable/disable specific optimizations
optimizations: {
deadCodeElimination: true,
refractionInlining: true,
componentTreeShaking: true,
opticMemoization: true
},
// Development settings
development: {
sourceMap: true,
hotReload: true,
debugInfo: true
},
// Production settings
production: {
minify: true,
stripDebugInfo: true,
aggressiveOptimization: true
}
}
};
Build tool integration
Vite plugin
// vite.config.js
import { defineConfig } from 'vite';
import refract from 'refract/vite';
export default defineConfig({
plugins: [
refract({
// Compiler options
optimizations: {
refractionInlining: true
}
})
]
});
Webpack plugin
// webpack.config.js
const RefractPlugin = require('refract/webpack');
module.exports = {
plugins: [
new RefractPlugin({
optimizations: {
componentTreeShaking: true
}
})
]
};
esbuild plugin
// build.js
import { build } from 'esbuild';
import refract from 'refract/esbuild';
await build({
entryPoints: ['src/main.js'],
plugins: [refract()],
bundle: true,
outdir: 'dist'
});
Optimization techniques
Dead code elimination
The compiler removes unused components, optics, and refractions:
// Before compilation
import { ComponentA, ComponentB, ComponentC } from './components';
const App = () => {
return <ComponentA />; // Only ComponentA is used
};
// After compilation - ComponentB and ComponentC are removed
import { ComponentA } from './components';
const App = () => {
return <ComponentA />;
};
Refraction inlining
Simple refractions are inlined for better performance:
// Before compilation
const SimpleComponent = createComponent(({ lens }) => {
const count = lens.useRefraction(0);
return <div>{count.value}</div>;
});
// After compilation - refraction logic inlined
const SimpleComponent = createComponent(({ lens }) => {
const count$internal = createInlineRefraction(0);
return <div>{count$internal}</div>;
});
Component tree shaking
Unused component methods and lifecycle hooks are removed:
// Before compilation
const Component = createComponent(({ lens }) => {
lens.useEffect(() => {
// This effect is never used
console.log('unused effect');
}, []);
const unusedOptic = useCustomOptic(); // Never referenced
return <div>Hello</div>;
});
// After compilation - unused code removed
const Component = createComponent(({ lens }) => {
return <div>Hello</div>;
});
Optic memoization
Frequently used optics are automatically memoized:
// Before compilation
const ExpensiveComponent = createComponent(() => {
const data = useExpensiveComputation(props.input);
return <div>{data}</div>;
});
// After compilation - automatic memoization added
const ExpensiveComponent = createComponent(() => {
const data = useMemoizedOptic(
() => useExpensiveComputation(props.input),
[props.input]
);
return <div>{data}</div>;
});
Static analysis
The compiler performs comprehensive static analysis to optimize your code:
Dependency tracking
Automatically tracks dependencies between components and optics:
// The compiler analyzes these relationships
const useUserData = createOptic(() => {
const auth = useAuth(); // Dependency: useAuth
const profile = useProfile(); // Dependency: useProfile
return { auth, profile };
});
// And optimizes the dependency graph
Bundle splitting recommendations
The compiler suggests optimal bundle splitting:
✓ Analyzing component dependencies...
✓ Found 3 potential split points:
- /src/components/admin/* (12KB)
- /src/optics/analytics/* (8KB)
- /src/components/dashboard/* (15KB)
Performance insights
Get detailed performance analysis:
RefractCompiler: Performance Analysis
┌─────────────────────┬──────────┬─────────────┐
│ Component │ Size │ Render Cost │
├─────────────────────┼──────────┼─────────────┤
│ UserDashboard │ 2.1KB │ High │
│ ProductList │ 1.8KB │ Medium │
│ Navigation │ 0.9KB │ Low │
└─────────────────────┴──────────┴─────────────┘
Recommendations:
• Consider lazy loading UserDashboard
• Optimize ProductList rendering
Advanced optimizations
Automatic code splitting
Enable automatic component code splitting:
// refract.config.js
export default {
compiler: {
codeSplitting: {
enabled: true,
threshold: '10KB', // Split components larger than 10KB
strategy: 'route-based' // Split by route boundaries
}
}
};
Prefetching strategies
Configure intelligent prefetching:
export default {
compiler: {
prefetch: {
components: 'viewport', // Prefetch when near viewport
optics: 'interaction', // Prefetch on user interaction
data: 'idle' // Prefetch during idle time
}
}
};
Bundle optimization
Fine-tune bundle generation:
export default {
compiler: {
bundling: {
splitChunks: {
vendor: true, // Separate vendor bundle
common: '2KB', // Extract common code > 2KB
async: true // Async chunk loading
},
compression: {
brotli: true,
gzip: true
}
}
}
};
Development mode features
Hot module replacement
The compiler provides sophisticated HMR for Refract components:
// Changes to this component trigger smart updates
const MyComponent = createComponent(({ lens }) => {
const state = lens.useRefraction({ count: 0 });
// State is preserved during HMR
return (
<button onClick={() => state.set({...state.value, count: state.value.count + 1})}>
Count: {state.value.count}
</button>
);
});
Debug information
Enhanced debugging in development:
// Development builds include detailed debug info
const DebugComponent = createComponent(({ lens }) => {
// Compiler adds debug metadata
const state = lens.useRefraction(0, {
__debug: { name: 'DebugComponent.state', location: 'src/Debug.js:5' }
});
return <div>{state.value}</div>;
});
Performance profiling
Built-in performance profiling:
// Enable profiling in development
export default {
compiler: {
development: {
profiling: {
enabled: true,
trackRenders: true,
trackRefractions: true,
reportThreshold: 16 // Report slow renders (>16ms)
}
}
}
};
Production optimizations
Minification strategies
Advanced minification beyond basic JavaScript minification:
export default {
compiler: {
production: {
minification: {
removeDebugCalls: true, // Remove console.log, debugger
inlineConstants: true, // Inline constant values
shortenIdentifiers: true, // Shorten variable names
removeUnusedImports: true // Remove unused imports
}
}
}
};
Runtime optimizations
Optimize runtime performance:
export default {
compiler: {
production: {
runtime: {
batchUpdates: true, // Batch refraction updates
lazyComponents: true, // Lazy load by default
precomputeSelectors: true, // Pre-compute selectors
optimizeLoops: true // Optimize render loops
}
}
}
};
Build analysis
Analyze your production builds:
npx refract analyze
Bundle Analysis:
┌─────────────────┬─────────┬────────┬─────────────┐
│ Chunk │ Size │ Gzipped│ Dependencies│
├─────────────────┼─────────┼────────┼─────────────┤
│ main.js │ 45.2KB │ 12.1KB │ 12 modules │
│ vendor.js │ 156.3KB │ 42.8KB │ 8 modules │
│ async-route.js │ 23.1KB │ 7.2KB │ 6 modules │
└─────────────────┴─────────┴────────┴─────────────┘
Largest Components:
• Dashboard.jsx: 8.3KB (consider code splitting)
• DataGrid.jsx: 6.1KB (optimizable)
Optimization Opportunities:
• 3 duplicate dependencies found
• 2 unused optics detected
Compiler plugins
Create custom compiler plugins:
// plugins/custom-optimization.js
export default function customOptimization() {
return {
name: 'custom-optimization',
transform(code, id) {
if (id.includes('.refract.js')) {
// Custom transformation logic
return {
code: transformedCode,
map: sourceMap
};
}
}
};
}
// refract.config.js
import customOptimization from './plugins/custom-optimization.js';
export default {
compiler: {
plugins: [
customOptimization()
]
}
};
Troubleshooting
Common optimization issues
Bundle size larger than expected
# Analyze bundle composition
npx refract analyze --verbose
# Check for duplicate dependencies
npx refract dedupe
Slow build times
// Reduce optimization levels for development
export default {
compiler: {
development: {
optimizations: {
aggressiveOptimization: false,
componentTreeShaking: false // Skip in development
}
}
}
};
Runtime errors after optimization
# Enable source maps for debugging
npx refract build --source-map
# Disable specific optimizations
npx refract build --no-refraction-inlining
Debug compiler behavior
# Verbose compilation output
npx refract build --verbose
# Save intermediate compilation steps
npx refract build --debug-output=./debug
# Profile compilation performance
npx refract build --profile
The Refract compiler provides powerful optimizations that significantly improve your application's performance and developer experience. By understanding and configuring these optimizations, you can build faster, smaller, and more maintainable applications.