Resource loading
Chromatic waits for resources like images and fonts to load before capturing a snapshot. When resources fail to load it leads to unintended UI changes.
The maximum time to capture a snapshot is 15 seconds. If the resources fail to load in the allotted time, Chromatic will retry. After several retries, the snapshot will be captured anyway and a warning message will be displayed.
Avoid external resources
It’s tough to predict network stability third-party hosting reliability. These factors mean external resources might not load predictably and affect your snapshots.
We recommend adding resources to your Storybook or using a reliable placeholder service. This also makes your builds run faster.
Asynchronous rendering
Our browsers monitor network activity that occurs while your story renders. If your story renders after a delay (i.e. asynchronously), there is no way for us to tell what happened. Thus, we can’t reliably wait for subsequent resources to be loaded asynchronously.
If you know how long async rendering takes, you can add a delay to avoid snapshotting until after that happens. But it can be difficult to reliably set a time that network resources will load within so you may have to add/subtract seconds to the delay.
We are investigating ways to add first-class support to Storybook and Chromatic for asynchronous rendering. Let us know if you need this feature by chat or email.
Loading custom fonts
Browsers can decide to render HTML in multiple passes when custom fonts are used. They do this to speed up the time-to-first-meaningful-paint.
Unfortunately, this behavior can cause your story to render without the custom font. Or worse, render inconsistently. That triggers font rendering changes that you have to accept again and again. Here are ways to prevent that.
Solution A: Preload fonts
We recommend that you ensure fonts are always loaded prior to rendering the story. Preload fonts in Storybook by specifying them in ./storybook/preview-head.html
.
// ./storybook/preview-head.html
<link
rel='preload'
href='path/to/font.woff2'
as='font'
type='font/woff2'
crossorigin='anonymous'
/>
Solution B: Check fonts have loaded in a loader
This alternate solution uses the browsers font load API and the isChromatic()
helper function to verify that fonts load when in the Chromatic environment.
// .storybook/preview.js
import isChromatic from 'chromatic/isChromatic';
// Use the document.fonts API to check if fonts have loaded
// https://developer.mozilla.org/en-US/docs/Web/API/Document/fonts API to
const fontLoader = async () => ({
fonts: await Promise.all([document.fonts.load('400 1em Font Name')]),
// or
// fonts: await document.fonts.ready,
});
/* 👇 It's configured as a global loader
* See https://storybook.js.org/docs/react/writing-stories/loaders
* to learn more about loaders
*/
export const loaders = isChromatic() && document.fonts ? [fontLoader] : [];
Solution C: Don’t load fonts
As a last resort, you can also disable custom fonts by setting font-display: optional
in your CSS when running in Chromatic.