Give cached fallback images 200ms to load
This commit is contained in:
parent
462ac1a573
commit
8ea82e8c09
@ -7,6 +7,9 @@ import { clsx} from 'clsx/lite';
|
|||||||
import Image, { ImageProps } from 'next/image';
|
import Image, { ImageProps } from 'next/image';
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
|
// If image is still loading after 200ms, force CSS animation
|
||||||
|
const FALLBACK_FADE_CUTOFF = 200;
|
||||||
|
|
||||||
export default function ImageWithFallback({
|
export default function ImageWithFallback({
|
||||||
className,
|
className,
|
||||||
classNameImage = 'object-cover h-full',
|
classNameImage = 'object-cover h-full',
|
||||||
@ -31,6 +34,7 @@ export default function ImageWithFallback({
|
|||||||
const onLoad = useCallback(() => setIsLoading(false), []);
|
const onLoad = useCallback(() => setIsLoading(false), []);
|
||||||
const onError = useCallback(() => setDidError(true), []);
|
const onError = useCallback(() => setDidError(true), []);
|
||||||
|
|
||||||
|
const [forceFallbackFade, setForceFallbackFade] = useState(false);
|
||||||
const [hideFallback, setHideFallback] = useState(false);
|
const [hideFallback, setHideFallback] = useState(false);
|
||||||
|
|
||||||
const refImage = useRef<HTMLImageElement>(null);
|
const refImage = useRef<HTMLImageElement>(null);
|
||||||
@ -50,16 +54,15 @@ export default function ImageWithFallback({
|
|||||||
isLoadingRef.current = isLoading;
|
isLoadingRef.current = isLoading;
|
||||||
}, [isLoading]);
|
}, [isLoading]);
|
||||||
|
|
||||||
const forceTransition = useRef(false);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
// If image is still loading, force CSS animation
|
// If image is still loading, force CSS animation
|
||||||
if (isLoadingRef.current) {
|
if (isLoadingRef.current) {
|
||||||
forceTransition.current = true;
|
setForceFallbackFade(true);
|
||||||
}
|
}
|
||||||
}, 200);
|
}, FALLBACK_FADE_CUTOFF);
|
||||||
return () => clearTimeout(timeout);
|
return () => clearTimeout(timeout);
|
||||||
}, [shouldDebugFallbackTiming]);
|
}, []);
|
||||||
|
|
||||||
const timeStartRef = useRef(performance.now());
|
const timeStartRef = useRef(performance.now());
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -81,7 +84,7 @@ export default function ImageWithFallback({
|
|||||||
wasCached: wasCachedRef.current,
|
wasCached: wasCachedRef.current,
|
||||||
hideFallback,
|
hideFallback,
|
||||||
showFallback,
|
showFallback,
|
||||||
forceTransition: forceTransition.current,
|
forceTransition: forceFallbackFade,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +177,7 @@ export default function ImageWithFallback({
|
|||||||
'@container',
|
'@container',
|
||||||
'absolute inset-0 pointer-events-none',
|
'absolute inset-0 pointer-events-none',
|
||||||
'overflow-hidden',
|
'overflow-hidden',
|
||||||
(showFallback || shouldDebugImageFallbacks) &&
|
((showFallback && !forceFallbackFade) || shouldDebugImageFallbacks) &&
|
||||||
'transition-opacity duration-300 ease-in',
|
'transition-opacity duration-300 ease-in',
|
||||||
!(BLUR_ENABLED && blurDataURL) && 'bg-main',
|
!(BLUR_ENABLED && blurDataURL) && 'bg-main',
|
||||||
(isLoading || shouldDebugImageFallbacks)
|
(isLoading || shouldDebugImageFallbacks)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user