网站前端性能优化Gzip压缩

111次阅读
没有评论

共计 4423 个字符,预计需要花费 12 分钟才能阅读完成。

gzip 简介

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

简单来说,gzip 是一种压缩技术。经过 gzip 压缩后,文件大小为原来的 30% 甚至更小,这样,用户浏览页面的时候速度会快得多。

那么客户端和服务器之间是如何通信来支持 gzip 的呢?通过下图我们可以很清晰的了解。

客户端 http 请求头 Accept-Encoding 声明浏览器支持的压缩方式,服务端配置启用压缩,压缩的文件类型,压缩方式。当客户端请求到服务端的时候,服务器解析请求头,如果客户端支持 gzip 压缩,响应时对请求的资源进行处理并返回给客户端,浏览器按照自己的方式解析,在 http 响应头,我们可以看到content-encoding:gzip,这是指服务端使用了 gzip 的压缩方式,返回的是 gzip 文件。

服务器返回 gzip 文件的处理方式可以有两种:

  1. 前端打包的时候生成了对应的.gz 文件,则浏览器请求 xx.js 时,服务器返回对应的 xxx.js.gz 文件
  2. 否则,浏览器请求 xx.js 时,服务器对 xx.js 进行 gzip 压缩后传输给浏览器

通常情况,前端会在打包时生成对应文件的.gz 文件,缓解服务器端压缩并缓存 gzip 文件时,对处理器和内存造成的压力。

安装前端压缩插件

安装 compression-webpack-plugin 包

npm i -D compression-webpack-plugin

由于脚手架版本兼容问题,直接安装最新版可能会导致报错

TypeError: Cannot read property‘tapPromise’of undefined

我这里 vue cli 是 4.4.6 版本,安装的是 6.1.1 版本

npm i -D compression-webpack-plugin@6.1.1

修改 vue.config.js 文件

在 vue.config.js 文件中添加以下代码,和 gizp 压缩无关的代码这里已去除

const isProd = process.env.NODE_ENV === 'production';

const vueConfig = {
    configureWebpack: {
        // webpack plugins
        plugins: [......]
    }
}

