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

Premise

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:

https://stackblitz.com/edit/stimulus-blurhash?file=index.html%3AL46

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

data-lazy-image-blurhash-value="qmH{m5I9D%V@WBj@WBj[_4aeM{WAWAayayj[WCx]t7WBRjWBfQj[NIt7t7offkayaxWBR+oLazt7t7kCWBWBxZR+ofj[ofofj[ay"

The images in the grid start with opacity 0:

https://stackblitz.com/edit/stimulus-blurhash?file=index.html%3AL54

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

https://stackblitz.com/edit/stimulus-blurhash?file=index.html%3AL58

Challenge

Using the blurhash Javascript library,

  1. Paint the canvasTargetwith the respective blurhash here: https://stackblitz.com/edit/stimulus-blurhash?file=controllers%2Flazy_image_controller.js%3AL9

  2. I’ve added a setTimeout to simulate slow loading. In the callback, fade out the canvas and fade in the image: https://stackblitz.com/edit/stimulus-blurhash?file=controllers%2Flazy_image_controller.js%3AL13

Here’s a sneak peek at the result:

Two images transitioning from a blurhash to the fully loaded image

Caveats

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

Teaser

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 - Video Progress Tracker with LocalStorage
29 October 2024

Store ephemeral user state like video playback progress in localStorage

Stimulus - Image Upload Previews with `URL.createObjectURL`
17 September 2024

Create client-side previews of files using URL.createObjectURL

Stimulus - Removing Markers from a Wavesurfer Element
30 July 2024

Use Stimulus value callbacks to interact with a wavesurfer element and remove markers.

Cookies
essential