产物体积优化

产物体积的优化在生产环境中是非常重要的,因为它直接影响到了线上的用户体验。在这篇文档中,我们将介绍在 Rsbuild 中一些常见的产物体积优化方式。

减少重复依赖

在 Web 项目中,经常出现某些第三方依赖被打包了多个版本的现象。重复依赖会导致包体积变大、构建速度变慢。

检测重复依赖

你可以使用 Rsdoctor 来检测项目中是否存在重复依赖,Rsdoctor 会在构建过程中进行分析,找出所有重复打包的依赖包,并可视化展示出来:

详见 Rsdoctor - 重复依赖问题

消除重复依赖

我们可以通过一些配置项和工具来检测或消除重复依赖。

  • Rsbuild 提供了 resolve.dedupe 配置项,它允许你强制从项目根目录解析指定的包,从而移除重复包。

  • 如果你在使用 pnpm >= 7.26.0,可以使用 pnpm 自带的 pnpm dedupe 命令来升级和消除其中的重复依赖。

pnpm dedupe
  • 如果你在使用 pnpm < 7.26.0 版本,可以使用 pnpm-deduplicate 来分析出所有的重复依赖,并通过升级依赖或声明 pnpm overrides 进行版本合并。
npx pnpm-deduplicate --list
  • 如果你在使用 yarn,可以使用 yarn-deduplicate 来自动合并重复依赖:
npx yarn-deduplicate && yarn

使用更轻量的库

建议将项目中体积较大的三方库替换为更轻量的库,比如将 moment 替换为 day.js

如果你需要找出项目中体积较大的三方库,可以在执行构建时添加 BUNDLE_ANALYZE=true 环境变量:

BUNDLE_ANALYZE=true pnpm build

详见 performance.bundleAnalyze 配置项。

提升 Browserslist 范围

Rsbuild 会根据项目的 Browserslist 配置范围进行代码编译,并注入相应的 Polyfill。如果项目不需要兼容旧版浏览器,可以根据实际情况来提升 Browserslist 范围,从而减少在语法和 Polyfill 上的编译开销。

Rsbuild 默认的 Browserslist 配置为:

['chrome >= 87', 'edge >= 88', 'firefox >= 78', 'safari >= 14'];

比如只兼容 Chrome 100 以上的浏览器,可以改成:

['Chrome >= 100'];
TIP

请阅读 设置浏览器范围 章节来了解更多关于 Browserslist 的用法。

按需引入 polyfill

如果当前项目的 output.polyfill'entry',在明确第三方依赖不需要额外 polyfill 的情况下,你可以将它设置为 usage

usage 模式下,Rsbuild 会分析源代码中使用的语法,按需注入所需的 polyfill 代码,从而减少 polyfill 的代码量。

export default {
  output: {
    polyfill: 'usage',
  },
};
TIP

请阅读 浏览器兼容性 章节来了解更多关于 polyfill 的用法。

使用图片压缩

在一般的前端项目中,图片资源的体积往往是项目产物体积的大头,因此如果能尽可能精简图片的体积,那么将会对项目的打包产物体积起到明显的优化效果。你可以在 Rsbuild 中注册插件来启用图片压缩功能:

rsbuild.config.ts
import { pluginImageCompress } from '@rsbuild/plugin-image-compress';

export default {
  plugins: [pluginImageCompress()],
};

详见 @rsbuild/plugin-image-compress

代码拆包

良好的拆包策略对于提升应用的加载性能是十分重要的,可以充分利用浏览器的缓存机制,减少请求数量,加快页面加载速度。

在 Rsbuild 中内置了多种拆包策略,可以满足大部分应用的需求,你也可以根据自己的使用场景,自定义拆包配置。

比如将 node_modules 下的 axios 库拆分到 axios.js 中:

export default {
  performance: {
    chunkSplit: {
      strategy: 'split-by-experience',
      forceSplitting: {
        axios: /node_modules[\\/]axios/,
      },
    },
  },
};