Skip to content

Commit b2d2c76

Browse files
authored
Merge pull request #47 from egeozcan/claude/preload-lightbox-images-oiqpB
Add image preloading to lightbox navigation
2 parents 54f8b28 + 47d4913 commit b2d2c76

2 files changed

Lines changed: 31 additions & 1 deletion

File tree

public/dist/main.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/lightbox/navigation.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ export const navigationState = {
2727

2828
// Reference to trigger element for focus restoration
2929
triggerElement: null,
30+
31+
// Cache of preloaded image URLs (kept in-memory by the Image objects we hold)
32+
_preloadedUrls: new Set(),
33+
_preloadedImages: [],
34+
_preloadAheadCount: 5,
3035
};
3136

3237
export const navigationMethods = {
@@ -157,13 +162,34 @@ export const navigationMethods = {
157162
this.announce(`Opened ${mediaType}: ${item?.name || 'media'}. ${this.currentIndex + 1} of ${this.items.length}`);
158163

159164
this.scheduleMediaCheck();
165+
this._preloadUpcoming();
160166

161167
// Restore quick tag panel from localStorage if it was previously open
162168
if (this.quickTagPanelOpen) {
163169
this.fetchResourceDetails();
164170
}
165171
},
166172

173+
_preloadUpcoming() {
174+
const ahead = this._preloadAheadCount || 5;
175+
const end = Math.min(this.items.length, this.currentIndex + 1 + ahead);
176+
for (let i = this.currentIndex + 1; i < end; i++) {
177+
const item = this.items[i];
178+
if (!item || !this.isImage(item.contentType)) continue;
179+
if (this._preloadedUrls.has(item.viewUrl)) continue;
180+
this._preloadedUrls.add(item.viewUrl);
181+
const img = new Image();
182+
img.decoding = 'async';
183+
img.src = item.viewUrl;
184+
this._preloadedImages.push(img);
185+
}
186+
// Cap retained references so the cache cannot grow unboundedly during long sessions.
187+
const cap = (this._preloadAheadCount || 5) * 6;
188+
if (this._preloadedImages.length > cap) {
189+
this._preloadedImages.splice(0, this._preloadedImages.length - cap);
190+
}
191+
},
192+
167193
close() {
168194
this.pauseCurrentVideo();
169195

@@ -224,6 +250,7 @@ export const navigationMethods = {
224250
this.loading = true;
225251
this.announcePosition();
226252
this.scheduleMediaCheck();
253+
this._preloadUpcoming();
227254
this.onResourceChange();
228255
} else if (this.hasNextPage) {
229256
await this.loadNextPage();
@@ -232,6 +259,7 @@ export const navigationMethods = {
232259
this.loading = true;
233260
this.announcePosition();
234261
this.scheduleMediaCheck();
262+
this._preloadUpcoming();
235263
this.onResourceChange();
236264
}
237265
}
@@ -248,6 +276,7 @@ export const navigationMethods = {
248276
this.loading = true;
249277
this.announcePosition();
250278
this.scheduleMediaCheck();
279+
this._preloadUpcoming();
251280
this.onResourceChange();
252281
} else if (this.hasPrevPage) {
253282
const prevItemCount = await this.loadPrevPage();
@@ -256,6 +285,7 @@ export const navigationMethods = {
256285
this.loading = true;
257286
this.announcePosition();
258287
this.scheduleMediaCheck();
288+
this._preloadUpcoming();
259289
this.onResourceChange();
260290
}
261291
}

0 commit comments

Comments
 (0)