Stimulus - Progressive Image Loading with Blurhash

Improve Largest Contentful Paint using image blurhashes and Stimulus

View Solution on Patreon
Stimulus - Progressive Image Loading with Blurhash


Let’s talk about images. Wrongly configured, they impact core web vitals like LCP (Largest Contentful Paint) and lead to layout shift when lazy loaded. Speaking of which, nowadays the loading="lazy"attribute on <img> tags is widely supported, and its use is encouraged. However, many developers shy away from it because it can mess up the page layout really bad. Blurhashes, though, are a clever way to bypass these issues.

Starting Point

I’ve put together a grid of images wrapped in <div> containers:

These are connect to a lazy-image Stimulus controller and given a blurhash string as a value:


The images in the grid start with opacity 0:

While the canvases to be painted with the respective blurhash start with opacity 1:


Using the blurhash Javascript library,

  1. Paint the canvasTargetwith the respective blurhash here:

  2. I’ve added a setTimeout to simulate slow loading. In the callback, fade out the canvas and fade in the image:

Here’s a sneak peek at the result:

Two images transitioning from a blurhash to the fully loaded image


Be sure to grab the correct width and height off the image to resize the canvas!


I’ve not actually added loading="lazy" here because that would complicate things a bit more. What would you need to change to use this?

More from

Stimulus - Picture in Picture API
04 June 2024

Use an IntersectionObserver to trigger a Picture in Picture overlay

Stimulus - Orchestrate Complex UI Changes with Target Callbacks
07 May 2024

Use Stimulus target callbacks to dynamically update parts of your UI

Hotwire Combobox with Real Time Data
12 March 2024

Update combobox options using Websockets and Stimulus outlets