gzip压缩实践

前言

为提高网页加载速度,启用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占用的影响。

压缩率
压缩率和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文件。

compression-webpack-plugin插件

在这种方式的压缩中,我们完全可以把压缩等级设置为一个比较高的值(默认),毕竟只是略微影响打包的时间,却能获取一个更小的体积的包,还是比较值得的。

nginx为例,静态压缩需要使用http_gzip_static_module这个模块,这个模块不是默认的,应使用--with-http_gzip_static_module的配置参数启用它

之后再配置中添加

  gzip_static: on;
  gzip_proxied expired no-cache no-store private auth;

这样便可开启静态压缩。

需要注意以下几点:

  1. gzip_static配置优先级要高于gzip
  2. 开启静态压缩后,任何文件都会查找是否存在对应的.gz文件,如果有则直接返回该.gz文件的内容
  3. gzip_types的设置对gzip_static无效

推荐阅读更多精彩内容