美文网首页
如何为项目开启gzip压缩及实现原理

如何为项目开启gzip压缩及实现原理

作者: AizawaSayo | 来源:发表于2021-04-19 18:01 被阅读0次

项目的线上版本我们一般都会结合构建工具(webpack)插件和服务端配置(nginx)来实现 http 传输 的 gzip 压缩,目的就是把服务端响应的文件的体积尽量减小,优化返回速度。那这件事具体是怎么实现的呢?

http 传输中 gzip 压缩的原理

客户端(浏览器)在请求静态资源(js、css等)的时候,在请求头 Request Header 里带上 accept-encoding字段来表明接受哪些压缩方法, 如accept-encoding: gzip, deflate;服务端在接收到请求时如果发现有这个配置,则发送gzip压缩版本的文件,并在响应头 Response Headers 配置一个 content-encoding 字段,用于说明服务端数据的压缩方法(可选值是gzip、compress、deflate),否则(没有accept-encoding)就发送源文件;客户端再根据返回响应头里 content-encoding 对应的格式去做相应的解码/解压缩;没有content-encoding项则不进行解压缩。
accept-encodingcontent-encoding字段都非常语义化,就是传输的文件以怎样的格式编码/解码,所以当响应头有content-encoding: gzip出现,就能说明我们服务端的gzip压缩成功开启了。如下:

同时我们还能看到压缩后的文件 size,记得先在Chrome浏览器的 Network 下勾选 ☑️Use large request rows

谁来压缩文件?

(1) 服务端响应请求时压缩
如果我们在服务器用Nginx代理部署项目,就直接让 nginx 来处理压缩,它有专门为此构建的内容,可以更好地利用缓存并减少开销。我们要做的只是在服务端的 nginx.conf做好配置,其他就不需要我们操心了。

配置参数可参考:Nginx的gzip配置文档

    # 开启gzip压缩
    gzip on;
    gzip_buffers 4 16k; # 置用于压缩响应的缓冲区的数量和大小
    gzip_comp_level 9;  # 对响应压缩的级别,可选范围:1到9,数字越大压缩得越好,但也越占用CPU时间
    gzip_http_version 1.1; # 默认 1.1,请求压缩响应所需的最小HTTP版本
    gzip_min_length  1k;  # 设置被gzip的响应的最小长度,小于该值的文件不会被压缩
    # 追加启用gzip压缩的MIME类型,默认已有text/html
    gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;
gzip_disable "MSIE [1-6]\.";
    gzip_vary on; # 默认off,如果指令gzip、gzip_static或gunzip是active的,启用插入" Vary: Accept-Encoding "响应报头字段

具体配置位置展示

(2) 项目打包构建生产版本时压缩
既然服务端都可以做压缩,为什么在 webpack 打包应用时还要多此一举呢?我们可以看上面 nginx 配置中 gzip_comp_level 这个配置项,数字越大压缩效果越好,但是会耗费更多的CPU和时间,我们压缩文件主要是为了减少传输时间,如果每次请求静态资源服务端都要压缩很久才会返回信息,不仅本末倒置吗?况且服务器开销也会增大很多。既然现在的 spa 应用文件都是打包生成的,我们在打包的时候就直接生成高压缩等级的文件,作为静态资源放在服务器上,接收到请求后直接把这些压缩版文件返回回去不就好了?

webpack 的 compression-webpack-plugin 就是专门做这件事情的:

tip:我bulid的时候报了Cannot read property 'tapPromise' of undefined的错,其实就是版本和vue-cli的某些包不兼容,把 compression-webpack-plugin 的版本降低到6.1.1就可以了。

先安装npm install compression-webpack-plugin -D,然后到vue.config.js配置:

const CompressionPlugin = require("compression-webpack-plugin");

