gzip 压缩
常见的压缩技术包括 gzip、Brotli (br) 和 Zstandard (zstd)。gzip兼容性最好,后文讲的都是gzip压缩。
gzip 是一种基于 LZ77 算法的通用数据压缩算法。它通过查找重复的字符串模式来减少数据冗余,从而实现压缩。
1 理解网络传输数值
在浏览器控制台的Network面板中,当你查看网页网络请求时,可能会注意到有两个与大小相关的数值:Transferred over network(网络传输大小)和 Resource size(资源大小)。这两个数值代表了不同的含义,理解它们有助于你更好地分析网络性能和资源优化情况。
-
Transferred over network(网络传输大小)
定义:这是指从服务器传输到浏览器(或从浏览器传输到服务器,如果是上传请求的话)的数据量大小。
影响因素:这个数值会受到多种因素的影响,包括文件本身的压缩情况(如是否开启了Gzip压缩)、HTTP头的大小、传输过程中可能添加的额外数据(如cookies、认证信息等)等。
重要性:网络传输大小是衡量网络性能的重要指标之一。较小的传输大小意味着更快的加载速度和更低的带宽消耗。 -
Resource size(资源大小)
定义:这是指资源本身的原始大小,即文件在服务器上的大小,不包括HTTP头或其他传输过程中添加的额外数据。
影响因素:这个数值主要取决于资源文件本身的内容,如图片、脚本、样式表等的大小。
重要性:资源大小对于评估网页的整体大小和加载性能也很重要。较小的资源大小有助于减少网页的加载时间,提高用户体验。
当你发现某些文件的Transferred over network值远小于Resource size值时,这通常意味着这些文件已经经过了Gzip压缩。
2 开启Gzip压缩
2.1 前置条件
- 服务器开启gzip压缩(nginx、IIS、Apache、tomcat服务器都支持)
- 响应头返回 Content-Encoding: gzip
- 浏览器支持gzip压缩(除IE都支持)
- 请求头返回 Accept-Encoding: gzip
2.2 传输流程
Gzip的动态压缩和静态压缩是两种不同的压缩方式,它们在实际应用中有各自的特点和适用场景。
2.2.1 动态压缩
- 定义:动态压缩是指服务器在响应客户端请求(如.js文件)时,实时地对文件进行压缩,并将压缩后的文件(如.js.gz文件)发送给客户端。
- 实现方式:在Nginx等Web服务器中,动态压缩通常是通过配置gzip模块来实现的。当服务器接收到客户端的请求时,它会检查请求的文件类型是否支持gzip压缩,如果支持,则对文件进行压缩,并在HTTP响应头中设置相应的Content-Encoding字段,指示客户端使用gzip解码。
- 特点:
- 实时性:动态压缩是在客户端请求时实时进行的。
- CPU负载:由于每次请求都需要进行压缩操作,因此会增加服务器的CPU负载。
- 适用性:适用于内容更新频繁、需要实时压缩的场景。
2.2.2 静态压缩
- 定义:静态压缩是指提前将文件压缩成gzip格式,并将压缩后的文件(.gz后缀)存储在服务器上。当客户端请求该文件(如.js文件)时,服务器直接发送压缩后的文件(如.js.gz文件)给客户端。
- 实现方式:在Nginx中,静态压缩可以通过配置 gzip_static 模块来实现。服务器会检查请求的文件是否存在对应的.gz压缩文件,如果存在,则直接发送该压缩文件给客户端。
- 特点:
- 提前性:静态压缩是在文件上传到服务器前或上传后由服务器提前进行的。
- CPU负载:由于压缩操作已经在文件上传前或上传后完成了,因此不会增加服务器在响应请求时的CPU负载。
- 适用性:适用于内容更新不频繁、可以提前压缩的场景。
2.2.3 选择何种方式
- 压缩效率:动态压缩在每次请求时都需要进行压缩操作,而静态压缩则只需要进行一次压缩操作。因此,在压缩效率方面,静态压缩通常更高。
- 资源消耗:动态压缩会增加服务器的CPU负载,而静态压缩则不会。因此,在资源消耗方面,静态压缩更具优势。
- 适用性:在实际项目中,选择gzip的动态压缩还是静态压缩,需要根据项目的具体需求和资源情况来决定。例如,对于静态资源(如图片、CSS、JavaScript等)可以使用静态压缩来优化存储和传输;而对于动态生成的内容(如API响应等)则可以使用动态压缩来减少带宽使用。
3 项目测试
3.1 webpack 开启gzip 压缩
// vue-cli @4.5.13
// compression-webpack-plugin @5.0.1
// webpack-bundle-analyzer @3.9.0
const CompressionWebpackPlugin = require("compression-webpack-plugin");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;module.exports = {...omitconfigureWebpack: config => {// 公共配置..omit// 生产模式if (isProduction) {const plugins = [// 用来观察压缩后的体积大小new BundleAnalyzerPlugin({analyzerMode: "static",reportFilename: "report.html",openAnalyzer: false // 不自动打开浏览器}),new CompressionWebpackPlugin({filename: "[path].gz[query]", // 生成的压缩文件名。algorithm: "gzip", // 压缩算法,这里选择gzip。test: /\.(js|css|svg)$/, // 匹配需要压缩的文件类型。如果删除原始文件一定不能压缩html文件threshold: 10240, // 文件大于这个大小时才进行压缩,单位为字节。minRatio: 0.8, // 压缩比例,只有压缩比例小于这个值的文件才会被压缩。deleteOriginalAssets: false //删除原始文件只保留压缩后的文件,不建议开启})];config.plugins.push(...plugins);} else {config.devtool = "source-map"; // 生成 source map 以便于调试}}
}
3.2 打包产物分析
正常对js/css 压缩就行了,使用gzip对图片进行压缩的话反而会增大体积和失真。
-
可以通过BundleAnalyzerPlugin 插件的点击gzipped查看压缩效率。
- 只能查看js文件的 14.44 M,,gzip压缩后为 3.43 M。js文件压缩为原文件 23%
-
CompressionWebpackPlugin 插件开启
deleteOriginalAssets:true
来比较最终产物大小。- 压缩前 58.5 M,gzip压缩后为 32.3 M 。最终产物压缩率为55%(不是实际压缩率 因为实际只压缩了js/css/svg)。
3.3 观察 gzip是否生效
-
开启Gzip压缩:如果服务器对资源进行了Gzip压缩,那么浏览器在接收到这些资源后会自动进行解压缩。在Network面板中,你可以通过查看Transferred over network值来判断是否开启了Gzip压缩。如果开启了Gzip压缩,该值通常会远小于Resource size值。
-
未开启Gzip压缩:如果服务器没有对资源进行Gzip压缩,那么Transferred over network值将接近或等于Resource size值(考虑到HTTP头和其他额外数据的影响,可能会有一些微小的差异)。
4 gzip 服务器部署设置
4.1 iis 配置
需要在根目录下设置 webconfig(或者全局的webconfig同等配置里)
<?xml version="1.0" encoding="UTF-8"?>
<configuration><system.webServer><httpProtocol><customHeaders><add name="Access-Control-Allow-Origin" value="*" /></customHeaders></httpProtocol><httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files"><scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" /><staticTypes><add mimeType="text/*" enabled="true" /><add mimeType="message/*" enabled="true" /><add mimeType="application/javascript" enabled="true" /><add mimeType="*/*" enabled="false" /></staticTypes><dynamicTypes><add mimeType="text/*" enabled="true" /><add mimeType="message/*" enabled="true" /><add mimeType="application/x-javascript" enabled="true" /><add mimeType="*/*" enabled="false" /></dynamicTypes></httpCompression><urlCompression doStaticCompression="true" doDynamicCompression="false" /></system.webServer>
</configuration>
tips:iis部署有时候会出现随机的gzip行为
iis部署有时候会出现随机的gzip行为 📚
开发环境必须触发频繁访问资源(10秒内2次访问同一url),才能开启gzip。
4.2 nginx 配置
需要设置 config.nginx
gzip on; # 开启Gzip压缩gzip_disable "msie6"; # IE 对 Gzip 压缩不友好,禁掉gzip_buffers 4 16k; # 获取多少内存用于缓存压缩结果,4 16k表示以16k*4为单位获得,默认 4 8kgzip_comp_level 6; # 压缩比{1 - 9},1处理压缩速度最快,9最慢(传输快但消耗CPU)gzip_static: on; # 告诉 nginx 在提供文件时优先查找对应的 .gz 版本gzip_http_version 1.1; # 识别http协议的版本,早期浏览器可能不支持gzip自解压,用户会看到乱码,默认1.1gzip_min_length 10k; // 超过 10Kb才压缩gzip_types text/plain text/plain application/javascript application/x-javascript text/css application/xml text/javascript
5 参考
Gzip、Brotli 和 Zstandard 压缩技术 📚
前端性能优化——Gzip压缩 📚