From 5924c17c7267ef96760c4fa978a4caa685ac97a4 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 29 Jun 2020 23:38:46 +0200 Subject: [PATCH 1/4] Improve blurhash performance --- src/components/images/imageLoader.js | 68 ++++++++++++---------------- src/components/images/style.css | 1 - 2 files changed, 28 insertions(+), 41 deletions(-) diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index f7183515c5..46e1c30e8a 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -12,7 +12,7 @@ import 'css!./style'; fillImageElement(elem, source); } - async function itemBlurhashing(target, blurhashstr) { + function itemBlurhashing(target, blurhashstr) { if (blurhash.isBlurhashValid(blurhashstr)) { // Although the default values recommended by Blurhash developers is 32x32, a size of 18x18 seems to be the sweet spot for us, // improving the performance and reducing the memory usage, while retaining almost full blur quality. @@ -36,27 +36,21 @@ import 'css!./style'; imgData.data.set(pixels); ctx.putImageData(imgData, 0, 0); - let child = target.appendChild(canvas); + let child = target.parentNode.insertBefore(canvas, target); child.classList.add('blurhash-canvas'); - child.style.opacity = 1; if (userSettings.enableFastFadein()) { child.classList.add('lazy-blurhash-fadein-fast'); } else { child.classList.add('lazy-blurhash-fadein'); } + child.style.opacity = 1; + target.classList.add('blurhashed'); target.removeAttribute('data-blurhash'); } } - function switchCanvas(elem) { - let child = elem.getElementsByClassName('blurhash-canvas')[0]; - if (child) { - child.style.opacity = elem.getAttribute('data-src') ? 1 : 0; - } - } - export function fillImage(entry) { if (!entry) { throw new Error('entry cannot be null'); @@ -66,23 +60,16 @@ import 'css!./style'; if (target) { source = target.getAttribute('data-src'); - var blurhashstr = target.getAttribute('data-blurhash'); } else { source = entry; } - if (userSettings.enableBlurhash()) { - if (!target.classList.contains('blurhashed', 'non-blurhashable') && blurhashstr) { - itemBlurhashing(target, blurhashstr); - } else if (!blurhashstr && !target.classList.contains('blurhashed')) { - target.classList.add('non-blurhashable'); - } - } - if (entry.intersectionRatio > 0) { if (source) fillImageElement(target, source); } else if (!source) { - emptyImageElement(target); + requestAnimationFrame(() => { + emptyImageElement(target); + }); } } @@ -94,29 +81,24 @@ import 'css!./style'; let preloaderImg = new Image(); preloaderImg.src = url; - // This is necessary here, so changing blurhash settings without reloading the page works - if (!userSettings.enableBlurhash() || elem.classList.contains('non-blurhashable')) { - elem.classList.add('lazy-hidden'); - } + elem.classList.add('lazy-hidden'); preloaderImg.addEventListener('load', () => { - if (elem.tagName !== 'IMG') { - elem.style.backgroundImage = "url('" + url + "')"; - } else { - elem.setAttribute('src', url); - } - elem.removeAttribute('data-src'); + requestAnimationFrame(() => { + if (elem.tagName !== 'IMG') { + elem.style.backgroundImage = "url('" + url + "')"; + } else { + elem.setAttribute('src', url); + } + elem.removeAttribute('data-src'); - if (elem.classList.contains('non-blurhashable') || !userSettings.enableBlurhash()) { elem.classList.remove('lazy-hidden'); if (userSettings.enableFastFadein()) { elem.classList.add('lazy-image-fadein-fast'); } else { elem.classList.add('lazy-image-fadein'); } - } else { - switchCanvas(elem); - } + }); }); } @@ -132,15 +114,21 @@ import 'css!./style'; } elem.setAttribute('data-src', url); - if (elem.classList.contains('non-blurhashable') || !userSettings.enableBlurhash()) { - elem.classList.remove('lazy-image-fadein-fast', 'lazy-image-fadein'); - elem.classList.add('lazy-hidden'); - } else { - switchCanvas(elem); - } + elem.classList.remove('lazy-image-fadein-fast', 'lazy-image-fadein'); + elem.classList.add('lazy-hidden'); } export function lazyChildren(elem) { + for (const lazyElem of elem.getElementsByClassName('lazy')) { + if (userSettings.enableBlurhash()) { + var blurhashstr = lazyElem.getAttribute('data-blurhash'); + if (!lazyElem.classList.contains('blurhashed', 'non-blurhashable') && blurhashstr) { + itemBlurhashing(lazyElem, blurhashstr); + } else if (!blurhashstr && !lazyElem.classList.contains('blurhashed')) { + lazyElem.classList.add('non-blurhashable'); + } + } + } lazyLoader.lazyChildren(elem, fillImage); } diff --git a/src/components/images/style.css b/src/components/images/style.css index 2b09da2da4..e4c706221f 100644 --- a/src/components/images/style.css +++ b/src/components/images/style.css @@ -28,6 +28,5 @@ left: 0; width: 100%; height: 100%; - z-index: 100; pointer-events: none; } From 0361a2d58d213c819717154ae111fd1382e29d96 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 29 Jun 2020 23:57:05 +0200 Subject: [PATCH 2/4] Fix blurhash entry animation --- src/components/images/imageLoader.js | 22 +++++++++++----------- src/components/images/style.css | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index 46e1c30e8a..b153331801 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -36,18 +36,18 @@ import 'css!./style'; imgData.data.set(pixels); ctx.putImageData(imgData, 0, 0); - let child = target.parentNode.insertBefore(canvas, target); - child.classList.add('blurhash-canvas'); - if (userSettings.enableFastFadein()) { - child.classList.add('lazy-blurhash-fadein-fast'); - } else { - child.classList.add('lazy-blurhash-fadein'); - } + requestAnimationFrame(() => { + canvas.classList.add('blurhash-canvas'); + if (userSettings.enableFastFadein()) { + canvas.classList.add('lazy-blurhash-fadein-fast'); + } else { + canvas.classList.add('lazy-blurhash-fadein'); + } - child.style.opacity = 1; - - target.classList.add('blurhashed'); - target.removeAttribute('data-blurhash'); + target.parentNode.insertBefore(canvas, target); + target.classList.add('blurhashed'); + target.removeAttribute('data-blurhash'); + }); } } diff --git a/src/components/images/style.css b/src/components/images/style.css index e4c706221f..af982f1582 100644 --- a/src/components/images/style.css +++ b/src/components/images/style.css @@ -12,12 +12,22 @@ opacity: 0; } +@keyframes fadein { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + .lazy-blurhash-fadein-fast { - transition: opacity 0.2s; + animation: fadein 0.2s; } .lazy-blurhash-fadein { - transition: opacity 0.7s; + animation: fadein 0.7s; } .blurhash-canvas { From c70ba48082b6a449736a74d4b063b5dac225b00b Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 29 Jun 2020 23:57:56 +0200 Subject: [PATCH 3/4] Adjust blurhash entry animation timing --- src/components/images/style.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/images/style.css b/src/components/images/style.css index af982f1582..7e8b01aff2 100644 --- a/src/components/images/style.css +++ b/src/components/images/style.css @@ -23,11 +23,11 @@ } .lazy-blurhash-fadein-fast { - animation: fadein 0.2s; + animation: fadein 0.1s; } .lazy-blurhash-fadein { - animation: fadein 0.7s; + animation: fadein 0.4s; } .blurhash-canvas { From 0766d360c1ee14c54ae5166e553392b6c8d6c29f Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Tue, 30 Jun 2020 00:10:13 +0200 Subject: [PATCH 4/4] Move check outside of loop --- src/components/images/imageLoader.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index b153331801..9981430a64 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -119,9 +119,9 @@ import 'css!./style'; } export function lazyChildren(elem) { - for (const lazyElem of elem.getElementsByClassName('lazy')) { - if (userSettings.enableBlurhash()) { - var blurhashstr = lazyElem.getAttribute('data-blurhash'); + if (userSettings.enableBlurhash()) { + for (const lazyElem of elem.getElementsByClassName('lazy')) { + const blurhashstr = lazyElem.getAttribute('data-blurhash'); if (!lazyElem.classList.contains('blurhashed', 'non-blurhashable') && blurhashstr) { itemBlurhashing(lazyElem, blurhashstr); } else if (!blurhashstr && !lazyElem.classList.contains('blurhashed')) {