Skip to content

Commit 27aa823

Browse files
feat: add delay before prefetching
1 parent 7593d56 commit 27aa823

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

packages/block-library/src/image/index.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,9 @@ function block_core_image_render_lightbox( $block_content, $block ) {
211211
$p->set_attribute( 'data-wp-on-async--load', 'callbacks.setButtonStyles' );
212212
$p->set_attribute( 'data-wp-on-async-window--resize', 'callbacks.setButtonStyles' );
213213
// Set an event to prefetch the image on pointerenter and pointerdown(mobile).
214-
$p->set_attribute( 'data-wp-on--pointerenter', 'actions.prefetchImage' );
214+
$p->set_attribute( 'data-wp-on--pointerenter', 'actions.prefetchImageWithDelay' );
215215
$p->set_attribute( 'data-wp-on--pointerdown', 'actions.prefetchImage' );
216+
$p->set_attribute( 'data-wp-on--pointerleave', 'actions.cancelPrefetch' );
216217
// Sets an event callback on the `img` because the `figure` element can also
217218
// contain a caption, and we don't want to trigger the lightbox when the
218219
// caption is clicked.

packages/block-library/src/image/view.js

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
getContext,
77
getElement,
88
withSyncEvent,
9+
withScope,
910
} from '@wordpress/interactivity';
1011

1112
/**
@@ -50,6 +51,7 @@ const { state, actions, callbacks } = store(
5051
{
5152
state: {
5253
currentImageId: null,
54+
prefetchTimers: {},
5355
get currentImage() {
5456
return state.metadata[ state.currentImageId ];
5557
},
@@ -212,20 +214,43 @@ const { state, actions, callbacks } = store(
212214
}
213215
},
214216
prefetchImage() {
215-
const ctx = getContext();
216-
if ( ! isValidLink( ctx.uploadedSrc ) ) {
217+
const { imageId } = getContext();
218+
const uploadedSrc = state.metadata[ imageId ].uploadedSrc;
219+
220+
if ( ! isValidLink( uploadedSrc ) ) {
217221
return;
218222
}
219223

220-
// Creates a link element to prefetch the image.
221224
const imageLink = document.createElement( 'link' );
222225
imageLink.rel = 'prefetch';
223226
imageLink.as = 'image';
224-
imageLink.href = ctx.uploadedSrc;
227+
imageLink.href = uploadedSrc;
225228

226-
// Appends the link element to the head of the document to start the prefetch.
229+
// Appends the link element to start the prefetch.
227230
document.head.appendChild( imageLink );
228231
},
232+
prefetchImageWithDelay() {
233+
const { imageId } = getContext();
234+
235+
if ( state.prefetchTimers && state.prefetchTimers[ imageId ] ) {
236+
clearTimeout( state.prefetchTimers[ imageId ] );
237+
}
238+
239+
state.prefetchTimers[ imageId ] = setTimeout(
240+
withScope( () => {
241+
actions.prefetchImage();
242+
delete state.prefetchTimers[ imageId ];
243+
} ),
244+
200
245+
);
246+
},
247+
cancelPrefetch() {
248+
const { imageId } = getContext();
249+
if ( state.prefetchTimers && state.prefetchTimers[ imageId ] ) {
250+
clearTimeout( state.prefetchTimers[ imageId ] );
251+
delete state.prefetchTimers[ imageId ];
252+
}
253+
},
229254
},
230255
callbacks: {
231256
setOverlayStyles() {

0 commit comments

Comments
 (0)