web性能优化之Gzip


最近开发活动页,启用了Lottie用于动画的播放,动画播放流畅了,但是发现动画的json资源很大,大点的都超过10M了,首页启动平均时间超过了10S,性能优化切实必行,精简请求资源大小是第一步,GZzip正是为此服务的。

gzip 是什么 ?

Gzip 是一种用于文件压缩和解压缩的算法与工具,全称是 “GNU zip”。它最初由 Jean-loup Gailly 和 Mark Adler 于 1992 年开发,作为 Unix 系统中的文件压缩程序。
Gzip 是一种无损压缩算法,它通过减少数据的冗余性来压缩文件大小,同时保证解压缩后的文件与原始文件完全一致。它使用 DEFLATE 算法,这是一种结合了 LZ77 和霍夫曼编码的压缩算法。

Gzip 在 Web 中的应用

在 Web 开发中,Gzip 压缩广泛用于减小静态文件(如 HTML、CSS、JavaScript、JSON、XML)和动态内容的大小。当浏览器向服务器请求资源时,服务器可以将这些文件以 Gzip 格式压缩后传输给浏览器,从而减少传输的数据量并加快页面加载速度。首先我们要了解什么是HTTP压缩。

HTTP压缩概述

HTTP压缩是在Web服务器和浏览器间传输压缩文本内容的方法。HTTP压缩采用通用的压缩算法如gzip等压缩HTML、JavaScript或CSS文件。压缩的最大好处就是降低了网络传输的数据量,从而提高客户端浏览器的访问速度。当然,同时也会增加一点点服务器的负担。Gzip是比较常见的一种HTTP压缩算法。

HTTP压缩工作原理


Web服务器处理HTTP压缩的工作原理如下:

  • 1.Web服务器接收到浏览器的HTTP请求后,检查浏览器是否支持HTTP压缩;
    在用户浏览器发送请求的HTTP头中,  带有”Accept-Encoding: gzip, deflate”参数则表明支持gzip和deflate两种压缩算法.
  • 2.如果浏览器支持HTTP压缩,Web服务器检查请求文件的后缀名;
    静态文件和动态文件后缀启动要所都需要在MetaBase.xml中设置.
    静态文件需要设置:   HcFileExtensions Metabase Property
    动态文件需要设置:   HcScriptFileExtensions Metabase Property
  • 3.如果请求文件是HTML、CSS等静态文件并且文件后缀启用了压缩,则Web服务器到压缩缓冲目录中检查是否已经存在请求文件的最新压缩文件;
  • 4.如果请求文件的压缩文件不存在,Web服务器向浏览器返回未压缩的请求文件,并在压缩缓冲目录中存放请求文件的压缩文件;
  • 5.如果请求文件的最新压缩文件已经存在,则直接返回请求文件的压缩文件;
  • 6.如果请求文件是ASPX等动态文件并且文件后缀启用了压缩,Web服务器动态压缩内容并返回浏览器,压缩内容不存放到压缩缓存目录中。

    Gzip 有多优秀 ?

开启 gzip 压缩前:

开启 gzip 压缩后(Tomcat):

生成Gzip

webpack构建支持Gzip

在 Webpack 中,可以通过插件来支持生成 Gzip 压缩文件,最常用的是 compression-webpack-plugin。这个插件会在构建时为生成的文件创建对应的 .gz 文件。

以下是配置 Webpack 生成 Gzip 压缩文件的步骤:

1. 安装 compression-webpack-plugin

首先,你需要安装 compression-webpack-plugin

1
npm install compression-webpack-plugin --save-dev

或者使用 Yarn:

1
yarn add compression-webpack-plugin --dev
2. 配置 Webpack

在 Webpack 配置文件(例如 webpack.config.js)中使用 compression-webpack-plugin 来生成 Gzip 压缩文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const CompressionPlugin = require('compression-webpack-plugin');

