
Webpack 的 Storybook 延迟编译
大型 Storybook 项目的闪电般快速本地开发体验

Storybook 是一个 UI 代码的构建、测试和文档编写车间环境。Shopify、Workday、Adobe、The Guardian 等众多团队都在使用它来交付健壮的 UI。
随着 Storybook 使用量的增长,性能已成为首要任务。我们 6.x 版本系列的核心主题是重构 Storybook 以减少构建和加载时间。我们首先优化了已发布的 Storybook,现在它们的加载速度快了 4 倍。现在,我们将重点转移到改善本地开发体验。
我很高兴地宣布,Storybook 6.5 将在开发模式下提供延迟编译。Storybook 将仅编译核心运行时以快速启动,然后在你访问它们时构建故事。这意味着大型 Storybook 项目的即时启动和闪电般快速的重建。请继续阅读以了解它是如何工作的。

性能路线图
在开始之前,让我们先了解一下到目前为止的性能更新。Storybook 由构建器(如 Webpack)提供支持,这些构建器会处理和打包你的代码 — Javascript、TypeScript、CSS、MDX,甚至框架特定的文件,如 Vue 或 Svelte SFCs。我们认为优化构建器是 Storybook 性能提升的巨大机会。
Storybook 6.1 为提高速度和加载时间奠定了基础。它弃用了 Webpack DLL,然后预构建并缓存了管理器以提高构建时间。
随后在 6.2 版本中进行了重大的架构重组,使 Storybook 能够支持 Vite、Snowpack 等现代构建器。虽然有些团队可以利用这一点,但大多数 JavaScript 社区仍然依赖 Webpack,这需要进一步优化。在 6.4 版本中,我们与 Webpack 和 Shopify UX 工程团队合作,对 Storybook 的运行时操作方式进行了关键更改 —按需架构。

以前,Storybook 将你所有的故事打包成一个大捆绑包。Storybook 6.4 采用代码分割为每个故事创建单独的捆绑包并异步加载它们。直接影响是捆绑包大小减小了 3 倍,这意味着已发布的 Storybook 加载速度快了 4 倍。
尽管如此,到目前为止的改进主要限于生产构建 — `build-storybook` 的静态输出。它们对那些将 Storybook 发布到云端的人来说影响最大。但 Storybook 主要是一个你本地运行的开发工具。每次保存时需要花费多少时间来重建?
加速开发中的构建
在构建组件时,你必须先等待 Storybook 启动。然后每次保存时,你必须再次等待它重建故事。这就是为什么 Storybook 6.5 的一个重要目标是利用 Webpack 的延迟编译和文件缓存功能来提供更快的开发体验。

什么是文件系统缓存?
Webpack 5 引入了持久的文件系统缓存功能,允许它利用先前构建的信息来跳过不必要的步骤。
它的工作原理是在 Storybook 运行之间缓存构建输出。然后在后续运行中,如果相关代码没有更改,Webpack 可以重用构建产物。最终,这意味着所有 Storybook 项目(无论大小)的更快的启动和重建。
什么是延迟编译?
延迟编译是一项由 Next.js 等工具率先推出的开发时间功能,它将页面的内容组装推迟到需要时。其思想是你的应用程序可能有许多路由,但在任何给定的开发会话中,你可能只会访问其中几个,所以为什么要提前花费编译所有路由的成本呢?
当你启动开发服务器时,构建器会做一些工作来启动运行时,并且启动速度非常快。
然后,当你第一次开始处理你应用程序的某个路由时,你会在浏览器中访问它。正是在这个时刻,构建器会编译它。当你导航到另一个路由时,你必须等待一小段时间(一两秒,具体取决于你的应用程序/路由的复杂程度)才能进行编译。

故事的延迟编译
我们将相同的体验带到 Storybook,只不过我们使用 CSF 文件作为编译点,而不是路由。
在典型的开发会话中,你只会访问 Storybook 中一小部分的故事。限制编译成本只编译那几个故事是明智的 — 特别是对于拥有数百个组件的大型项目。Storybook 使用 Webpack 延迟生成故事捆绑包。
启动 Storybook 可以快速启动,因为它只需要构建加载和渲染故事所需的画布运行时。
当你访问第一个故事时,Storybook 将仅编译其代码 — CSF 文件和组件。
启动性能
你会看到中小型项目的启动时间有边际改善。但是延迟编译极大地减少了 Storybook 在大型项目上启动所需的时间。


热缓存启动性能
延迟编译与文件系统缓存结合使用时效果最佳。构建输出被缓存,从而加快了后续的启动时间。


重建性能
仅编译最少数量的故事捆绑包的一个额外好处是,当你在修改组件或故事时,Webpack 通常需要做的工作要少得多才能更新编译后的代码。
我们可以在下面的时间表中看到这些好处。


试用一下
延迟编译现已在 6.5 beta 版中提供。只需一分钟即可试用,你可以在项目的根目录下运行以下命令
npx sb upgrade --prerelease如果你还没有使用 Storybook,很容易上手
npx sb@next init然后通过安装 `@storybook/builder-webpack5` 和 `@storybook/manager-webpack5` 包来选择加入 Webpack 5 构建器。
最后,在你的 Storybook 配置中启用它
// .storybook/main.js
module.exports = {
features: {
storyStoreV7: true,
},
core: {
builder: {
name: 'webpack5',
options: {
lazyCompilation: true,
fsCache: true,
}
}
},
};Storybook 性能的下一步
我们希望继续提高 Storybook 的性能,无论是对于大型项目还是小型项目。我们将研究的一些策略
- 预测性预取以缩短“下一故事的时间”:Storybook 将预测你可能接下来要处理的故事,并预取和预编译其代码。
- 缓存 Storybook 运行时以进一步缩短启动时间:类似于 Storybook 缓存其“管理器”GUI 的方式,我们也计划预构建和缓存运行时。
最后,我们还将与 Angular 和 Webpack 等社区合作伙伴合作,充分利用他们所提供的一切。
帮助塑造下一代 Storybook!
延迟编译和文件系统缓存显著改善了你使用 Storybook 的本地开发体验。你现在将花费更少的时间等待 Storybook 编译代码。
成千上万的开发人员每天使用 Storybook 来构建 UI。你做了哪些调整来加速你的 Storybook?我们很想听听你的意见。请通过 Twitter 联系我们,或访问 Storybook Discord。
按需架构功能由Tom Coleman(我!)、Michael Shilman、Yann Braga 和Norbert de Langen 在整个 Storybook 社区的反馈下开发的。Storybook 是由 1440 多名贡献者贡献的产品,并由核心维护者的指导委员会组织。你也可以贡献新功能、修复错误或改进文档。加入我们的 Discord,在 Open Collective 上支持我们,或者直接在 GitHub 上参与。
大型 Storybook 项目即时启动!
— Storybook (@storybookjs) 2022年4月13日
Storybook 6.5 为 Webpack 带来了延迟编译
⚙️ 仅编译核心运行时以快速启动
🧳 在你访问故事时构建故事
这意味着在本地开发过程中更快的启动和重建。https://#/EzcKqzrgTa pic.twitter.com/Xyz8YligA0