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,
-
Paint the
canvasTarget
with the respective blurhash here: https://stackblitz.com/edit/stimulus-blurhash?file=controllers%2Flazy_image_controller.js%3AL9 -
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:
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?