-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Add Image Prefetching for Click to expand Images #61107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from 11 commits
d8e6f5e
6f66cb1
e345cc6
78f0f64
579d32e
6c5b0cd
d7f2e41
3ab6bc0
dd686d5
06e3f74
1fa9abe
a9bcf60
af3ca8d
cab1562
4dc208b
9c34388
8185a6c
b228d53
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ import { | |
getContext, | ||
getElement, | ||
withSyncEvent, | ||
withScope, | ||
} from '@wordpress/interactivity'; | ||
|
||
/** | ||
|
@@ -29,6 +30,8 @@ const { state, actions, callbacks } = store( | |
{ | ||
state: { | ||
currentImageId: null, | ||
preloadTimers: {}, | ||
preloadedImageIds: new Set(), | ||
get currentImage() { | ||
return state.metadata[ state.currentImageId ]; | ||
}, | ||
|
@@ -47,6 +50,12 @@ const { state, actions, callbacks } = store( | |
'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=' | ||
); | ||
}, | ||
get enlargedSrcset() { | ||
return state.currentImage.lightboxSrcset || ''; | ||
}, | ||
get enlargedSizes() { | ||
return state.currentImage.lightboxSizes || '100vw'; | ||
}, | ||
get figureStyles() { | ||
return ( | ||
state.overlayOpened && | ||
|
@@ -187,6 +196,57 @@ const { state, actions, callbacks } = store( | |
} | ||
} | ||
}, | ||
preloadImage() { | ||
const { imageId } = getContext(); | ||
const imageMetadata = state.metadata[ imageId ]; | ||
const uploadedSrc = imageMetadata.uploadedSrc; | ||
|
||
// Bails if it has already been preloaded. This could help | ||
// prevent unnecessary preloading of the same image multiple times, | ||
// leading to duplicate link elements in the document head. | ||
if ( state.preloadedImageIds.has( imageId ) ) { | ||
return; | ||
} | ||
|
||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const imageLink = document.createElement( 'link' ); | ||
imageLink.rel = 'preload'; | ||
imageLink.as = 'image'; | ||
imageLink.href = uploadedSrc; | ||
|
||
// Apply srcset if available for responsive preloading | ||
const srcset = imageMetadata.lightboxSrcset; | ||
if ( srcset ) { | ||
imageLink.setAttribute( 'imagesrcset', srcset ); | ||
imageLink.setAttribute( 'imagesizes', '100vw' ); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can use the getter functions, but for that we need to temporarily set the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't think it would be a good approach, as there can be more than one image preloading at the same time. Why don't you just use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That was how it was implemented previously. I changed it in cab1562 to use the getter fns. |
||
|
||
document.head.appendChild( imageLink ); | ||
state.preloadedImageIds.add( imageId ); | ||
}, | ||
preloadImageWithDelay() { | ||
const { imageId } = getContext(); | ||
|
||
// Cancels any previous preload timer for the same image. | ||
if ( state.preloadTimers && state.preloadTimers[ imageId ] ) { | ||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
clearTimeout( state.preloadTimers[ imageId ] ); | ||
} | ||
|
||
// Set a new timer to preload the image after a short delay. | ||
state.preloadTimers[ imageId ] = setTimeout( | ||
withScope( () => { | ||
actions.preloadImage(); | ||
delete state.preloadTimers[ imageId ]; | ||
} ), | ||
200 | ||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
); | ||
}, | ||
cancelPrefetch() { | ||
const { imageId } = getContext(); | ||
if ( state.preloadTimers && state.preloadTimers[ imageId ] ) { | ||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
clearTimeout( state.preloadTimers[ imageId ] ); | ||
delete state.preloadTimers[ imageId ]; | ||
} | ||
}, | ||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
callbacks: { | ||
setOverlayStyles() { | ||
|
Uh oh!
There was an error while loading. Please reload this page.