使用 Vite 拆分供应商块并异步加载它们

2025-06-07

使用 Vite 拆分供应商块并异步加载它们

你的网站数据块最近怎么样?需要瘦身吗?

让我们看看如何拆分供应商块并减小其大小。允许浏览器加载较小的块并异步加载它们。我将使用一个个人项目来演示。堆栈如下:

这同样适用于 Vite 的任何其他 JS 框架。它也可能适用于 Webpack,请参阅文档了解具体方法。

请参阅我的其他文章

开发词中的块是什么?

前端开发人员通常会接触 .ts、.vue 和 .tsx 文件,但浏览器无法识别它们。为此,浏览器需要将这些文件转换为 .js 文件,甚至可以进行优化,通常使用构建命令。

虽然所有开发文件都可以转换为单个 .js 文件,但由于性能影响,我们不建议这样做。理想情况下,这些文件应该转换为多个 .js 文件(分块),以便在需要时加载它们——考虑到用户导航。

所以,简而言之,块是 .js 文件,它们共同定义整个前端系统。

当前项目包

首先,让我们看看这个项目是什么样子的:

包含所有第三方的巨大 index.js 文件

可以看到,项目中有一些js文件,我们重点看一下index.hash.js

通常,Vite、Wepack 等工具会创建两个主要的 chunk 文件:index.hash.jsvendor.hash.js

  • index:里面存放的是关键的应用代码,比如App.tsx的代码;
  • 供应商:所有生产依赖项(package.json > 依赖项);

等等。为什么 gif 中没有 vendor 代码块?Vite 从 2.9 版本开始就移除了这种行为。现在,默认情况下,索引中也包含了生产依赖的代码。

通过使用 Rollup Plugin Visualizer,我们可以更轻松地查看项目包的交互式图表:

没有供应商 js 文件的捆绑包屏幕截图

如您所见,有一个巨大的索引块。

我们可以做的第一件事是将核心内容与第三方内容分离,通过添加modulepreload 属性,浏览器可以异步下载这两个文件。

但在继续之前,请查看当前索引大小(255.35 kb):

当前索引大小

将索引块拆分为两个块并异步加载

尽管 Vite 默认不拆分它们,但它提供了一个插件来为您完成此操作:



import { splitVendorChunkPlugin } from 'vite';

export default defineConfig({
  plugins: [
    react(),
    splitVendorChunkPlugin()
]})


Enter fullscreen mode Exit fullscreen mode

Vite 为您完成剩下的工作。

带有索引和供应商块

供应商大小:239.95kb
索引大小:15.90kb

好吧,我们可以看到第三方包是如何影响这个项目的。


喜欢吗?如果喜欢,别忘了点个赞❤️_ 并关注我获取最新资讯。之后我会继续创作更多类似的内容_


将供应商块拆分成更多块

当我们弄清楚谁是坏人时,让我们尝试将供应商块分成更小的块。

为此,我们将使用Rollup 提供的manualChunk 函数。但在此之前,我们必须决定从主 vendor chunk 中移除哪些文件(?),而这正是问题的关键所在……再次查看我们的 bundle,我们发现一些(与其他包相比)体积巨大的包,例如 react-dom,但在本文中,我将从 vendor chunk 中创建另外两个文件:

  • @open-ish
  • @react-router

为什么?因为我们有一个 vendor chunk,它可能包含一些依赖项,这些依赖项必须按正确的顺序加载,因为有些依赖项可能会用到其他依赖项,否则你的应用程序可能无法正常工作。这是手动创建 chunk 最难的部分:知道哪些依赖项必须位于同一个 chunk 中,这取决于你正在开发的应用程序。就我的项目而言,我知道这些依赖项必须位于同一个 chunk 中:“react-router-dom”、“@remix-run”和“react-router”。

那么让我们看看拆分它们的代码:



import { splitVendorChunkPlugin } from 'vite';

export default defineConfig({
  plugins: [
    react(),
    splitVendorChunkPlugin()
],
 build: {
    rollupOptions: {
      output: {
        manualChunks(id: string) {
          // creating a chunk to @open-ish deps. Reducing the vendor chunk size
          if (id.includes('@open-ish') || id.includes('tslib')) {
            return '@open-ish';
          }
          // creating a chunk to react routes deps. Reducing the vendor chunk size
          if (
            id.includes('react-router-dom') ||
            id.includes('@remix-run') ||
            id.includes('react-router')
          ) {
            return '@react-router';
          }
        },
      },
    },
  },
})


Enter fullscreen mode Exit fullscreen mode

通过此代码,Rollup 将创建两个新的块:

捆绑两个新块

现在,比较一下供应商块大小:

使用手动块函数后构建

供应商大小:211.94kb

可以看到,我们将最大的块从 255.35kb 缩减到了 211.94kb(约 18%)。这听起来可能不算多,但这只是拆分块并创建更小块的开始,甚至还提供了与浏览器异步加载的可能性。

现在看看我们的应用程序如何加载(重点关注瀑布图):

最终捆绑包

它们同时开始加载,你看到了吗?

请我喝杯咖啡☕。希望我能帮到你。🤗

结论

在本文中,您了解了更多有关块的知识,以及如何使用 Vite/Rollup 拆分它们并异步加载它们。

尽管代码本身很简单(感谢 Vite/Rollup),但最困难的是确定哪些依赖项必须在同一个块中。

稍后我可能会创建此内容的第二部分,进一步拆分供应商块。

请参阅我的其他文章

文章来源:https://dev.to/tassiofront/splitting-vendor-chunk-with-vite-and-loading-them-async-15o3
PREV
使用对象文字 - [en-US] 替换您的 switch 语句和多个“if and else”。
NEXT
掌握代码审查:审查人员和 PR 创建者的指南