11. Оптимизация бандла
Оптимизация Webpack — это искусство достижения баланса между размером бандла, скоростью загрузки и скоростью сборки. В production режиме Webpack автоматически включает ряд оптимизаций, но для максимального результата нужна ручная настройка.
Что происходит в mode: ‘production’
Заголовок раздела «Что происходит в mode: ‘production’»// Автоматически включается в production:optimization: { minimize: true, // Минификация JS minimizer: [new TerserPlugin()], // Через TerserPlugin moduleIds: 'deterministic', // Стабильные ID модулей chunkIds: 'deterministic', concatenateModules: true, // Scope hoisting usedExports: true, // Для tree shaking mangleWasmImports: false,}TerserPlugin — минификация JavaScript
Заголовок раздела «TerserPlugin — минификация JavaScript»npm install --save-dev terser-webpack-pluginconst TerserPlugin = require('terser-webpack-plugin');
optimization: { minimize: true, minimizer: [ new TerserPlugin({ parallel: true, // Многопоточная минификация terserOptions: { compress: { drop_console: true, // Удалить console.log в production drop_debugger: true, pure_funcs: ['console.info', 'console.debug'], }, mangle: { safari10: true, // Совместимость с Safari 10 }, format: { comments: false, // Удалить комментарии }, }, extractComments: false, // Не создавать .txt с лицензиями }), ],}CssMinimizerPlugin — минификация CSS
Заголовок раздела «CssMinimizerPlugin — минификация CSS»npm install --save-dev css-minimizer-webpack-pluginconst CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
optimization: { minimize: true, minimizer: [ new TerserPlugin(), new CssMinimizerPlugin({ minimizerOptions: { preset: ['default', { discardComments: { removeAll: true }, normalizeWhitespace: true, colormin: true, }], }, }), ],}SplitChunks — детальная настройка
Заголовок раздела «SplitChunks — детальная настройка»optimization: { splitChunks: { chunks: 'all', maxInitialRequests: 30, maxAsyncRequests: 30, minSize: 20000, // 20 KB — минимальный размер чанка maxSize: 244000, // 244 KB — разбить на меньшие части cacheGroups: { // Все node_modules в один vendor чанк defaultVendors: { test: /[\\/]node_modules[\\/]/, priority: -10, reuseExistingChunk: true, name: 'vendors', }, // React в отдельный чанк (кешируется долго) react: { test: /[\\/]node_modules[\\/](react|react-dom|react-router)[\\/]/, name: 'react-vendor', chunks: 'all', priority: 20, }, // Общий код (используется в 2+ чанках) common: { name: 'common', minChunks: 2, priority: -20, reuseExistingChunk: true, }, }, }, runtimeChunk: 'single', // Webpack runtime в отдельный файл}Performance Hints
Заголовок раздела «Performance Hints»performance: { hints: 'warning', // 'error' | 'warning' | false maxEntrypointSize: 244000, // 244 KB — предупреждение для entry maxAssetSize: 244000, // 244 KB — предупреждение для ассетов assetFilter: (assetFilename) => { return /\\.(js|css)$/.test(assetFilename); },}Persistent Caching (Webpack 5)
Заголовок раздела «Persistent Caching (Webpack 5)»Резко ускоряет повторные сборки:
cache: { type: 'filesystem', // Кешировать на диск cacheDirectory: path.resolve(__dirname, '.webpack-cache'), buildDependencies: { config: [__filename], // Инвалидировать кеш при изменении конфига },}// Повторная сборка: 10s → 1s!Resolve оптимизации
Заголовок раздела «Resolve оптимизации»resolve: { // Не проверять расширения лишний раз extensions: ['.tsx', '.ts', '.js'], // Только нужные modules: [path.resolve(__dirname, 'src'), 'node_modules'], // Не разрешать симлинки (ускоряет разрешение) symlinks: false,}Bundle Analysis
Заголовок раздела «Bundle Analysis»# Генерация статистикиnpx webpack --json > dist/stats.jsonnpx webpack-bundle-analyzer dist/stats.json
# Или через плагин:new BundleAnalyzerPlugin({ analyzerMode: 'static' })Ниже — интерактивная scoreboard оптимизации. Включайте оптимизации и смотрите как меняется размер бандла.