load visible favicons immediately, lazy-load the rest

This commit is contained in:
tophf 2017-12-24 09:42:07 +03:00
parent 5a07bbb1e3
commit 53eac84312
2 changed files with 35 additions and 17 deletions

View File

@ -312,6 +312,7 @@ select {
.newUI .entry { .newUI .entry {
display: table-row; display: table-row;
contain: strict;
} }
.newUI .entry.odd { .newUI .entry.odd {
@ -606,6 +607,7 @@ select {
box-sizing: border-box; box-sizing: border-box;
padding-right: 1rem; padding-right: 1rem;
line-height: 18px; line-height: 18px;
contain: layout style;
} }
.newUI .applies-to .expander { .newUI .applies-to .expander {
@ -644,6 +646,7 @@ select {
backface-visibility: hidden; backface-visibility: hidden;
opacity: .25; opacity: .25;
display: none; display: none;
contain: layout style size;
} }
.newUI .has-favicons .target { .newUI .has-favicons .target {

View File

@ -139,6 +139,9 @@ function showStyles(styles = []) {
renderBin.appendChild(createStyleElement(sorted[index++])); renderBin.appendChild(createStyleElement(sorted[index++]));
} }
filterAndAppend({container: renderBin}); filterAndAppend({container: renderBin});
if (newUI.enabled && newUI.favicons) {
debounce(handleEvent.loadFavicons);
}
if (index < sorted.length) { if (index < sorted.length) {
requestAnimationFrame(renderStyles); requestAnimationFrame(renderStyles);
return; return;
@ -146,9 +149,6 @@ function showStyles(styles = []) {
if ('scrollY' in (history.state || {}) && !sessionStorage.justEditedStyleId) { if ('scrollY' in (history.state || {}) && !sessionStorage.justEditedStyleId) {
setTimeout(window.scrollTo, 0, 0, history.state.scrollY); setTimeout(window.scrollTo, 0, 0, history.state.scrollY);
} }
if (newUI.enabled && newUI.favicons) {
debounce(handleEvent.loadFavicons, 16);
}
if (sessionStorage.justEditedStyleId) { if (sessionStorage.justEditedStyleId) {
const entry = $(ENTRY_ID_PREFIX + sessionStorage.justEditedStyleId); const entry = $(ENTRY_ID_PREFIX + sessionStorage.justEditedStyleId);
delete sessionStorage.justEditedStyleId; delete sessionStorage.justEditedStyleId;
@ -212,20 +212,17 @@ function createStyleElement({style, name, index}) {
$('.actions', entry).appendChild(template.configureIcon.cloneNode(true)); $('.actions', entry).appendChild(template.configureIcon.cloneNode(true));
} }
// name being supplied signifies we're invoked by showStyles() createStyleTargetsElement({entry, style});
// which debounces its main loop thus loading the postponed favicons
createStyleTargetsElement({entry, style, postponeFavicons: name});
return entry; return entry;
} }
function createStyleTargetsElement({entry, style, postponeFavicons}) { function createStyleTargetsElement({entry, style}) {
const parts = createStyleElement.parts; const parts = createStyleElement.parts;
const targets = parts.targets.cloneNode(true); const targets = parts.targets.cloneNode(true);
let container = targets; let container = targets;
let numTargets = 0; let numTargets = 0;
let numIcons = 0;
const displayed = new Set(); const displayed = new Set();
for (const type of TARGET_TYPES) { for (const type of TARGET_TYPES) {
for (const section of style.sections) { for (const section of style.sections) {
@ -270,9 +267,6 @@ function createStyleTargetsElement({entry, style, postponeFavicons}) {
if (numTargets > newUI.targets) { if (numTargets > newUI.targets) {
$('.applies-to', entry).classList.add('has-more'); $('.applies-to', entry).classList.add('has-more');
} }
if (numIcons && !postponeFavicons) {
debounce(handleEvent.loadFavicons);
}
} }
const entryTargets = $('.targets', entry); const entryTargets = $('.targets', entry);
if (numTargets) { if (numTargets) {
@ -395,12 +389,33 @@ Object.assign(handleEvent, {
this.closest('.applies-to').classList.toggle('expanded'); this.closest('.applies-to').classList.toggle('expanded');
}, },
loadFavicons(container = document.body) { loadFavicons({all = false} = {}) {
for (const img of $$('img', container)) { if (!installed.firstElementChild) return;
if (img.dataset.src) { let favicons = [];
if (all) {
favicons = $$('img[data-src]', installed);
} else {
const {left, top} = installed.firstElementChild.getBoundingClientRect();
const x = Math.max(0, left);
const y = Math.max(0, top);
const first = document.elementFromPoint(x, y);
const lastOffset = first.offsetTop + window.innerHeight;
const numTargets = prefs.get('manage.newUI.targets');
let entry = first && first.closest('.entry') || installed.children[0];
while (entry && entry.offsetTop <= lastOffset) {
favicons.push(...$$('img', entry).slice(0, numTargets).filter(img => img.dataset.src));
entry = entry.nextElementSibling;
}
}
let i = 0;
for (const img of favicons) {
img.src = img.dataset.src; img.src = img.dataset.src;
delete img.dataset.src; delete img.dataset.src;
// loading too many icons at once will block the page while the new layout is recalculated
if (++i > 100) break;
} }
if ($('img[data-src]', installed)) {
debounce(handleEvent.loadFavicons, 1, {all: true});
} }
}, },
@ -549,7 +564,7 @@ function switchUI({styleOnly} = {}) {
for (const style of styles) { for (const style of styles) {
const entry = $(ENTRY_ID_PREFIX + style.id); const entry = $(ENTRY_ID_PREFIX + style.id);
if (entry) { if (entry) {
createStyleTargetsElement({entry, style, postponeFavicons: true}); createStyleTargetsElement({entry, style});
} }
} }
debounce(handleEvent.loadFavicons); debounce(handleEvent.loadFavicons);