前言
为提高网页加载速度,启用gzip
缩减资源的大小是非常常见的手段。现代浏览器均支持gzip
压缩,并会为HTTP请求自动协商此类压缩。
本文将对gzip
的实践和原理做一个简单的总结。
处理流程
web服务器在接收到浏览器的请求之后,会检查浏览器可以接受哪些压缩方法,详情可见下图。
浏览器在请求头中会带上Accept-Encoding
这个参数来说明自己支持哪些内容编码方式。
而服务端返回的Response Headers
中则存在一个Content-Encoding
,用来说明数据的压缩方法。
几乎所有的浏览器都已经支持了gzip
,并且有请求头的验证,所以基本不需要担心兼容相关的问题。
压缩前后的体积前后差异,可以在控制台中看到。可以说,对于js、css文件的压缩率还是比较可观的。
配置实践
# 开启gzip
gzip on;
# 设置允许压缩文件的最小字节数
gzip_min_length 100;
# 压缩级别(0-9),数字越大压缩效果越好,但也占用CPU性能
gzip_comp_level 2;
# 压缩的文件类型
gzip_types text/plain application/javascript application/x-javascript text/css
经过这种方式的配置,在服务端响应请求的时候会对文件进行压缩,之后返回压缩过后的内容。不过压缩这一过程多多少少会占用一些服务端的性能,具体压缩的程度,也就是gzip_comp_level
设置的值也会影响到占用性能的多少,接下来我们来看一些网上搜集到的数据,了解不同值的设置对文件大小和CPU占用的影响。
可以看到,压缩级别从0到1时,文件大小明显减小,CPU消耗略微上涨。而在之后文件减小的速率明显放缓,在达到了5之后继续增加压缩级别,文件的体积也几乎没有缩小,但CPU消耗却有较为明显的上涨。
根据结论可以看出,如果是在服务端使用gzip
压缩的话,考虑到性能和压缩率的取舍,将压缩级别设置为一个较低的值,比如2之类的,是比较合理的。
我们也可以选择在打包构建项目的时候就对文件进行gzip压缩
这边以打包一个webpack
的前端项目为例
const CompressionWebpackPlugin = require('compression-webpack-plugin');
//plugin中添加该插件
plugins: [
...,
new CompressionWebpackPlugin({
filename: '[path].gz[query]', //升级到webpack v4后,该字段由asset变为filename
algorithm: 'gzip',
compressionOptions: { level: 9 }, //压缩等级设置,默认为9
test: new RegExp('\\.(js|css)$'),
threshold: 8192
})
]
运行构建命令后可以看到,在生成.js
和.css
的同时还生成了对应的.gz
文件。
在这种方式的压缩中,我们完全可以把压缩等级设置为一个比较高的值(默认),毕竟只是略微影响打包的时间,却能获取一个更小的体积的包,还是比较值得的。
以nginx
为例,静态压缩需要使用http_gzip_static_module
这个模块,这个模块不是默认的,应使用--with-http_gzip_static_module
的配置参数启用它
之后再配置中添加
gzip_static: on;
gzip_proxied expired no-cache no-store private auth;
这样便可开启静态压缩。
需要注意以下几点:
-
gzip_static
配置优先级要高于gzip
- 开启静态压缩后,任何文件都会查找是否存在对应的
.gz
文件,如果有则直接返回该.gz
文件的内容 -
gzip_types
的设置对gzip_static
无效