From 93bd9ded88c4df8d1310e9a1d9442cfe04b18b94 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Mon, 26 Feb 2024 12:34:52 -0600 Subject: [PATCH] Faster skeleton with refs (#10063) * don't load metadata until image has loaded * correct class name and remove lazy loading pkg * try refs * hook * don't load metadata until image has loaded * correct class name and remove lazy loading pkg * try refs * hook --- .../player/PreviewThumbnailPlayer.tsx | 6 +++-- web/src/hooks/use-image-loaded.ts | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 web/src/hooks/use-image-loaded.ts diff --git a/web/src/components/player/PreviewThumbnailPlayer.tsx b/web/src/components/player/PreviewThumbnailPlayer.tsx index eb410f7ab..7b5ffac64 100644 --- a/web/src/components/player/PreviewThumbnailPlayer.tsx +++ b/web/src/components/player/PreviewThumbnailPlayer.tsx @@ -19,6 +19,7 @@ import { import { LuCheckSquare, LuFileUp, LuTrash } from "react-icons/lu"; import axios from "axios"; import { useFormattedTimestamp } from "@/hooks/use-date-utils"; +import useImageLoaded from "@/hooks/use-image-loaded"; import { Skeleton } from "../ui/skeleton"; type PreviewPlayerProps = { @@ -50,7 +51,7 @@ export default function PreviewThumbnailPlayer({ const [hoverTimeout, setHoverTimeout] = useState(); const [playback, setPlayback] = useState(false); const [progress, setProgress] = useState(0); - const [imgLoaded, setImgLoaded] = useState(false); + const [imgRef, imgLoaded, onImgLoad] = useImageLoaded(); const playingBack = useMemo(() => playback, [playback, autoPlayback]); @@ -126,6 +127,7 @@ export default function PreviewThumbnailPlayer({ )}
{ - setImgLoaded(true); + onImgLoad(); }} /> diff --git a/web/src/hooks/use-image-loaded.ts b/web/src/hooks/use-image-loaded.ts new file mode 100644 index 000000000..b64258c88 --- /dev/null +++ b/web/src/hooks/use-image-loaded.ts @@ -0,0 +1,24 @@ +import { useEffect, useRef, useState } from "react"; + +const useImageLoaded = (): [ + React.RefObject, + boolean, + () => void, +] => { + const [loaded, setLoaded] = useState(false); + const ref = useRef(null); + + const onLoad = () => { + setLoaded(true); + }; + + useEffect(() => { + if (ref.current && ref.current?.complete) { + onLoad(); + } + }); + + return [ref, loaded, onLoad]; +}; + +export default useImageLoaded;