1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Merge pull request #1498 from MrTimscampi/blurhash-perf

Improve blurhash performance
This commit is contained in:
Joshua M. Boniface 2020-07-01 11:42:13 -04:00 committed by GitHub
commit 59eed728de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 51 deletions

View file

@ -12,7 +12,7 @@ import 'css!./style';
fillImageElement(elem, source); fillImageElement(elem, source);
} }
async function itemBlurhashing(target, blurhashstr) { function itemBlurhashing(target, blurhashstr) {
if (blurhash.isBlurhashValid(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, // 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. // improving the performance and reducing the memory usage, while retaining almost full blur quality.
@ -36,24 +36,18 @@ import 'css!./style';
imgData.data.set(pixels); imgData.data.set(pixels);
ctx.putImageData(imgData, 0, 0); ctx.putImageData(imgData, 0, 0);
let child = target.appendChild(canvas); requestAnimationFrame(() => {
child.classList.add('blurhash-canvas'); canvas.classList.add('blurhash-canvas');
child.style.opacity = 1; if (userSettings.enableFastFadein()) {
if (userSettings.enableFastFadein()) { canvas.classList.add('lazy-blurhash-fadein-fast');
child.classList.add('lazy-blurhash-fadein-fast'); } else {
} else { canvas.classList.add('lazy-blurhash-fadein');
child.classList.add('lazy-blurhash-fadein'); }
}
target.classList.add('blurhashed'); target.parentNode.insertBefore(canvas, target);
target.removeAttribute('data-blurhash'); 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;
} }
} }
@ -66,23 +60,16 @@ import 'css!./style';
if (target) { if (target) {
source = target.getAttribute('data-src'); source = target.getAttribute('data-src');
var blurhashstr = target.getAttribute('data-blurhash');
} else { } else {
source = entry; 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 (entry.intersectionRatio > 0) {
if (source) fillImageElement(target, source); if (source) fillImageElement(target, source);
} else if (!source) { } else if (!source) {
emptyImageElement(target); requestAnimationFrame(() => {
emptyImageElement(target);
});
} }
} }
@ -94,29 +81,24 @@ import 'css!./style';
let preloaderImg = new Image(); let preloaderImg = new Image();
preloaderImg.src = url; preloaderImg.src = url;
// This is necessary here, so changing blurhash settings without reloading the page works elem.classList.add('lazy-hidden');
if (!userSettings.enableBlurhash() || elem.classList.contains('non-blurhashable')) {
elem.classList.add('lazy-hidden');
}
preloaderImg.addEventListener('load', () => { preloaderImg.addEventListener('load', () => {
if (elem.tagName !== 'IMG') { requestAnimationFrame(() => {
elem.style.backgroundImage = "url('" + url + "')"; if (elem.tagName !== 'IMG') {
} else { elem.style.backgroundImage = "url('" + url + "')";
elem.setAttribute('src', url); } else {
} elem.setAttribute('src', url);
elem.removeAttribute('data-src'); }
elem.removeAttribute('data-src');
if (elem.classList.contains('non-blurhashable') || !userSettings.enableBlurhash()) {
elem.classList.remove('lazy-hidden'); elem.classList.remove('lazy-hidden');
if (userSettings.enableFastFadein()) { if (userSettings.enableFastFadein()) {
elem.classList.add('lazy-image-fadein-fast'); elem.classList.add('lazy-image-fadein-fast');
} else { } else {
elem.classList.add('lazy-image-fadein'); elem.classList.add('lazy-image-fadein');
} }
} else { });
switchCanvas(elem);
}
}); });
} }
@ -132,15 +114,21 @@ import 'css!./style';
} }
elem.setAttribute('data-src', url); 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.remove('lazy-image-fadein-fast', 'lazy-image-fadein'); elem.classList.add('lazy-hidden');
elem.classList.add('lazy-hidden');
} else {
switchCanvas(elem);
}
} }
export function lazyChildren(elem) { export function lazyChildren(elem) {
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')) {
lazyElem.classList.add('non-blurhashable');
}
}
}
lazyLoader.lazyChildren(elem, fillImage); lazyLoader.lazyChildren(elem, fillImage);
} }

View file

@ -12,12 +12,22 @@
opacity: 0; opacity: 0;
} }
@keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.lazy-blurhash-fadein-fast { .lazy-blurhash-fadein-fast {
transition: opacity 0.2s; animation: fadein 0.1s;
} }
.lazy-blurhash-fadein { .lazy-blurhash-fadein {
transition: opacity 0.7s; animation: fadein 0.4s;
} }
.blurhash-canvas { .blurhash-canvas {
@ -28,6 +38,5 @@
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
z-index: 100;
pointer-events: none; pointer-events: none;
} }