代码压缩策略与工具选择
代码压缩的必要性
代码压缩是现代前端构建流程中不可或缺的环节。随着项目规模扩大,未压缩的代码会导致加载时间延长,影响用户体验。压缩后的代码能显著减少文件体积,提升传输效率,同时也能在一定程度上保护源代码。
Webpack内置压缩方案
Webpack从4.0版本开始内置了TerserPlugin作为默认的JS压缩工具。基本配置非常简单:
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimize: true,
minimizer: [new TerserPlugin()],
},
};
这个配置会自动启用多进程并行压缩,并应用默认的优化策略。TerserPlugin支持ES6+语法,能够正确处理箭头函数、类声明等现代JS特性。
高级压缩策略
多进程并行压缩
对于大型项目,可以配置parallel参数提升压缩速度:
new TerserPlugin({
parallel: true, // 启用多进程
// 或者指定具体的线程数
// parallel: 4,
})
自定义压缩选项
通过terserOptions可以深度定制压缩行为:
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true, // 移除所有console语句
pure_funcs: ['console.log'], // 只移除console.log
passes: 3, // 多次压缩提升压缩率
},
mangle: {
properties: {
regex: /^_/, // 只混淆下划线开头的属性
},
},
},
})
条件压缩
某些情况下需要对特定文件采用不同的压缩策略:
optimization: {
minimizer: [
new TerserPlugin({
test: /\.m?js(\?.*)?$/i,
exclude: /\/node_modules\/lodash/,
}),
],
}
CSS压缩方案
CssMinimizerPlugin
Webpack5推荐使用CssMinimizerPlugin处理CSS:
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new CssMinimizerPlugin({
parallel: 4,
minimizerOptions: {
preset: [
'default',
{
discardComments: { removeAll: true },
},
],
},
}),
],
},
};
高级CSS优化
结合PostCSS可以实现更智能的CSS压缩:
const PostcssPresetEnv = require('postcss-preset-env');
new CssMinimizerPlugin({
minimizerOptions: {
processorOptions: {
postcssOptions: {
plugins: [
PostcssPresetEnv({
stage: 3,
features: {
'nesting-rules': true,
},
}),
],
},
},
},
})
HTML压缩方案
HtmlWebpackPlugin集成
在HtmlWebpackPlugin中直接配置压缩选项:
new HtmlWebpackPlugin({
minify: {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true,
minifyCSS: true,
minifyJS: true,
},
})
自定义HTML压缩
对于更复杂的需求可以使用专门的html-minifier-terser:
const HtmlMinimizerPlugin = require('html-minimizer-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new HtmlMinimizerPlugin({
minimizerOptions: {
collapseWhitespace: true,
removeComments: true,
caseSensitive: true,
keepClosingSlash: true,
},
}),
],
},
};
资源压缩策略
图片压缩
使用image-minimizer-webpack-plugin处理图片资源:
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
minimizerOptions: {
plugins: [
['gifsicle', { interlaced: true }],
['jpegtran', { progressive: true }],
['optipng', { optimizationLevel: 5 }],
[
'svgo',
{
plugins: [
{
removeViewBox: false,
},
],
},
],
],
},
}),
],
};
字体文件压缩
虽然字体文件通常已经经过压缩,但可以通过以下方式进一步优化:
const FontminPlugin = require('fontmin-webpack');
module.exports = {
plugins: [
new FontminPlugin({
autodetect: true,
glyphs: ['你', '好', '世', '界'], // 只包含特定字符
}),
],
};
高级优化技巧
基于AST的优化
利用Babel插件在编译阶段进行优化:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
plugins: [
['transform-remove-console', { exclude: ['error', 'warn'] }],
'transform-remove-debugger',
],
},
},
},
],
},
};
代码分割与压缩
结合SplitChunksPlugin实现更智能的压缩:
optimization: {
splitChunks: {
chunks: 'all',
minSize: 30000,
maxSize: 244000,
minChunks: 1,
},
minimizer: [
new TerserPlugin({
extractComments: false,
}),
],
}
性能与质量的平衡
压缩级别调节
不同的环境可以采用不同的压缩级别:
const isProduction = process.env.NODE_ENV === 'production';
new TerserPlugin({
terserOptions: {
compress: {
ecma: 2015,
warnings: false,
comparisons: false,
inline: isProduction ? 2 : 1,
},
mangle: {
safari10: true,
},
output: {
ecma: 2015,
comments: false,
ascii_only: true,
},
},
})
SourceMap处理
压缩时正确处理SourceMap:
new TerserPlugin({
sourceMap: true,
terserOptions: {
output: {
comments: /^\**!|@preserve|@license|@cc_on/,
},
},
})
监控与分析
压缩效果分析
使用webpack-bundle-analyzer评估压缩效果:
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'static',
reportFilename: 'report.html',
openAnalyzer: false,
}),
],
};
构建性能监控
记录压缩阶段的耗时:
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
const smp = new SpeedMeasurePlugin();
module.exports = smp.wrap({
// webpack配置
});
特殊场景处理
第三方库的特殊处理
某些库需要特殊压缩配置:
new TerserPlugin({
terserOptions: {
compress: {
defaults: false,
unused: true,
},
mangle: false,
format: {
beautify: true,
comments: true,
},
},
include: /[\\/]node_modules[\\/]some-library[\\/]/,
})
保留特定注释
保留法律声明等特殊注释:
new TerserPlugin({
extractComments: {
condition: /^\**!|@preserve|@license|@cc_on/i,
filename: (fileData) => {
return `${fileData.filename}.LICENSE.txt${fileData.query}`;
},
banner: (licenseFile) => {
return `License information can be found in ${licenseFile}`;
},
},
})
现代压缩技术
ESBuild集成
使用esbuild-loader获得极速压缩:
const { ESBuildMinifyPlugin } = require('esbuild-loader');
module.exports = {
optimization: {
minimizer: [
new ESBuildMinifyPlugin({
target: 'es2015',
css: true,
}),
],
},
};
SWC压缩
利用SWC的压缩能力:
const SwcMinifyPlugin = require('swc-minify-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new SwcMinifyPlugin({
ecma: 2015,
compress: {
unused: true,
},
}),
],
},
};
持续优化实践
自动化基准测试
建立压缩效果基准:
const { execSync } = require('child_process');
function getSizeStats() {
const output = execSync('du -sb dist').toString();
return parseInt(output.split('\t')[0], 10);
}
const beforeSize = getSizeStats();
// 构建完成后
const afterSize = getSizeStats();
console.log(`压缩率: ${((beforeSize - afterSize) / beforeSize * 100).toFixed(2)}%`);
渐进式压缩策略
分阶段应用不同压缩级别:
const defaultMinimizer = new TerserPlugin({
terserOptions: {
compress: {
defaults: true,
},
},
});
const aggressiveMinimizer = new TerserPlugin({
terserOptions: {
compress: {
passes: 3,
pure_getters: true,
unsafe: true,
unsafe_comps: true,
},
},
});
module.exports = {
optimization: {
minimizer: [
process.env.AGGRESSIVE_MINIFY === 'true'
? aggressiveMinimizer
: defaultMinimizer,
],
},
};
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:图片/字体等资源优化
下一篇:按需加载与路由懒加载