@@ -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
3237export 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