from 'blurhash'; export default class extends Controller { connect() { // If blur-hash is defined, use it if (this.element.hasAttribute('data-blur-hash') && !this.element.src) { const pixels = decode(this.element.getAttribute('data-blur-hash'), this.element.width, this.element.height); const canvas = document.createElement('canvas'); canvas.width = this.element.width; canvas.height = this.element.height; const ctx = canvas.getContext('2d'); const imageData = ctx.createImageData(this.element.width, this.element.height); imageData.data.set(pixels); ctx.putImageData(imageData, 0, 0); this.element.src = canvas.toDataURL(); } this.element.style.visibility = 'initial'; // Load HD in background const hd = new Image(); // Once loaded, replace image hd.addEventListener('load', () => { this.element.src = this.element.getAttribute('data-hd-src'); }); setTimeout(() => hd.src = this.element.getAttribute('data-hd-src'), 2000); } } <img width="200" height="150" style="visibility: hidden" data-blur-hash="{{ blur_hash(photo_dir~'/t_' ~ comment.photofilename data-controller="lazyimg" data-hd-src="{{ asset('uploads/photos/' ~ comment.photofilename) }}" /> Stimulus Controllers lazyimg_controller.js show.html.twig