乐趣区

关于javascript:前端性能之压缩拒绝各种没有试验的复制粘贴

一、前言

最近在做我的项目的过程中,发现随着我的项目越来越大。编译之后的包也越来越大。

能够发现,足足有 35M

之后,进入 static 下的 js 文件夹。


发现有两个文件,一个 4M,一个 13M,比其余的都大。

于是便在网上搜寻各种晋升页面及接口响应速度快的方法。无奈的是,网上大多都是从他人那里复制粘贴的帖子。最初也只能本人入手搞。

二、compression-webpack-plugin

言归正传。通过查问,发现前端有个库。compression-webpack-plugin

引入形式也很简略

yarn add compression-webpack-plugin --D

须要留神 compression-webpack-plugin 得和你我的项目中的 webpack 匹配,否则会呈现问题。
个别对应图是

compression-webpack-plugin 是 8.x,则 webpack 须要 5.x
compression-webpack-plugin 是 7.x,则 webpack 须要 5.x
compression-webpack-plugin 是 6.x,则 webpack 须要 4.x 或者 5.x
compression-webpack-plugin 是 5.x,则 webpack 须要 4.x 或者 5.x

比方你我的项目中的 webpack 是 4.x 的,那么 compression-webpack-plugin 只能用 5 和 6 的。不能用 7 和 8 版本的。

以 vue-cli3.x 为例。

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


... 其余代码
configureWebpack:{
  plugins:[
    new CompressionWebpackPlugin({test: /\.(js|css)?$/i, // 哪些文件要压缩
      filename: "[path][base].gz", // 压缩后的文件名
      algorithm: "gzip", // 应用 gzip 压缩
      threshold: 10240, // 大于 10240 字节,既 10k 时
      minRatio: 0.8,  // 压缩率
      deleteOriginalAssets: true, // 是否删除本来的 js
    });
  ]
}
... 其余代码

先来解释下 CompressionWebpackPlugin 选项中的几个参数的含意。

1、test:是个正则表达式,示意哪些文件须要压缩。这里咱们抉择以.js 和.css 结尾的文件。这样的话上面的文件都在范畴内。


2、filename:示意压缩之后的文件名,后缀必须为.gz(是 gzip 的文件格式),path 和 base 示意,会在压缩时,把源文件的名称和门路都携带上。比方

index.9b65b390.js   // 须要压缩的源文件
index.9b65b390.js.gz   // 压缩之后的文件。

3、algorithm:压缩形式。

个别能够抉择 gzip 和 brotliCompress 两种,brotliCompress 稍后会说到。

4、threshold:压缩阈值

示意文件的大小超过定义的字节,就会压缩

threshold: 10240 示意,超过 10240 个字节,也就是超过 10k 是压缩。

5、minRatio 这个没试出来怎么个用法,前面补充。

6、deleteOriginalAssets:示意是否删除源文件。

网上百分之 90 全写的 false。

那么咱们如果有两个文件

index.9b65b390.js  
index.9b65b390.js.gz 

如果 deleteOriginalAssets:true, 最初只残余 index.9b65b390.js.gz

成果是这样的

最初查看 dist,曾经从原来的 37M,降到了 19M

而如果 deleteOriginalAssets 为 false,那么最终的源文件和 gz 文件都在。

最初查看 dist,发现比我没压缩前的 37M 都大。达到了 41M

那我图啥呢?图 37M 不够大吗?

所以如果咱们想要让 dist 变小,那就必须选 deleteOriginalAssets 为 true。
然而留神一点,在 development 模式下,这个要 false,不然浏览器会报错,空白页面。

二、nginx

前端打包好 gz 后,还须要后端进行配置,以 nginx 为例。
只须要加一行代码即可。

有的敌人会说。”gzip true” 也能够呀。

没错,gzip true 的确能够。像这样

然而 gzip 是动静压缩,比方你的接口返回大量数据或者返回动态的大 js 文件。服务器会杜绝你 gzip_min_length 的配置,去实时压缩,而后给你返回。在这个过程中,服务器是要耗费性能和资源的。你压缩的越小。服务器解决的越慢,相应的你 http 会期待更长。

而 gzip_static 是指,间接从服务器下来找.gz 的文件。如果有间接返回。没有就退而求其次找源文件。这个过程,服务器响应是很疾速的。

你也能够都配置上。gzip_static 优先于 gzip

location / {
       root   html;
       index  index.html; 
       gzip_static on; 
}


gzip  on;
gzip_min_length 10k;
gzip_comp_level 1;
gzip_types text/plain application/json application/javascript text/css;
gzip_vary on;


关上浏览器咱们能够看到 content-encoding 为 gzip,文件大小为 4.2M,比咱们刚开始没压缩的 13M 小了太多了。

最初,gz 的文件返回后,不须要显式的解决,浏览器会主动解压。

查看浏览器咱们发现,Accept-Encoding 定义的浏览器能够承受的压缩格局为 gzip, deflate, br 三种。而服务器返回给咱们的格局是 Content-Encoding:gzip,这 OK,浏览器能够解决。


你鼠标放到 4.2M 这个地位上,会有个相似于 title 的货色,提醒只有 4.2M 是通过网络传输的。然而实际上源文件有 13.9M。

三、Brotli

方才在 CompressionWebpackPlugin 中说 algorithm 时,除了 gzip,还有个压缩形式,那就是 brotli。

它是一种更加高效的压缩形式。而且各大浏览器根本都反对,然而也严格,须要 https 才能够,http 中不反对 Brotli,


上面是 vue 的配置

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

... 其余代码
configureWebpack:{
  plugins:[
    new CompressionWebpackPlugin({test: /\.(js|css)?$/i, 
      filename: "[path][base].br",
      algorithm: "brotliCompress", 
      threshold: 10240, 
      minRatio: 0.8, 
      deleteOriginalAssets: true, // 是否删除本来的 js
      compressionOptions: {
          params: {[zlib.constants.BROTLI_PARAM_QUALITY]: 11,
          },
      },
    });
  ]
}
... 其余代码

压缩后,咱们发现,比方才 gzip 压缩的更小

整个 dist 的大小,从 gzip 的 19M,放大到了 16M

而后设置 nginx 的配置。


location / {
       root   html;
       index  index.html; 
       brotli_static on; 
}


brotli on;  
brotli_comp_level 6;
brotli_buffers 16 8k;
brotli_min_length 20;
brotli_types *;  

留神下 nginx 默认没有 brotli 模块,须要装置,编译下(后端晓得怎么弄,前端不必关怀)

而后关上浏览器咱们会看到

退出移动版