Cache the merged media catalog and trim card rendering
This commit is contained in:
@@ -78,6 +78,12 @@
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Skip layout and paint for cards far off screen: the DOM can grow to thousands. */
|
||||
.vk-media-figure {
|
||||
content-visibility: auto;
|
||||
contain-intrinsic-size: auto 170px;
|
||||
}
|
||||
|
||||
.vk-media-figure {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
+28
-5
@@ -359,14 +359,23 @@
|
||||
);
|
||||
}
|
||||
|
||||
async function loadStats() {
|
||||
async function loadStats(force = false) {
|
||||
const key = filterQuery();
|
||||
const fresh = state.statsAt && Date.now() - state.statsAt < 60_000;
|
||||
if (!force && fresh && state.stats && state.statsKey === key) {
|
||||
renderStatus();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
state.stats = await window.VK.api.get(`/api/media/stats?${filterQuery()}`);
|
||||
state.stats = await window.VK.api.get(`/api/media/stats?${key}`);
|
||||
state.statsKey = key;
|
||||
state.statsAt = Date.now();
|
||||
} catch {
|
||||
state.stats = null;
|
||||
}
|
||||
renderStatus();
|
||||
if (state.pageMode === "page" && state.view === "media") renderToolbar();
|
||||
updatePager();
|
||||
}
|
||||
|
||||
/** Append only the cards that are new, so existing images never get rebuilt. */
|
||||
@@ -444,13 +453,13 @@
|
||||
}
|
||||
|
||||
layoutBuffer();
|
||||
void loadStats();
|
||||
void loadStats(reset);
|
||||
if (state.pageMode === "infinite") {
|
||||
void prefetchNext();
|
||||
void fillBuffer();
|
||||
} else {
|
||||
state.pageCooldownUntil = Date.now() + 2000;
|
||||
renderToolbar();
|
||||
updatePager();
|
||||
void prefetchNext();
|
||||
}
|
||||
}
|
||||
@@ -1307,6 +1316,8 @@
|
||||
if (imageSource) {
|
||||
const img = document.createElement("img");
|
||||
img.loading = "lazy";
|
||||
img.decoding = "async";
|
||||
img.fetchPriority = "low";
|
||||
img.src = imageSource;
|
||||
img.alt = item.kind;
|
||||
img.addEventListener("error", () => placeholder(media, item), { once: true });
|
||||
@@ -1389,9 +1400,17 @@
|
||||
}
|
||||
|
||||
/** Dropdown with the metadata-field checkboxes. */
|
||||
/** Re-render only the pager after a page load, not the whole toolbar. */
|
||||
function updatePager() {
|
||||
if (state.pageMode !== "page") return;
|
||||
if (!state.pagerHost?.isConnected) return;
|
||||
state.pagerHost.replaceWith(pageControls());
|
||||
}
|
||||
|
||||
/** Infinite/page flippy toggle plus the pager shown in page mode. */
|
||||
function pageControls() {
|
||||
const wrap = el("span", "vk-media-page-controls");
|
||||
state.pagerHost = wrap;
|
||||
|
||||
const toggle = el("span", "vk-media-toggle");
|
||||
for (const [mode, label] of [
|
||||
@@ -1514,6 +1533,8 @@
|
||||
function applyDraft() {
|
||||
state.page = 1;
|
||||
state.pagePrefetch = null;
|
||||
state.statsKey = null;
|
||||
state.statsAt = 0;
|
||||
savePage();
|
||||
state.kind = state.draft.kind;
|
||||
state.filters = {
|
||||
@@ -2035,6 +2056,8 @@
|
||||
state.page = 1;
|
||||
state.pageCooldownUntil = 0;
|
||||
state.pagePrefetch = null;
|
||||
state.statsKey = null;
|
||||
state.statsAt = 0;
|
||||
savePage();
|
||||
state.prefetched = null;
|
||||
state.items = [];
|
||||
|
||||
Reference in New Issue
Block a user