gzip、cssnano、uglifyjs压缩原理
gzip 压缩算法
Lempel-Ziv coding (LZ77) 算法 加 Huffman 编码来压缩文件
- LZ77 算法检测重复的数据序列,并用偏移量和长度代替重复数据。
- Huffman 编码进一步压缩数据,通过使用更短的位序列表示更频繁出现的数据模式。
具体的可以再次详细查找资料 看视频可能更容易理解,文字描述起来比较复杂还难以理解,如果需要可以留言,之后会尽量整理一下。
cssnano 压缩原理
cssnano主要通过 移除不必要的字符、合并选择器、简化颜色值等,从而减小文件大小而不影响最终样式的表现。
cssnano 的压缩算法概览:
- 语法分析: 首先,
cssnano读取 CSS 文件并使用 PostCSS 的解析器将其转换成一个 AST。PostCSS 使用postcss-safe-parser或postcss-css-in-js等解析器来完成这项工作。 - 插件优化:
cssnano会应用一系列 PostCSS 插件来优化 AST。这些插件执行不同的任务,比如:- 清理无用规则: 移除未使用的 CSS 规则, 清理空规则集。
- 移除注释和空白: 删除所有 CSS 注释, 最小化空白字符,包括行尾空白。
- 简化选择器和属性: 合并相似的选择器, 简化颜色值(例如,将
#ffffff缩短为#fff), 使用更短的语法替代较长的语法(例如,将border: none替换为border: 0)。 - 优化字体图标: 对于使用字体图标的 CSS,可以进行特定优化。
- 移除冗余前缀: 移除不需要的浏览器前缀。
- 转换属性值: 将某些属性值转换为更简短的形式(例如,
background-position: 0 0可以变为background-position: 0)。 - 其他优化: 转换长度单位(例如,从
px到em), 简化函数调用(例如,将rgba(255, 255, 255, 1)转换为#fff)。
- 代码生成: 经过优化之后,
cssnano会将修改后的 AST 重新生成为压缩后的 CSS 文件。这一步通常会去除空白字符、注释以及不必要的分号等。
uglifyjs 原理
- 语法分析: 对原文件进行语法分析,生成
AST - 语义分析: 对 AST 进行分析,包括但不限于变量作用域和类型推断等,这一步骤有助于确定哪些代码可以安全地被压缩或转换。
- 代码转换:
UglifyJS应用一系列转换规则来修改 AST 比如:- 死代码消除 :删除那些永远不会被执行的代码。
- 常量折叠 :计算静态表达式的值。
- 条件简化 :简化条件表达式。
- 变量重命名 :将长变量名替换为单个字符或其他简短的标识符。
- 内联函数 :替换函数调用为函数体,减少函数调用的开销。
- 循环展开 :减少循环中的迭代次数,以减少循环控制结构的开销。
- 代码生成:
UglifyJS重新生成源代码,这个新生成的源代码就是压缩后的版本,这个过程中还会进行一些优化,例如移除不必要的空格、注释和换行等。
拓展
MiniCssExtract-webpack-plugin 的作用
MiniCssExtract-webpack-plugin 主要作用是提取模块中的 css 代码到单独的文件中, MiniCssExtractPlugin.loader 的主要作用是将模块中的 css 分离出来,供 MiniCssExtractPlugin 进行可以提取,生成单独的 css 文件,自动在 HTML 文件中插入 <link> 标签指向生成的 CSS 文件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
// ...
module: {
rules: [
{
test: /.css$/,
use: [
MiniCssExtractPlugin.loader, // 用于提取 CSS 到单独的文件
"css-loader", // 解析 CSS 文件
"postcss-loader", // 运行 PostCSS 插件
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css",
chunkFilename: "[id].[contenthash].css",
}),
],
// ...
};
MiniCssExtract-webpack-plugin 配合optimize-css-assets-webpack-plugin 或者 css-minimizer-webpack-plugin 或者 cssnano 一起使用进行 css 压缩并提取单独的文件
这个插件使用 cssnano 优化和压缩 CSS。
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
// ...
module: {
rules: [
{
test: /.s?css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
},
],
},
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
// `...`,
new CssMinimizerPlugin(),
],
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
],
// ...
};
小小结
粗略的介绍了一下它们,让大家有一个大概的了解,之后再深入了解,比如源码的实现,AST树的了解等。