构建与资源压缩优化
一、构建优化
Tree Shaking
1 | import _ from 'lodash'; // ❌ 全量导入,无法 tree-shaking |
在 webpack 4+ 中默认对 tree-shaking 进行了支持。
Split Chunks(代码分割)
1 | splitChunks({ |
webpack 4 内置的分割策略:
- 新的 chunk 是否来自 node_modules 或被共享
- 压缩前体积是否大于 30KB
- 按需加载并发请求数 ≤ 5 个
- 页面初始加载并发请求数 ≤ 3 个
拆包(CDN 外置)
将体积大且不变的三方库(react、vue 等)通过 CDN 加载,不打包进主 bundle:
1 | <script src="https://cdn.example.com/react@18.2.0.min.js"></script> |
1 | externals: { react: 'React', 'react-dom': 'ReactDOM' } |
Prefetch / Preload(魔术注释)
1 | import(/* webpackPrefetch: true */ './someModule'); |
逻辑后移
将主体内容的接口请求前移,非主体的请求后移,尽快渲染主要内容。
二、文件压缩
Gzip 压缩
gzip 对纯文本内容可压缩到原大小的 40%,但 png、jpg 等图片不推荐使用 gzip。
Nginx 配置:
1 | http { |
压缩原理
gzip 使用 Deflate 算法,先用 Lz77 算法压缩,再使用 Huffman 编码。
Lz77 原理:如果文件中有两块内容相同,用距离 + 相同长度这一对信息替换后一块内容。由于这对信息的大小小于被替换内容的大小,所以文件得到了压缩。
构建时预压缩
1 | const fs = require('fs'); |
开启 gzip 后,响应头中会出现 content-encoding: gzip。
Brotli 压缩
Brotli 由 Google 在 2015 年推出,使用预定义的 120KB 字典(包含 13000+ 常用单词和子字符串),对文本文件压缩通常比 gzip 增加 20% 的压缩密度。
1 | 请求头:Accept-Encoding: gzip, deflate, sdch, br |
目前 Brotli 只能在 HTTPS 下生效,主流 CDN 服务商已支持。