module.exports = {
// 其他配置
plugins: [
new CompressionPlugin({
filename: '[path][base].gz', // 生成的 gzip 文件名
algorithm: 'gzip', // 使用 gzip 压缩
test: /\.(js|css|html|svg)$/, // 匹配哪些文件进行压缩
threshold: 10240, // 只有大小超过 10KB 的文件才会被压缩
minRatio: 0.8, // 只有压缩比小于这个值的文件才会被生成 gzip
})
],
// 其他配置
};
3. 选项说明:
  • filename: 生成的 Gzip 文件名,默认是 [path][base].gz,即在原文件的路径和名称后加上 .gz 后缀。
  • algorithm: 使用的压缩算法,这里指定为 gzip。你也可以选择 brotliCompress 来生成 Brotli 文件。
  • test: 指定要压缩的文件类型,通常包括 .js.css.html.svg 等。
  • threshold: 只有文件大小超过这个值时,才会进行压缩,单位为字节。默认是 10KB。
  • minRatio: 只有压缩比低于此值时,才生成对应的 .gz 文件。比如 0.8 表示压缩后的文件大小至少是原始文件的 80%。

    Vite构建支持Gzip

    在 Vite 中构建时,支持 Gzip 压缩是通过配置插件来实现的。Vite 本身并不会自动生成 Gzip 文件,但可以使用插件如 vite-plugin-compression 来实现 Gzip 压缩支持。以下是具体步骤:
    1. 安装 vite-plugin-compression
    首先,在你的项目中安装 vite-plugin-compression,这是一个用于生成 Gzip 压缩文件的插件。
    1
    npm install vite-plugin-compression --save-dev
    或者使用 Yarn:
    1
    yarn add vite-plugin-compression --dev
    2. 配置 Vite
    接下来,在 Vite 的配置文件 vite.config.js 中引入并使用这个插件。这个插件会在 Vite 构建的过程中生成 .gz 压缩文件。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import { defineConfig } from 'vite';
    import viteCompression from 'vite-plugin-compression';

    export default defineConfig({
    plugins: [
    viteCompression({
    verbose: true, // 是否在控制台输出压缩结果
    disable: false, // 是否禁用插件
    threshold: 10240, // 只有大于这个大小的文件才会压缩,单位是字节,默认值为 10240 (10kb)
    algorithm: 'gzip', // 使用 gzip 压缩
    ext: '.gz', // 生成的压缩包后缀
    })
    ]
    });
配置项说明:
  • verbose: 是否在构建时在控制台输出哪些文件被压缩。
  • disable: 是否禁用该插件,默认值为 false
  • threshold: 只有文件大小大于指定值时,才会生成压缩文件,单位是字节(默认 10KB)。
  • algorithm: 压缩算法,默认为 gzip,你也可以使用 brotliCompress 来生成 Brotli 压缩文件。
  • ext: 压缩文件的后缀名,默认是 .gz

    Linux手动生成Gzip文件

    在 Linux 中,gzip 是一个常用的压缩命令,用于压缩文件。它会将原始文件压缩为 .gz 格式。以下是一些常见的 gzip 命令使用方法:
    1. 压缩文件
    将指定文件压缩为 .gz 格式:
    1
    gzip filename
  • 例如,将 test.txt 压缩为 test.txt.gz
    1
    gzip test.txt
    2. 解压文件
    使用 gzip -dgunzip 来解压 .gz 文件:
    1
    2
    3
    gzip -d filename.gz
    # 或者
    gunzip filename.gz
  • 例如,解压 test.txt.gz
    1
    2
    3
    gzip -d test.txt.gz
    # 或者
    gunzip test.txt.gz
3. 保留原文件的压缩

如果你希望压缩文件时保留原文件,可以使用 -k 选项:

1
gzip -k filename
  • 例如,将 test.txt 压缩为 test.txt.gz,并保留 test.txt 原文件:
    1
    gzip -k test.txt

进阶用法

4. 压缩目录

gzip 不能直接压缩目录,但可以先使用 tar 打包目录,再使用 gzip 压缩:

1
tar -czvf archive.tar.gz directory_name
  • -c:创建压缩文件
  • -z:通过 gzip 进行压缩
  • -v:显示压缩过程中的详细信息
  • -f:指定输出文件名

例如,压缩 myfolder 目录:

1
tar -czvf myfolder.tar.gz myfolder
5. 查看压缩比

使用 -l 选项来查看 .gz 文件的压缩信息,包括原文件大小、压缩文件大小、压缩比等:

1
gzip -l filename.gz
  • 例如,查看 test.txt.gz 的压缩比:
    1
    gzip -l test.txt.gz

6. 递归压缩目录中的所有文件

使用 find 命令与 gzip 结合,递归压缩目录下所有文件:

1
find directory_name -type f -exec gzip {} \;
  • 例如,压缩 myfolder 目录下的所有文件:
    1
    find myfolder -type f -exec gzip {} \;
7. 指定压缩级别

gzip 提供了从 1 到 9 的压缩级别,数字越大压缩率越高,但速度越慢。默认压缩级别是 6。

  • 快速压缩(较低压缩比)
    1
    gzip -1 filename
  • 最大压缩(较慢速度)
    1
    gzip -9 filename
