web性能优化(二):文件压缩

压缩了吗?

以当前页面为例,按F12打开控制台,打开网络(Network),刷新一下页面,然后打开Content-Encoding显示,就可以在接口对应的属性列看到gzip、br等值:
FYuX.png

  • Content-Encoding:HTTP协议中用来指示资源文件经过编码处理以减小传输大小时所用的编码格式。
  • 常见的Content-Encoding值:
    1. gzip:表示内容使用GNU zip算法进行了压缩。
    2. compress:表明内容采用了Unix compress程序进行压缩,现在较少使用。
    3. deflate:表示内容使用zlib格式进行了压缩。
    4. br:表示内容使用Brotli算法进行了压缩。
    5. identity或空白:表示内容没有被编码或压缩,是原始格式。

怎么压缩?

nginx压缩

在Nginx中,压缩前端静态文件主要是通过gzip模块实现的。这个模块可以对服务器响应给客户端的内容进行实时压缩或使用预先生成的.gz压缩文件(即静态压缩)。以下是两种配置方法:

动态压缩(实时压缩)

动态压缩是Nginx在接收到客户端请求时,根据配置自动将HTML、CSS、JavaScript等文本类型的静态资源内容压缩后再发送给客户端。配置如下:

1
2
3
4
5
6
7
8
9
http {
gzip on; # 开启gzip压缩功能
gzip_types text/plain text/css application/json application/javascript text/xml application/xml+rss text/javascript; # 配置需要压缩的MIME类型
gzip_comp_level 6; # 压缩级别,默认1-9,数值越大压缩率越高,但消耗CPU资源也越多
gzip_vary on; # 启用Vary头部,以便代理服务器正确处理缓存
gzip_min_length 256; # 设置允许压缩的最小响应内容长度,避免小文件压缩反而增大开销

# 其他可能的配置项...
}

静态压缩

静态压缩是指提前把静态资源文件压缩成.gz格式,然后Nginx会优先查找并直接返回这些预压缩文件,如果找不到.gz文件,则返回未压缩的源文件。

配置静态压缩的方法通常是在location块中启用gzip_static模块:

1
2
3
4
5
6
7
8
location / {
gzip_static on; # 开启静态压缩,优先返回.gz文件
gunzip on; # 如果有需要解压的情况,可以开启gunzip模块以支持解压
expires 30d; # 可设置缓存过期时间,对于静态资源很有用
# 其他可能的配置项...
}

# 确保Nginx能找到.gz文件,例如在同一个目录下与原文件名相同只是扩展名为.gz

前期的压缩,我们一般在构建产物时进行,比如说在Umi.js项目中,对文件进行压缩通常涉及两方面的内容:前端资源(如JavaScript、CSS)的Gzip压缩以及整体项目的打包压缩。

1. 前端资源Gzip压缩:

  1. Gzip压缩:为了减小静态资源在网络传输中的大小,可以使用compression-webpack-plugin插件在webpack构建过程中生成gzip压缩过的资源。在Umi.js项目的配置文件(通常是.umirc.tsconfig/config.ts)中添加该插件配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // .umirc.ts 或 config/config.ts
    import CompressionWebpackPlugin from 'compression-webpack-plugin';

    export default {
    chainWebpack(config, { env }) {
    if (env === 'production') {
    config
    .plugin('compression')
    .use(CompressionWebpackPlugin, [{
    filename: '[path].gz[query]',
    algorithm: 'gzip',
    test: /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i,
    threshold: 10240, // 只有大于这个值的资源会被压缩
    minRatio: 0.8, // 最小压缩比达到这个值才会被压缩
    deleteOriginalAssets: false, // 是否删除原文件,默认为false,不删除
    }]);
    }
    },
    };

    注意版本匹配,确保使用的compression-webpack-plugin是与当前项目兼容的版本。

2. 整体项目打包压缩:

  • 项目文件压缩为ZIP包:若要将整个dist目录下的文件压缩成一个ZIP包,可以使用filemanager-webpack-plugin插件。例如,在Umi.js v2.x版本中,你可以在配置文件中加入该插件以实现此功能。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    // 安装插件
    npm install filemanager-webpack-plugin --save-dev

    // 在配置文件中引入并配置
    import FileManagerPlugin from 'filemanager-webpack-plugin';

    export default {
    configureWebpack: {
    plugins: [
    new FileManagerPlugin({
    onEnd: {
    archive: [
    {
    source: './dist', // 要压缩的源文件夹
    destination: './dist/dist.zip', // 输出的zip文件路径
    format: 'zip', // 压缩格式
    },
    ],
    },
    }),
    ],
    },
    };

    根据实际需要调整插件的配置项。

注意事项:

  • 在部署时,确保服务器(如Nginx)已经正确配置了支持发送Gzip压缩后的资源给客户端。
  • 对于大型项目,优化构建速度也是重要的一环,可以考虑代码分割、懒加载等策略来减少主包体积,并结合上述压缩方法进一步优化。

CDN

压缩是需要重新编码的,这必然会消耗一部分服务器性能,并且还要进行麻烦的配置。部署个人网站,比如说这个博客时,我选择无脑交给云服务提供商来解决。

我的部分网站使用了阿里云提供的的CDN服务,在对应域名的配置中,有“性能优化”相关一栏,我选择全部开启:
FEic.png
原理大概是CDN服务器在回源拿到资源后,会对这些资源进行编码压缩然后再分发。反正是免费功能,就不占用我自己的服务器资源了。缺点可能是回源的速度会慢一些,但我的静态网站更新频率也不会太高,所以问题不大!