mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +01:00 
			
		
		
		
	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
This commit is contained in:
		
							parent
							
								
									1dd904d89a
								
							
						
					
					
						commit
						93bd9ded88
					
				@ -19,6 +19,7 @@ import {
 | 
				
			|||||||
import { LuCheckSquare, LuFileUp, LuTrash } from "react-icons/lu";
 | 
					import { LuCheckSquare, LuFileUp, LuTrash } from "react-icons/lu";
 | 
				
			||||||
import axios from "axios";
 | 
					import axios from "axios";
 | 
				
			||||||
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
 | 
					import { useFormattedTimestamp } from "@/hooks/use-date-utils";
 | 
				
			||||||
 | 
					import useImageLoaded from "@/hooks/use-image-loaded";
 | 
				
			||||||
import { Skeleton } from "../ui/skeleton";
 | 
					import { Skeleton } from "../ui/skeleton";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type PreviewPlayerProps = {
 | 
					type PreviewPlayerProps = {
 | 
				
			||||||
@ -50,7 +51,7 @@ export default function PreviewThumbnailPlayer({
 | 
				
			|||||||
  const [hoverTimeout, setHoverTimeout] = useState<NodeJS.Timeout | null>();
 | 
					  const [hoverTimeout, setHoverTimeout] = useState<NodeJS.Timeout | null>();
 | 
				
			||||||
  const [playback, setPlayback] = useState(false);
 | 
					  const [playback, setPlayback] = useState(false);
 | 
				
			||||||
  const [progress, setProgress] = useState(0);
 | 
					  const [progress, setProgress] = useState(0);
 | 
				
			||||||
  const [imgLoaded, setImgLoaded] = useState(false);
 | 
					  const [imgRef, imgLoaded, onImgLoad] = useImageLoaded();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const playingBack = useMemo(() => playback, [playback, autoPlayback]);
 | 
					  const playingBack = useMemo(() => playback, [playback, autoPlayback]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -126,6 +127,7 @@ export default function PreviewThumbnailPlayer({
 | 
				
			|||||||
          )}
 | 
					          )}
 | 
				
			||||||
          <div className={`${imgLoaded ? "visible" : "invisible"}`}>
 | 
					          <div className={`${imgLoaded ? "visible" : "invisible"}`}>
 | 
				
			||||||
            <img
 | 
					            <img
 | 
				
			||||||
 | 
					              ref={imgRef}
 | 
				
			||||||
              className={`w-full h-full transition-opacity ${
 | 
					              className={`w-full h-full transition-opacity ${
 | 
				
			||||||
                playingBack ? "opacity-0" : "opacity-100"
 | 
					                playingBack ? "opacity-0" : "opacity-100"
 | 
				
			||||||
              }`}
 | 
					              }`}
 | 
				
			||||||
@ -135,7 +137,7 @@ export default function PreviewThumbnailPlayer({
 | 
				
			|||||||
              )}`}
 | 
					              )}`}
 | 
				
			||||||
              loading="lazy"
 | 
					              loading="lazy"
 | 
				
			||||||
              onLoad={() => {
 | 
					              onLoad={() => {
 | 
				
			||||||
                setImgLoaded(true);
 | 
					                onImgLoad();
 | 
				
			||||||
              }}
 | 
					              }}
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										24
									
								
								web/src/hooks/use-image-loaded.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								web/src/hooks/use-image-loaded.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					import { useEffect, useRef, useState } from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const useImageLoaded = (): [
 | 
				
			||||||
 | 
					  React.RefObject<HTMLImageElement>,
 | 
				
			||||||
 | 
					  boolean,
 | 
				
			||||||
 | 
					  () => void,
 | 
				
			||||||
 | 
					] => {
 | 
				
			||||||
 | 
					  const [loaded, setLoaded] = useState(false);
 | 
				
			||||||
 | 
					  const ref = useRef<HTMLImageElement>(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const onLoad = () => {
 | 
				
			||||||
 | 
					    setLoaded(true);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    if (ref.current && ref.current?.complete) {
 | 
				
			||||||
 | 
					      onLoad();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return [ref, loaded, onLoad];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default useImageLoaded;
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user