8. 压缩多个文件

如果你有多个文件想要压缩为单独的 .gz 文件,可以一次性传递多个文件名:

1
gzip file1 file2 file3
  • 例如,压缩 file1.txtfile2.txt
    1
    gzip file1.txt file2.txt
9. 检查文件完整性

你可以使用 -t 选项来测试 .gz 文件的完整性:

1
gzip -t filename.gz
10. 重定向输出到标准输出

使用 -c 选项将压缩结果输出到标准输出(stdout),可以与其他命令配合使用:

1
gzip -c filename > output.gz

配置服务器处理 Gzip 文件

虽然 Vite 可以生成 Gzip 或 Brotli 文件,但为了让浏览器请求这些文件时生效,你需要配置 Web 服务器来处理它们。例如,如果你使用 Nginx,可以按以下方式配置:

Nginx 配置:
1
2
3
4
5
6
7
8
server {
gzip on;
gzip_types text/plain application/json application/javascript text/css image/svg+xml;
gzip_static on; # 自动提供 .gz 文件
location / {
try_files $uri $uri.gz $uri.html =404;
}
}

这会告诉 Nginx 优先提供 .gz 文件,并自动检测是否存在这些压缩文件。

Apache 配置示例:

如果使用 Apache,可以通过启用 mod_rewritemod_headers 模块来处理 Gzip 文件。

1
2
3
4
5
6
7
8
9
10
11
# 启用 Gzip 静态文件
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.*)$ $1.gz [QSA]

# 设置正确的 Content-Encoding 头
<FilesMatch "\.gz$">
Header set Content-Encoding gzip
Header set Cache-Control "max-age=31536000"
</FilesMatch>

在浏览器中检测 Gzip 压缩

构建完成并配置好服务器后,你可以通过浏览器的开发者工具或者线上工具(如 Gzip Test)来检查 JSON 文件是否成功启用了 Gzip 压缩。。在响应头中,Content-Encoding: gzip 表示服务器成功返回了 Gzip 压缩的内容。

也可以使用 curl 命令来测试:

1
curl -I -H "Accept-Encoding: gzip" https://your-domain.com/bundle.js

如果 Gzip 压缩有效,你应该会看到类似如下的响应头:

1
Content-Encoding: gzip


我们通过Http头中的: 属性判断返回后的数据已经启用了gzip压缩:

注意:如果未收到gzip的返回,需要看下服务器端的gzip_types是否支持你访问的文件类型

Gzip兼容性

所有主流浏览器都支持 Gzip 压缩。这意味着如果服务器返回 Gzip 压缩的资源,浏览器可以自动解压缩并呈现页面。

Gzip 支持非常广泛,从早期版本的浏览器(如 Internet Explorer 6)到现代浏览器都默认支持它,因此从浏览器兼容性的角度来看,使用 Gzip 是非常安全的。

Gzip 支持的文件类型

虽然 Gzip 对大多数文本内容(如 HTML、CSS、JavaScript、JSON 等)压缩效果显著,但某些文件类型并不适合使用 Gzip。一般来说,Gzip 适合以下类型的文件:

  • HTML、CSS、JavaScript:这些是最常压缩的文件类型,压缩率通常在 60%-80% 左右。
  • JSON 和 XML:用于 API 的数据格式,压缩率较高。
  • SVG:虽然是图像文件,但由于它是 XML 格式,压缩率也较好。

不适合 Gzip 压缩的文件类型包括:

  • 图片(如 JPEG、PNG、GIF 等):这些文件通常已经压缩,再次使用 Gzip 压缩效果不佳,甚至可能导致文件体积增大。
  • 视频和音频文件(如 MP4、MP3 等):这些多媒体文件已经过压缩,使用 Gzip 无效。
  • PDF 文件:PDF 文件通常也已压缩,再使用 Gzip 可能没有显著效果。

总结

Gzip 是一种高效、广泛兼容的压缩算法,在提升网站性能方面表现突出。
适用于大多数文本文件,特别是在 Web 环境中压缩 HTML、CSS、JavaScript、JSON 等资源文件,能够显著缩短页面加载时间并节省带宽。
现代浏览器和服务器均支持 Gzip,因此在大多数 Web 应用中使用 Gzip 压缩是安全且高效的性能优化方案。

因此,在大多数网站和 Web 应用中,启用 Gzip 压缩是提升性能的最佳实践之一。