0%

webpack优化-启用gzip

一、GZIP简介

HTTP协议上的gzip编码是一种用来改进web应用程序性能的技术,web服务器和客户端(浏览器)必须共同支持gzip。目前(2022-04)所有浏览器都支持该协议

GZIP是若干文件压缩程序的简称,通常指GNU计划的实现,此处的GZIP代表的就是GUN ZIP,这也是HTTP1.1协议定义的两种压缩方法中最常用的一种压缩方法,客户端浏览器大都支持这种压缩格式。亲测压缩后的文件大小可以减至原先的1/3甚至更小。
其原理如下图

客户端向服务器端发起一个请求,请求头会带上accept-encoding表示客户端支持的压缩编码格式。
accept-encoding: gzip, deflate, br

服务端启用gzip时,

  • 接收客户端请求,查看请求头accept-encoding支持的压缩编码格式,如果是包含gzip那么
  • 在每次响应资源请求之前进行gzip编码压缩后再响应返回(在响应头会带上content-encoding: gzip)

既然压缩了,就涉及到解压。客户端接受到响应的内容后,根据content-encoding格式自动进行相应的解码。

二、webpack优化

压缩成gz文件

可以借助compression-webpack-plugin对前端资源进行gzip压缩,压缩完会生成以.gz结尾的同名文件。

服务器直接读取gz文件

服务器在查找到有与源文件同名的.gz文件就会直接读取,不会主动压缩,降低cpu负载,优化了服务器性能

问题来了,为什么会自动去取gz文件?自动是有前提的

以nginx为例
动态压缩模式

nginx在设置了gzip on 后就已经打开了gzip压缩功能,不过这时候nginx所使用的是动态压缩。在动态压缩的情况下nginx会自动的将文件压缩成.gz文件,这时候就算不配置webpack也能达到一样的效果。
但是动态对所有文件进行压缩无疑会占用服务器的资源来进行此操作,可以通过限制文件类型gzip_types来减少对服务器资源的占用。

1
2
3
4
5
6
gzip on;
gzip_min_length 1100;
gzip_buffers 4 8k;
gzip_comp_level 6;
gzip_proxied any;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss

静态压缩模式

相对的nginx提供了静态压缩模式,也就是gzip_static,在这个模式下nginx会去寻找对应文件的.gz文件,只有.gz文件不存在的时候才会去压缩对应文件。这样就不会过度占用服务器资源。

一般不会默认安装此模块。gzip_static功能依赖http_gzip_static_module 模块。

配置过程中遇到的问题

1、webpack版本冲突

1
TypeError:Cannot read property 'thisCompilation' of undefined
1
2
"webpack": "4.16.5",
"compression-webpack-plugin": "^6.1.1"

2、插件新旧版本配置项变化了

1
2
- options has an unknown property 'asset'. These properties are valid:
object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename? }

看错误提示说不存在asset属性,查看github上的文档发现,应该改为filename

具体webpack配置

webpack配置中,productionGzip默认为false,将它设置为true

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')

webpackConfig.plugins.push(
new CompressionWebpackPlugin({
filename: '[path][base].gz',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8 // minRatio小于1才会进行压缩
})
)
}

Ref:

  1. 服务器端如何开启gzip
  2. gzip浏览器兼容性
  3. 插件compression-webpack-plugin的github链接