Site Image Optimization using eleventy-img
Why? permalink
- I originally began with using
eleventy-img
for all my assets. But, I was having trouble with the markup and the fact thatPug
won't support "on the fly" image handling. I switched out to usingcloudinary
for everything as a quick win. - Drop Cloudinary report in here.
- Issue was that within a day of deployment, I'd used over 3GB of bandwidth. This was mainly due to video and gif as to be expected. However, I was also not getting consistent image formats to come through. Some would be
webp
, and some would bejpeg
.
Solution? permalink
- I kinda had this half-baked in already.
- Generate an image markup lookup. Have the sizes generated and the markup at enhance time and make it available to the preprocessor. This could be a Pug workaround 🤔
- But, it might also make for better DX
- What's the best experience for writing content?
Nunjucks shortcode
vs.

- Short code provides no visual feedback in a preview. But, does provide an "in" for doing things like captions.
Runtime implications. permalink
- We could transform everything after the fact.
- But, we are adjusting the markup which has the potential to break the styling.
- Runtime transformations allow us to deal with this.
- However. Pug doesn't like the
async
stuff so it'll make more sense to do this as a transform. - Enhancement via transforms works for markdown documents, etc.
- But. How do we make this play nice with Storybook? We could do transforms in
main.js
. When we generate the markup for a story, we can wrap the images in apicture
tag. We don't care if we get the hottest format. - We could also transform all the images in the media folder
predev
.
Hurdles permalink
- Netlify Flat CMS media folder is a bit of a downer
- Could make it so that all the processing is handled at deploy time. However, the markup generates
<picture>
tags which throw off the styling... - Design? Do you prefer writing a shortcode everywhere or would it be easier to drop a standard image tag in?
markdown-it
perhaps to add titles? Or is shortcode the cleanest way? - If you drop a shortcode in. Then that markup gets transformed which would generate another image... Cacheing should handle this. But, I've seen inconsistent results.
- Decisions about base styling for pictures. This is a quick win because it should for the most part work as a straight swap. This was the case with the featured pens strip.
picture img {
max-width: 100%;
max-height: 100%;
object-fit: cover;
}
- Running the image optimizations on every build doesn't make sense. It's slow. Can't we generate everything in a node script first and then use a lookup? Swapping DOM elements doesn't "feel" expensive at runtime. But, transforming the entire image library on every save is overkill.
Pros permalink
- Easier to make on the fly content changes without uploading the asset in one spot, and then copying the resource URL to somewhere else. We can use
avif
.
Todos permalink
- Switch out to the media chooser for any referenced images in the CMS. Collections: Pens, blog posts, scraps, generic page heros.
Do we need lazysizes? I've switched out toloading="lazy"
as default unlessloading="eager"
is explicitly set.- Create a
predev
node script that generates a markup lookup that can be used by the image enhancer whenELEVENTY_ENV === dev
- Base style the nested images in pictures. Currently we are applying a nested class which does work but will catch us out eventually.
- Write up as generic image optimization post. Explain what
picture
tag does visually.
Results permalink
- Switch out to using a
predev
script that generates images and assets for us. - Wrap your markup in
picture
where possible. - During
dev
, do nothing, or return a wrappedimg
wherepicture
isn't theparentNode
. - Reduce build times by creating a dynamic
.eleventyignore
. .avif
coming out at a 1/3 of the size in some cases- Build times from ~30s -> ~1-2s.