gZip
GZIP是网站压缩加速的一种技术,对于开启后可以加快我们网站的打开速度,原理是经过服务器压缩,客户端浏览器快速解压的原理,可以大大减少了网站的流量。
在 http/1.0
协议中关于服务端发送的数据可以配置一个 Content-Encoding
字段,这个字段用于说明数据的压缩方法
Content-Encoding: gzip
Content-Encoding: compress
Content-Encoding: deflate
客户端在接受到返回的数据后去检查对应字段的信息,然后根据对应的格式去做相应的解码。客户端在请求时,可以用 Accept-Encoding
字段说明自己接受哪些压缩方法。
Accept-Encoding: gzip, deflate
Nginx
首先需要安装一个可以启动服务的容器,如tomcat、nginx 、node都可以,我这里使用的nginx作为代理服务器。
Nginx安装请自行百度,也可以参考我之前的文章 http://www.guofeian.cn/article_details/3#toc29。
优化之前的效果
这是我的博客后台加载的速度,打包后js、css 文件加载非常慢,一个简单的js文件就要4秒多。
优化后的效果
通过gzip和vite插件可以看到效果显著,不是半秒就渲染出来了。
服务端返回的类型
服务端响应请求时候压缩
当我们点击网页发送一个请求时候,我们的服务端会找到对应的文件,然后对文件进行压缩返回压缩后的内容【当然可以利用缓存减少压缩次数】,并配置好我们上面提到的 Content-Encoding
信息。
# 开启gzip
gzip on;
# 开启gzip_static
# gzip_static 开启后可能会报错,需要安装相应的模块, 具体安装方式可以自行查询
# 只有这个开启,vue文件打包的.gz文件才会有效果,否则不需要开启gzip进行打包
gzip_static on;
gzip_proxied any;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
gzip_buffers 4 16k;
#如果nginx中使用了多层代理 必须设置这个才可以开启gzip。
gzip_http_version 1.0;
# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间
gzip_comp_level 2;
# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary off;
gzip_disable "MSIE [1-6]\.";
应用构建时候压缩
既然服务端都可以做了为什么 webpack
在打包前端应用时候还有这样一个压缩插件呢,我们可以在上面 nginx
配置中看到 gzip_comp_level 2
这个配置项,上面也有注释写道 1-10
数字越大压缩效果越好,但是会耗费更多的CPU和时间,我们压缩文件除了减少文件体积大小外,也是为了减少传输时间,如果我们把压缩等级配置的很高,每次请求服务端都要压缩很久才回返回信息回来,不仅服务器开销会增大很多,请求方也会等的不耐烦。但是现在的 spa
应用既然文件都是打包生成的,那如果我们在打包时候就直接生成高压缩等级的文件,作为静态资源放在服务器上,接收到请求后直接把压缩的文件内容返回回去的。
webpack的压缩插件
compression-webpack-plugin:https://www.npmjs.com/package/compression-webpack-plugin
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
publicPath: './',
productionSourceMap: false,
chainWebpack: config => {
config.resolve.alias.set('@', resolve('src'));
if (process.env.NODE_ENV === 'production') {
config.plugin('compressionPlugin')
.use(new CompressionPlugin({
// 压缩后的名称
filename: '[path].gz[query]',
// 压缩算法/函数
algorithm: 'gzip',
// 匹配规则
test: /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i,
// 仅处理大于此大小的文件,以字节为单位。
threshold: 8192,
// 仅处理压缩率高于此比率的资产
minRatio: 0.8,
// 是否删除原始资产
deleteOriginalAssets: true
}));
}
},
};
webpack
打包完成后生成打包文件外还会额外生成 .gz
后缀的压缩文件.
vite 的压缩插件
vite-plugin-compression:https://github.com/anncwb/vite-plugin-compression
import viteCompression from 'vite-plugin-compression';
export default {
build: {
// 设置最终构建的浏览器兼容目标。
target: "es2015",
// 打包输出目录
outDir: "dist",
// 指定生成静态资源的存放路径
assetsDir: "assets",
// 小于此阈值的导入或引用资源将内联为 base64 编码,以避免额外的 http 请求,设置为 0 可以完全禁用此项。
assetsInlineLimit: 4096,
// 源码映射
sourcemap:process.env.NODE_ENV === "development"; ? true : false,
terserOptions: {
compress: {
// 打包自动删除console
drop_console: true,
drop_debugger: true,
// 对代码压缩的次数,默认是1,压缩次数越多,时间越长
passes: 100,
},
},
// 设置为false禁用缩小,或指定要使用的缩小器。默认为Terser,它速度较慢,但在大多数情况下会生成较小的包。
// Esbuild 缩小速度明显更快,但会产生稍大的包。
minify: isDev ? "esbuild" : "terser",
// 启用/禁用 brotli 压缩大小报告。压缩大型输出文件可能会很慢,因此禁用它可能会提高大型项目的构建性能。
brotliSize: false,
// 块大小警告的限制(以 kbs 为单位),默认: 500
chunkSizeWarningLimit: 2000,
},
css: {
preprocessorOptions: {
less: {
// 解决andt less loader版本高的问题
javascriptEnabled: true,
},
},
},
plugins: [viteCompression({
ext: ".gz", // 生成的压缩包后缀
verbose: true, // 是否在控制台输出压缩结果
deleteOriginFile: true, // 压缩后是否删除源文件
})],
};
附上我的nginx配置
server {
listen 3000;
server_name localhost;
location ~ .*\.(js|json|css)$ {
gzip on;
gzip_static on;
gzip_proxied expired no-cache no-store private auth;
gzip_http_version 1.1;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 5;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary off;
gzip_disable "MSIE [1-6]\.";
}
location / {
root /data/;
try_files $uri $uri/ /index.html;
index index.html;
proxy_set_header Accept-Encoding "";
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 1m;
proxy_connect_timeout 1m;
}
location /api/ {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'POST,GET,OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Authorization';
rewrite ^/api/(.*) /$1 break;
proxy_pass xxxxx;
}
}
写在最后
当然前端的首屏优化也不止这一个,如 路由懒加载、组件按需引入、插件CDN引用、图片懒加载、css压缩、js压缩等,也可以让申请让公司加大网络带宽。
参考文章:
-
为什么要开启gZip:https://segmentfault.com/a/1190000012800222
-
Nginx中文文档:https://www.nginx.cn/doc/standard/httpgzip.html
-
https://blog.csdn.net/qq_41499782/article/details/118650279