Storybook Lazy Compilation for Webpack
Lightning fast local development experience for large Storybooks
Storybook is the workshop environment where all UI code gets built, tested and documented. It's used by front-end teams at Shopify, Workday, Adobe, The Guardian and many more to ship robust UIs.
As Storybook usage has grown, performance has become a top priority. A central theme for our 6.x release series has been to re-architect Storybook to reduce build and load times. We started by optimizing published Storybooks, and they now load up to 4 times faster. Now we're shifting focus on improving the local development experience. ย
I am thrilled to share that Storybook 6.5 will offer lazy compilation in development mode. Storybook will only compile the core runtime to get going quickly and then itโll build stories as you visit them. That means instant boot-up and lightning-quick rebuilds for larger Storybooks. Read on to see how it all works.
Performance roadmap
Before we begin, letโs get a sense of the performance updates so far. Storybook is powered by builders such as Webpack, which process and bundle up your codeโJavascript, TypeScript, CSS, MDX, and even framework-specific files like Vue or Svelte SFCs. We see optimizing builders as a massive opportunity for performance gains in Storybook.
Storybook 6.1 laid the foundation for improving speed and load times. It dropped Webpack DLLs then pre-built and cached the manager to improve build times.
This was followed by significant re-architecture in 6.2 that enabled Storybook to support modern builders such as Vite, Snowpack, and more. While some teams could take advantage of this, most of the JavaScript community still relies on Webpack, requiring further optimizations. In 6.4, we worked with the Webpack and Shopify UX engineering teams to make an essential change to how Storybookโs runtime operatesโon-demand architecture.
Previously, Storybook packaged all your stories into one big bundle. Storybook 6.4 employs code splitting to create individual bundles for each story and load them asynchronously. The immediate impact was 3x smaller bundle sizes, which meant that published Storybooks loaded up to 4x faster.
That said, the improvements so far were mainly restricted to production builds โ the static output of build-storybook
. They were most impactful for folks that published their Storybook to the cloud. But Storybook is primarily a developer tool that you run locally. What about the time it takes to rebuild every time you hit save?
Supercharging builds in-development
While building components, you have to wait for Storybook to first boot up. Then every time you hit save, you have to wait again for it to rebuild stories. That's why an important goal of Storybook 6.5 was to take advantage of Webpack's lazy compilation and file caching features to provide a faster development experience.
What is file system caching?
Webpack 5 introduced the persistent file system caching feature, allowing it to use information from previous builds to skip unnecessary steps.
It works by caching build output between runs of Storybook. Then on subsequent runs, Webpack can reuse build artifacts if the associated code did not change. Ultimately it means faster startup and rebuilds for all Storybooks regardless of their size.
What is lazy compilation?
Lazy compilation is a development time feature pioneered by tools like Next.js to defer assembling content for a page until you need it. The idea is that your app may have many routes, but in any given development session, you'll probably only visit a few, so why pay the cost of compiling all of them upfront?
When you start your development server, the builder does some work to get the runtime going and starts very quickly.
Then as you first start working a route of your app, you visit it in the browser. It is at this moment that the builder compiles it. As you navigate to another route, you have to wait for a little bit (a second or two depending on the complexity of your app/route) for it to be compiled.
Lazy compilation of stories
We're bringing that same experience to Storybook, except that we use CSF files as the point of compilation rather than routes.
In a typical development session, you'll only visit a small fraction of the stories in your Storybook. It's sensible to limit the cost of compiling to just those few storiesโespecially for large projects with hundreds of components. Storybook uses Webpack to lazily generate the story bundles.
Starting Storybook boots it up quickly as it only has to build the canvas runtime required to load and render stories.
When you visit your first story, Storybook will compile just its codeโthe CSF file and component.
Start-up performance
You'll see a marginal improvement in start-up times for small and mid-sized projects. But lazy compilation drastically reduces the time it takes for Storybook to start up on larger projects.
Warm cache start-up performance
Lazy compilation is most effective when paired with file system caching. The build output is cached, speeding up subsequent startup times.
Rebuild performance
An additional benefit of compiling only the minimal number of story bundles is that Webpack will often need to do far less work to update the compiled code when you modify a component or a story.
We can see those benefits in the timings below.
Try it out
Lazy compilation is now available in the 6.5 beta. It takes just a minute to try it out, you can run the following command at the root of your project:
npx sb upgrade --prerelease
If youโre not using Storybook already, it's easy to get started:
npx sb@next init
Then opt into the Webpack 5 builder by installing the @storybook/builder-webpack5
and @storybook/manager-webpack5
packages.
Lastly, enabling it in in your Storybook config:
// .storybook/main.js
module.exports = {
features: {
storyStoreV7: true,
},
core: {
builder: {
name: 'webpack5',
options: {
lazyCompilation: true,
fsCache: true,
}
}
},
};
What's next for Storybook performance
We want to keep improving the performance of Storybook, both for large and smaller projects. Some strategies we'll be investigating:
- Predictive prefetching to lower โtime to next storyโ: Storybook will predict which story you're likely to work on next and prefetch and precompile its code.
- Cache Storybook runtime to lower the startup time further: Similar to how Storybook caches its โmanagerโ GUI, we also plan to pre-build and cache the runtime.
Finally, we'll also be working with our community partners, such as Angular and Webpack, to fully take advantage of everything they have to offer.
Help shape the next-generation of Storybook!
Lazy compilation and file system caching significantly improve your local development experience with Storybook. You'll now spend much less time waiting for Storybook to compile code.
Tens of thousands of developers use Storybook daily to build UIs. What tweaks have you made to speed up your Storybook? We'd love to hear from you. Reach out on Twitter or drop by the Storybook Discord.
The on-demand architecture feature was developed by Tom Coleman (me!), Michael Shilman, Yann Braga and Norbert de Langen with feedback from the entire Storybook community.Storybook is the product of over 1440 contributors and is organized by a steering committee of core maintainers. You, too, can contribute a new feature, fix a bug, or improve the docs. Join us on Discord, support us on Open Collective, or just jump in on GitHub.