为了账号安全,请及时绑定邮箱和手机立即绑定

HTTP压缩之gzip和brotli

gzip

Gzip是若干种文件压缩程序的简称,通常指GNU计划的实现,此处的gzip代表GNU zip。也经常用来表示gzip这种文件格式。

目前主要讲的gzip压缩优化,就是通过gzip这个压缩程序,对资源进行压缩,从而降低请求资源的文件大小。

1 gzip简介

示例:csdn

在网络请求Network中,选择一个js或css,都能在Response Headers中找到 content-encoding: gzip 键值对,这就表示了这个文件是启用了gzip压缩的。
在这里插入图片描述

掘金:

在这里插入图片描述

淘宝网,等等

demo演示

  1. 建一个没有开启gzip的本地服务器,看看未开启gzip压缩这个文件是多大。

  2. 用原生node写一个服务,目录和代码如下:

const http = require("http");
const fs = require("fs");

const server = http.createServer((req, res) => {
  const rs = fs.createReadStream(`static${req.url}`); //读取文件流
  rs.pipe(res); //将数据以流的形式返回
  rs.on("error", err => {
    //找不到返回404
    console.log(err);
    res.writeHead(404);
    res.write("Not Found");
  });
});
//监听8080
server.listen(8080, () => {
  console.log("listen prot:8080");
});

node server.js启动服务,访问[http://localhost:8080/target=http%3A%2F%2Flocalhost%3A8080%2Fvds.js),网页会显示文件的内容,查看Network面版,会发现.js请求大小,和原始资源文件大小一致,Response Headers中也没有 content-encoding: gzip ,说明这是未经过gzip压缩的。

如何开启gzip呢,很简单,node为我们提供了zlib模块,直接使用就行,上面的代码简单修改一下就可以。

const http = require("http");
const fs = require("fs");
const zlib = require("zlib"); // <-- 引入zlib块

const server = http.createServer((req, res) => {
  const rs = fs.createReadStream(`static${req.url}`);
  const gz = zlib.createGzip(); // <-- 创建gzip压缩
  rs.pipe(gz).pipe(res); // <-- 返回数据前经过gzip压缩
  rs.on("error", err => {
    console.log(err);
    res.writeHead(404);
    res.write("Not Found");
  });
});

server.listen(8080, () => {
  console.log("listen prot:8080");
});

运行这段代码,访问http://localhost:8080/vds.js,会发现网页没有显示vds.js内容。

服务器设置:Response Headers里的 content-encoding: gzip

我们最后修改一下代码,加一个请求头:

const http = require("http");
const fs = require("fs");
const zlib = require("zlib"); 

const server = http.createServer((req, res) => {
  const rs = fs.createReadStream(`static${req.url}`);
  const gz = zlib.createGzip(); 
  res.setHeader("content-encoding", "gzip"); //添加content-encoding: gzip请求头。
  rs.pipe(gz).pipe(res); 
  rs.on("error", err => {
    console.log(err);
    res.writeHead(404);
    res.write("Not Found");
  });
});

server.listen(8080, () => {
  console.log("listen prot:8080");

浏览器再请求到gzip压缩后的文件,会先解压处理一下再使用,这对于我们用户来说是无感知的,工作浏览器都在背后默默做了,我们只是看到网络请求文件的大小,比服务器上实际资源的大小小了很多。

nginx中有关gzip的配置项如下:

1、gzip on|off:**默认off

开启或者关闭gzip模块

2、gzip_comp_level 4:**默认1,建议选择为4

gzip压缩比/压缩级别,压缩级别 1-9,级别越高压缩率越大,压缩时间越长,消耗CPU也越大。

3、gzip_min_length 1k:**默认0,不管页面多大都压缩

设置允许压缩的页面最小字节数,页面字节数从header头中的Content-Length中进行获取。

建议设置成大于1k的字节数,小于1k可能会越压越大。 即: gzip_min_length 1024

4、gzip_static on|off:**默认off

gzip_static是nginx对于静态文件的处理模块,可以读取预先压缩的gz文件,多与构建时压缩同时使用,详见下节构建时压缩介绍

5、gzip_types

6、更多配置信息参考:**Nginx的gzip

gzip的注意点

前面说的哪些文件适合开启gzip压缩,哪些不适合是一个注意点。

还有一个注意点是,谁来做这个gzip压缩,我们的例子是在接到请求时,由node服务器进行压缩处理。这和express中使用compression中间件,koa中使用koa-compress中间件,nginx和tomcat进行配置都是一样的,这也是比较普遍的一种做法,由服务端进行压缩处理。

服务器了解到我们这边有一个 gzip 压缩的需求,它会启动自己的 CPU 去为我们完成这个任务。而压缩文件这个过程本身是需要耗费时间的,大家可以理解为我们以服务器压缩的时间开销和 CPU 开销(以及浏览器解析压缩文件的开销)为代价,省下了一些传输过程中的时间开销。

如果我们在构建的时候,直接将资源文件打包成gz压缩包,其实也是可以的,这样可以省去服务器压缩的时间,减少一些服务端的消耗。

比如我们在使用webpack打包工具的时候可以使用compression-webpack-plugin插件,在构建项目的时候进行gzip打包,详细的配置使用可以去看插件的文档,非常简单。

gzip在webpack中的应用

此例子是真实项目中的配置

1 先安装compression-webpack-plugin插件(注意版本问题)

2 Config/index.js中配置:

    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css']

3 发布时在webpack.prod.conf.js中设置具体配置

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp(
        '\\.(' + config.build.productionGzipExtensions.join('|') + ')$'
      ),
      threshold: 10240,
      minRatio: 0.8
    })
  )

4 nginx配置

1、gzip on|off

5、gzip_types 

说明:webpack-dev-server中的compress: true就是指采用gzip压缩

brotli压缩

谁在用:

在这里插入图片描述

支持Brotli压缩算法的浏览器使用的内容编码类型为br

Chrome浏览器请求头里Accept-Encoding的值:

Accept-Encoding: gzip, deflate, sdch, br

如果服务端支持Brotli算法,则会返回以下的响应头:

Content-Encoding: br

需要注意的是,只有在HTTPS的情况下,浏览器才会发送br这个Accept-Encoding。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消