Persist the build cache on your host
Encoding images is the slowest thing in most Baseline builds, and a rendition never changes once it exists. Locally the cache takes care of itself. A CI runner starts from a clean checkout every time, so unless the host is told to keep the cache, every deploy pays the full encode again.
Reach for this when deploy times are dominated by images, or when you have added enough of them that you have started noticing.
Prerequisites
- A Baseline site building on a host, with
npm run buildproducing images underdist/media/. - Deploy logs you can read.
Know what is worth keeping
Baseline writes two things under .cache:
.cache/media/holds the image renditions. Expensive to produce, and stable: the filename carries a hash of the image's own bytes plus the encode options, so a rendition is either correct or absent, never stale..cache/_baseline/content-graph.jsonholds the content graph. Rebuilt from scratch on every run, because that is what the pre-pass does.
Cache the first and not the second. Restoring a graph that is about to be overwritten saves nothing and makes the cache artefact bigger for no reason.
Install the plugin, then declare it
On Netlify this takes two steps, and skipping either one fails.
npm install --save-dev netlify-plugin-cache
Then in netlify.toml:
[[plugins]]
package = "netlify-plugin-cache"
[plugins.inputs]
paths = [ ".cache/media" ]
A [[plugins]] entry naming a package that is not in package.json fails the build rather than being quietly skipped, and the error names the plugin rather than the missing install, which reads like the plugin is broken.
Vercel and Cloudflare Pages persist the build cache without being asked, so there is nothing to add on either.
Check your clean script
A clean script that removes .cache undoes all of this on every build, and the symptom is that the cache appears to do nothing at all.
"clean": "rimraf dist/"
Delete dist, never .cache. They hold different things: one is output and one is work you have already paid for.
Confirm it is actually being restored
netlify-plugin-cache deliberately reports nothing itself, because Netlify publishes an official plugin that does exactly this:
npm install --save-dev netlify-plugin-debug-cache
[[plugins]]
package = "netlify-plugin-debug-cache"
It takes no inputs, so the block is the package name and nothing else. Put it after the cache plugin, not before: plugins run in the order they appear, and a debug plugin that runs first reports on a cache that has not been restored yet.
Every plugin needs its own [[plugins]] line. Two packages is two blocks. Deploy twice and read the second build's log: the first deploy has nothing to restore, and the second is the one that tells you whether the arrangement works.
The other signal is the build time itself. A deploy that restores the cache skips the encode entirely, and on an image-heavy site that is the difference you were chasing.
You can leave the debug plugin in permanently or take it out once you have seen a good log. It only reads and reports.
Clear it when you need to
The cache is never invalidated for you. That is deliberate: clearing a cache is maintenance, and the plugin is not in a position to know when you want it done.
Locally, rm -rf .cache. On Netlify, use the deploy menu's option to clear the cache and deploy the site.
Two reasons to bother. Renditions for images you have deleted stay in the cache and keep being copied into the output, so it is worth clearing occasionally if the folder has grown past what the site uses. And a build interrupted mid-encode can leave a truncated file, which is the one failure this design cannot detect: the name is valid, so the existence check passes and the broken file now persists instead of being cleaned away with dist.
Notes
- The renditions are safe to lose and safe to keep. Nothing in the site depends on the cache existing, so a cleared cache costs one slow deploy and nothing else.
- Do not point the cache at
dist. It is rebuilt every time, and caching it would serve you a stale site. - If you have replaced an image but the old one keeps appearing, the cache is not the cause unless you have changed
filenameFormatto drop the content hash. See the image shortcode reference for why that hash is what makes the cache safe. - The same two-step shape works for anything else expensive and derived that your build writes under
.cache. Name the subdirectory rather than the whole folder, for the same reason as above.