if(isProd) {
  // production 模式下,plugins 中添加文件压缩处理器
  const CompressionWebpackPlugin = require('compression-webpack-plugin');
  vueConfig.configureWebpack.plugins.push(new CompressionWebpackPlugin({test: /.js|.css/, // 对匹配的文件类型进行压缩}))
}

module.exports = vueConfig;

服务器端如何启用 gzip

前面说过了,启用 gzip 需要客户端和服务端的支持,如果客户端支持 gzip 的解析,那么只要服务端能够返回 gzip 的文件就可以启用 gzip 了,现在来说一下几种不同的环境下的服务端如何配置。

nginx 启用 gzip

gzip 使用环境:http,server,location,if(x), 一般把它定义在 nginx.conf 的 http{……}之间

修改 nginx 配置,在 server 里添加以下代码,与 listen 同级

gzip on; # 开启 Gzip
gzip_static on; # 开启静态文件压缩
gzip_min_length  1k; # 不压缩临界值,大于 1K 的才压缩
gzip_buffers     4 16k;
gzip_comp_level 5;
gzip_types     application/javascript application/x-javascript application/xml application/xml+rss application/x-httpd-php text/plain text/javascript text/css image/jpeg image/gif image/png; # 进行压缩的文件类型
gzip_http_version 1.1;
gzip_vary on;
gzip_proxied   expired no-cache no-store private auth;
gzip_disable   "MSIE [1-6].";
  • gzip on
    on 为启用,off 为关闭
  • gzip_min_length 1k
    设置允许压缩的页面最小字节数,页面字节数从 header 头中的 Content-Length 中进行获取。默认值是 0,不管页面多大都压缩。建议设置成大于 1k 的字节数,小于 1k 可能会越压越大。
  • gzip_buffers 4 16k
    获取多少内存用于缓存压缩结果,‘4 16k’表示以 16k* 4 为单位获得
  • gzip_comp_level 5
    gzip 压缩比(1~9),越小压缩效果越差,但是越大处理越慢,所以一般取中间值;
  • gzip_types application/javascript application/x-javascript application/xml application/xml+rss application/x-httpd-php text/plain text/javascript text/css image/jpeg image/gif image/png
    对特定的 MIME 类型生效, 其中 ’text/html’被系统强制启用
  • gzip_http_version 1.1
    识别 http 协议的版本, 早期浏览器可能不支持 gzip 自解压, 用户会看到乱码
  • gzip_vary on
    启用应答头 ”Vary: Accept-Encoding”
  • gzip_proxied off
    nginx 做为反向代理时启用 off(关闭所有代理结果的数据的压缩),
    expired(启用压缩, 如果 header 头中包括 ”Expires” 头信息),
    no-cache(启用压缩,header 头中包含 ”Cache-Control:no-cache”),
    no-store(启用压缩,header 头中包含 ”Cache-Control:no-store”),
    private(启用压缩,header 头中包含 ”Cache-Control:private”),
    no_last_modefied(启用压缩,header 头中不包含 ”Last-Modified”),
    no_etag(启用压缩, 如果 header 头中不包含 ”Etag” 头信息),
    auth(启用压缩, 如果 header 头中包含 ”Authorization” 头信息)
  • gzip_disable “MSIE [1-6].”
    (IE5.5 和 IE6 SP1 使用 msie6 参数来禁止 gzip 压缩)指定哪些不需要 gzip 压缩的浏览器(将和 User-Agents 进行匹配), 依赖于 PCRE 库

tomcat 启用 gzip

找到 tomcat 的 server.xml 文件,找到其中 Connector 节点然后进行配置修改,具体配置如下

<Connectorport="80"protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" maxPostSize="0" useBodyEncodingForURI="true" compression="on" compressionMinSize="2048" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml,application/javascript,text/css,text/plain,image/jpeg,application/json"/>

参数说明:

  • compression=”on” 打开压缩功能
  • compressionMinSize=”2048″ 启用压缩的输出内容大小,当被压缩对象的大小 >= 该值时才会被压缩,这里面默认为 2KB
  • noCompressionUserAgents=”gozilla, traviata” 对于以下的浏览器,不启用压缩
  • compressableMimeType=”text/html,text/xml,text/javascript,text/css,text/plain” 压缩类型

注意:tomcat7 以后,js 文件的 mimetype 类型变为了 application/javascript,而在 tomcat7 以下则为 text/javascript; 具体的 tomcat7 定义的类型可以在:conf/web.xml 文件中找到。

可以在 web.xml 下搜索,如我搜索 javascript 会找到如下代码

<mime-mapping>
    <extension>js</extension>
    <mime-type>application/javascript</mime-type>
</mime-mapping>

切记上面的类型不能配置错了,如果配置错了压缩是不会起作用的。

node 端启用 gzip

node 端很简单,只要加上 compress 模块即可,代码如下

var compression = require('compression')
var app = express();

// 尽量在其他中间件前使用 compression
app.use(compression());

这是基本用法,如果还要对请求进行过滤的话,还要加上

app.use(compression({filter: shouldCompress}))

function shouldCompress (req, res) {if (req.headers['x-no-compression']) {
    // 这里就过滤掉了请求头包含 'x-no-compression'
    return false
  }

  return compression.filter(req, res)
}

更多用法请移步 compression 文档
如果用的是 koa,用法和上面的差不多

const compress = require('koa-compress');
const app = module.exports = new Koa();
app.use(compress());

因为 node 读取的是生成目录中的文件,所以要先用 webpack 等其他工具进行压缩成 gzip。

验证处理结果

运行打包命令 npm run build,可以看到生成的 dist 文件夹中的 js 和 css 文件多出了同名.gz 文件,这里以 js 文件举例。

打包后上传服务器查看效果,可以发现浏览器上下载的是 gzip 压缩后的文件。

通过 Network 可看到 Request Headers 和 Response Headers 里都带有 gzip 标记

注:开发环境下,无法查看压缩效果

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-06-05发表,共计4423字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)