Zach’s ugly mug (his face) Zach Leatherman

One weird trick to reduce Eleventy Image Build Times by 60%

August 01, 2025

This web site does a fair bit of build-time Image Optimization using the HTML Transform method provided by the Eleventy Image plugin. I took a bit of a set-it-and-forget-it approach with the plugin on this site, mostly for my own convenience. My usage looked something like this:

import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";

export default function(eleventyConfig) {
	eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
		failOnError: false,
		formats: ["svg", "avif", "jpeg"],
		svgShortCircuit: true,
	});
};

Eleventy Image includes a fair number of caches and performance optimizations to make this default behavior pretty fast.

  • It uses a memory cache to de-duplicate multiple requests to optimize the same input image.
  • It uses an on-request image processing engine to avoid processing images during local development.
  • It uses a hash for output file name and checks the target file location to avoid reprocessing images.

The biggest drawback with the third method is that when you’re building on a deployment server, these environments start with an empty output folder (and thus, an empty disk cache). What can we do to re-use the disk cache and avoid reprocessing unchanged images on each new deploy?

With just a few lines of configuration code to create an intermediate output folder in a location that is persisted between builds (.cache), I was able to drop my site’s build time from an embarrasing 9:40 down to a respectable 3:56 (trophy icon) (for throughput info, the output folder has 7,779 files weighing 492.7 MB).

I think this approach is very reusable and we’ll likely bundle it into a future version of Eleventy Image. Until then, you can use it yourself by adding the following lines of configuration:

+import path from "node:path";
+import fs from "node:fs";
 import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";

 export default function(eleventyConfig) {
 	eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
+		urlPath: "/img/built/",
+		outputDir: ".cache/@11ty/img/",
 		failOnError: false,
 		formats: ["svg", "avif", "jpeg"],
 		svgShortCircuit: true,
 	});

+	eleventyConfig.on("eleventy.after", () => {
+		fs.cpSync(".cache/@11ty/img/", path.join(eleventyConfig.directories.output, "/img/built/"), {
+			recursive: true
+		});
+	});
 };

You could improve the above example by restricting the copy step using the process.env.ELEVENTY_RUN_MODE environment variable.

You may also need to persist .cache on your web host. This behavior is provided for-free if you’re using Vercel or Cloudflare Pages.

Subscribe to github.com/11ty/eleventy-img/issues/285 for future updates.


< Newer
A note from my late Grandmother about Eleventy
Older >
Never write your own Date Parsing Library

Zach Leatherman IndieWeb Avatar for https://zachleat.com/is a builder for the web at Font Awesome and the creator/maintainer of IndieWeb Avatar for https://www.11ty.devEleventy (11ty), an award-winning open source site generator. At one point he became entirely too fixated on web fonts. He has given 85 talks in nine different countries at events like Beyond Tellerrand, Smashing Conference, Jamstack Conf, CSSConf, and The White House. Formerly part of CloudCannon, Netlify, Filament Group, NEJS CONF, and NebraskaJS. Learn more about Zach »

17 Reposts

Zach LeathermanZach Leatherman :11ty:Jeff SikesMura ????????Léonie WatsonKhalid K-1000 ????Jean Pierre KolbChristopher KingSami MäättäEleventy ???? v4.0.0-alpha.4Nicolas HoizeybobschiEleventy v4.0.0-alpha.4Bob Monsour???? Stvn Hrlnd (He/Him)Evil Jim O’DonnellCory Dransfeldt :demi:

39 Likes

OrbitalMartianThomas CannonJonathan YuJeff SikesLinkyMura ????????SergioEric PortisLudo HartzemaAlistairMijndertMax BöckKhalid K-1000 ????WillJackmarkisevilAlberto CalvoHey it's JessJean Pierre KolbChristopher KingCassidyAdam Stoddardd3v1an7???? Alex TrostPat ByrneEric McCormickEthan MarcottedamianwalshEleventy ???? v4.0.0-alpha.4bobschiEleventy v4.0.0-alpha.4SimonCoxMike Aparicio???? Stvn Hrlnd (He/Him)Fynn Ellie BeckerCory Dransfeldt :demi:Thomas Maria HelzleFrontend Focus ????
7 Comments
  1. Zach Leatherman

    (now with fixed OG image, thank you @cassidoo.co ????)

  2. Zach Leatherman :11ty:

    @stvnhrlnd the results were SHOCKING!

  3. Zach Leatherman :11ty:

    @nhoizey the transform method does use attributes, yeah. If you’re wanting programmatic access to each image transformation, the transform method is likely not for you. (use the shortcode method instead?) I’d subscribe to something like https://github.com/11ty/eleventy-img/issues… Truncated

  4. Zach Leatherman :11ty:

    @mxbck @11ty *awesome*

  5. Seb Duggan

    Ah, I thought it cached to .cache automatically, and couldn’t work out why Cloudflare Pages never used the cache on the next build… Thanks for the tip - I’ll give it a go!

  6. Zach Leatherman

    we should do that but don’t currently! we’ll probably tackle that soon!

  7. Zach Leatherman :11ty:

    @aaadaaam oh no!! ????

Shamelessly plug your related post

These are webmentions via the IndieWeb and webmention.io.

Sharing on social media?

This is what will show up when you share this post on Social Media:

How did you do this? I automated my Open Graph images. (Peer behind the curtain at the test page)