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:
commit
59eed728de
2 changed files with 48 additions and 51 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue