unload off screen carousels

This commit is contained in:
Pas 2025-02-28 22:20:35 -07:00
parent 47c6c04444
commit 557c6cb26a
2 changed files with 16 additions and 17 deletions

View file

@ -26,9 +26,8 @@ export function LazyMediaCarousel({
const [medias, setMedias] = useState<Media[]>([]); const [medias, setMedias] = useState<Media[]>([]);
// Use intersection observer to detect when this component is visible // Use intersection observer to detect when this component is visible
const { targetRef, isIntersecting, hasIntersected } = useIntersectionObserver( const { targetRef, isIntersecting } = useIntersectionObserver(
{ rootMargin: "200px" }, // Load when within 200px of viewport { rootMargin: "200px" }, // Load when within 200px of viewport
true, // Only trigger once
); );
// Use the lazy loading hook to fetch data when visible // Use the lazy loading hook to fetch data when visible
@ -36,7 +35,7 @@ export function LazyMediaCarousel({
genre || null, genre || null,
category || null, category || null,
mediaType, mediaType,
hasIntersected, isIntersecting,
); );
// Update medias when data is loaded // Update medias when data is loaded

View file

@ -8,20 +8,24 @@ interface IntersectionObserverOptions {
export function useIntersectionObserver( export function useIntersectionObserver(
options: IntersectionObserverOptions = {}, options: IntersectionObserverOptions = {},
onceOnly = false,
) { ) {
const [isIntersecting, setIsIntersecting] = useState(false); const [isIntersecting, setIsIntersecting] = useState(false);
const [hasIntersected, setHasIntersected] = useState(false); const [hasIntersected, setHasIntersected] = useState(false);
const targetRef = useRef<Element | null>(null); const targetRef = useRef<Element | null>(null);
useEffect(() => { useEffect(() => {
const observer = new IntersectionObserver(([entry]) => { const observer = new IntersectionObserver(
setIsIntersecting(entry.isIntersecting); ([entry]) => {
setIsIntersecting(entry.isIntersecting);
if (entry.isIntersecting && !hasIntersected) { if (entry.isIntersecting) {
setHasIntersected(true); setHasIntersected(true);
} }
}, options); },
{
...options,
rootMargin: options.rootMargin || "200px 0px",
},
);
const currentTarget = targetRef.current; const currentTarget = targetRef.current;
if (currentTarget) { if (currentTarget) {
@ -33,11 +37,7 @@ export function useIntersectionObserver(
observer.unobserve(currentTarget); observer.unobserve(currentTarget);
} }
}; };
}, [options, hasIntersected]); }, [options]);
// If onceOnly is true, we only care if it has ever intersected return { targetRef, isIntersecting, hasIntersected };
// Otherwise, we care about the current intersection state
const shouldLoad = onceOnly ? hasIntersected : isIntersecting;
return { targetRef, isIntersecting: shouldLoad, hasIntersected };
} }