
Storybook Webpack 按需编译
为大型 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 可以快速启动,因为它只需要构建加载和渲染故事所需的 canvas 运行时。
当您访问您的第一个故事时,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 的性能,无论对于大型还是小型项目。我们将探索的一些策略有:
- 预测性预取以缩短“加载下一个故事的时间”(time to next story): Storybook 将预测您接下来可能处理的故事,并预取并预编译其代码。
- 缓存 Storybook 运行时以进一步缩短启动时间: 类似于 Storybook 缓存其“管理器”(manager)GUI 的方式,我们也计划预构建并缓存运行时。
最后,我们还将与 Angular 和 Webpack 等社区合作伙伴合作,充分利用他们提供的所有功能。
帮助塑造下一代 Storybook!
按需编译和文件系统缓存显著改善了您使用 Storybook 的本地开发体验。您现在等待 Storybook 编译代码的时间将大大减少。
成千上万的开发者每天使用 Storybook 构建 UI。您为加速您的 Storybook 做过哪些优化?我们很想听听您的经验。请在Twitter 上联系我们,或者访问 Storybook Discord。
按需架构功能由Tom Coleman (我!)、Michael Shilman、Yann Braga 和 Norbert de Langen 开发,并获得了整个 Storybook 社区的反馈。Storybook 是 1440 多名贡献者的成果,由核心维护者组成的指导委员会组织。您也可以贡献一个新功能、修复一个 bug 或改进文档。通过Discord 加入我们,在Open Collective 上支持我们,或者直接在GitHub 上参与。
大型 Storybook 即时启动!
— Storybook (@storybookjs) 2022年4月13日
Storybook 6.5 为 Webpack 带来按需编译
⚙️ 只编译核心运行时,快速启动
🧳 在您访问故事时构建它们
这意味着本地开发期间启动和重建速度更快。https://#/EzcKqzrgTa pic.twitter.com/Xyz8YligA0