configureWebpack: config => {
    config.name = name
    const plugins = []
    if (IS_PROD) { // 生产环境
      plugins.push( 
        // 为静态资源准备压缩版本,在服务器也要开启相应配置
        new CompressionWebpackPlugin({
          test: /\.(js|css|json|ico|svg)$/,// 匹配文件格式
          algorithm: 'gzip',
          threshold: 10240, // 对超过10k的数据压缩
          minRatio: 0.8, // 压缩比
          // filename: "[path][base].gz", // 压缩后的文件名,默认值是 [path][base].gz
          filename(pathData) {
            // `pathData` 参数包含很多可以获取到文件路径相关数据的属性 - `path`/`name`/`ext`/等等
            // 如果路径中包含svg,则放到svg/目录下
            // 只是演示,一般都用字符串默认值就好
            if (/\.svg$/.test(pathData.ext)) {
              return 'static/svg/[base].gz'
            }
            return '[path][base].gz'
          },
          deleteOriginalAssets: false, // 不删除源文件,true 则只保留压缩后的文件
        })
      )
    } else {
      // 为开发环境修改配置
    }
    config.plugins = [...config.plugins, ...plugins]
  },

其中 filename 参数就是定义文件编码压缩后的路径和文件名,格式除了字符串也可以是Function(基本没啥必要)。
默认值是"[path][base].gz",一般保持默认值就好。
gz是文件后缀,那[path][base] 是啥呢

比如我们有这么个静态资源:static/images/image.png?foo=bar#hash (static是我打包目录下自定义的静态资源目录),然后若我们给插件 filename 的值里配置如下参数,完成压缩后输出的文件名中:

  • [path] 会被替换为源静态资源的目录, 包括末尾的 / (static/images/)
  • [file] 为源静态资源的路径 (static/images/image.png)
  • [name] 为源文件的文件名 (image)
  • [ext] 为源文件(包含.)的扩展名 (.png)
  • [base] 会被替换为 ([name] + [ext]) 的内容 (image.png)
  • [query] 为源文件的查询参数,包括 ? (?foo=bar)
  • [fragment] 为源文件的 fragment (在URL的概念里叫做hash)(#hash)
在filename给svg单独配文件名的效果 打完包大部分文件会多出一个gz版本, 根据我们的配置,size小于threshold数值的文件不会生成gz版本

参考文章:探索HTTP传输中gzip压缩

相关文章

  • 如何为项目开启gzip压缩及实现原理

    项目的线上版本我们一般都会结合构建工具(webpack)插件和服务端配置(nginx)来实现 http 传输 的 ...

  • nginx开启gzip

    1.开启gzip nginx实现资源压缩的原理是通过ngx_http_gzip_module模块拦截请求,并对需要...

  • Nginx启用压缩及开启gzip 压缩的方法

    Nginx启用压缩及开启gzip 压缩的方法 gzip(GNU-ZIP)是一种压缩技术。经过gzip压缩后页面大小...

  • [性能优化]HTTP篇

    参考文章:Vue 项目性能优化 — 实践指南(网上最全 / 详细) 开启 gzip 压缩 gzip 是 GNUzi...

  • vue项目优化一

    vue 项目开启gzip自拍压缩和部署 nginx 开启gzip优化性能 第一步,在vue项目中安装依赖并将pro...

  • 开启gzip

    开启gzip 标签: gzip compression 开启gzip压缩要在 static 之前才有效,下面以 c...

  • springboot常用配置

    springboot开启https springboot开启gzip压缩

  • Tomcat优化之Connector配置建议

    Gzip相关设置 作用:用来压缩网络参数 相关参数:①compression --是否开启Gzip压缩②compr...

  • 页面打开速度优化

    1、开启gzip压缩,浏览器是可以识别gzip压缩的。现在的服务基本上都使用nginx做转发,开启gzip也是很容...

  • vue gzip压缩

    productionGzip改为true,开启Gzip压缩

网友评论

      本文标题:如何为项目开启gzip压缩及实现原理

      本文链接:https://www.haomeiwen.com/subject/usfvlltx.html