Skip to content

Commit 9dc8a5f

Browse files
committed
feat: Start the media preload on screen intersection
1 parent 84bbe74 commit 9dc8a5f

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

Diff for: packages/ui/src/elements/Thumbnail/index.tsx

+11-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const baseClass = 'thumbnail'
88
import type { SanitizedCollectionConfig } from 'payload'
99

1010
import { File } from '../../graphics/File/index.js'
11+
import { useIntersect } from '../../hooks/useIntersect.js'
1112
import { ShimmerEffect } from '../ShimmerEffect/index.js'
1213

1314
export type ThumbnailProps = {
@@ -29,12 +30,20 @@ export const Thumbnail = (props: ThumbnailProps) => {
2930
const [src, setSrc] = React.useState<null | string>(
3031
fileSrc ? `${fileSrc}${imageCacheTag ? `?${imageCacheTag}` : ''}` : null,
3132
)
33+
const [intersectionRef, entry] = useIntersect()
34+
const [hasPreloaded, setHasPreloaded] = React.useState(false)
35+
3236
React.useEffect(() => {
3337
if (!fileSrc) {
3438
setFileExists(false)
3539
return
3640
}
3741

42+
if (!entry?.isIntersecting || hasPreloaded) {
43+
return
44+
}
45+
setHasPreloaded(true)
46+
3847
if (fileType === 'video') {
3948
const video = document.createElement('video')
4049
video.src = fileSrc
@@ -58,12 +67,12 @@ export const Thumbnail = (props: ThumbnailProps) => {
5867
img.src = fileSrc
5968
img.onload = () => setFileExists(true)
6069
img.onerror = () => setFileExists(false)
61-
}, [fileSrc, fileType, imageCacheTag])
70+
}, [fileSrc, fileType, imageCacheTag, entry, hasPreloaded])
6271

6372
const alt = props.alt || (filename as string)
6473

6574
return (
66-
<div className={classNames}>
75+
<div className={classNames} ref={intersectionRef}>
6776
{fileExists === undefined && <ShimmerEffect height="100%" />}
6877
{fileExists && <img alt={alt} src={src} />}
6978
{fileExists === false && <File />}

0 commit comments

Comments
 (0)