JavaScript Internals (521 Qs)•Part 8: Modern JavaScript APIs, WeakRef, Proxy & Performance (464 - 521)
What are the best practices for optimizing JavaScript bundle size?
Optimizing bundle size improves load times, reduces bandwidth usage, and enhances user experience, especially on slow networks.
1. Code splitting:
javascript
// Split by route
const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));
// Split by feature
button.addEventListener('click', async () => {
const module = await import('./features/analytics.js');
module.trackEvent('button_click');
});
2. Tree shaking (remove unused code):
javascript
// Bad - imports entire library
import _ from 'lodash';
_.debounce(fn, 300);
// Good - imports only what's needed
import debounce from 'lodash/debounce';
debounce(fn, 300);
// Even better - use ES modules
import { debounce } from 'lodash-es';
3. Minimize dependencies:
javascript
// Before - 50KB library for date formatting
import moment from 'moment';
moment().format('YYYY-MM-DD');
// After - native Intl API (0KB)
new Intl.DateTimeFormat('en-CA').format(new Date());
// Or small alternative - 2KB
import { format } from 'date-fns';
format(new Date(), 'yyyy-MM-dd');
4. Use production builds:
javascript
// package.json
{
"scripts": {
"build": "NODE_ENV=production webpack --mode production"
}
}
// React automatically removes development code
if (process.env.NODE_ENV !== 'production') {
console.log('Development mode');
}
5. Compress and minify:
javascript
// webpack.config.js
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimize: true,
minimizer: [new TerserPlugin({
terserOptions: {
compress: {
drop_console: true, // Remove console.logs
drop_debugger: true
}
}
})]
}
};
6. Analyze bundle:
bash
# Install bundle analyzer
npm install --save-dev webpack-bundle-analyzer
# Run analysis
npx webpack-bundle-analyzer stats.json
7. Remove duplicate dependencies:
javascript
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
};
8. Use CDN for large libraries:
html
<!-- Load from CDN instead of bundling -->
<script src="https://cdn.jsdelivr.net/npm/react@18/umd/react.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-dom@18/umd/react-dom.production.min.js"></script>
9. Defer non-critical JavaScript:
html
<!-- Critical - inline or load immediately -->
<script src="critical.js"></script>
<!-- Non-critical - defer -->
<script src="analytics.js" defer></script>
<script src="social-widgets.js" async></script>
10. Remove dead code:
javascript
// Use /* #__PURE__ */ comment for tree shaking
const result = /* #__PURE__ */ expensiveOperation();
// Configure webpack to remove unused exports
module.exports = {
optimization: {
usedExports: true,
sideEffects: false
}
};
11. Optimize images and assets:
javascript
// Use image-webpack-loader
module.exports = {
module: {
rules: [{
test: /\.(png|jpe?g|gif|svg)$/,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
mozjpeg: { quality: 75 },
pngquant: { quality: [0.65, 0.9] }
}
}
]
}]
}
};
12. Enable gzip/brotli compression:
javascript
// Server-side compression (Express)
const compression = require('compression');
app.use(compression());
// Build-time compression
const CompressionPlugin = require('compression-webpack-plugin');
plugins: [
new CompressionPlugin({
algorithm: 'brotliCompress',
test: /\.(js|css|html|svg)$/,
threshold: 10240,
minRatio: 0.8
})
]