diff --git a/package-lock.json b/package-lock.json index c54fc04..7d436bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "netflix-react-apollo", - "version": "1.0.0", + "version": "1.0.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "netflix-react-apollo", - "version": "1.0.0", + "version": "1.0.1", "dependencies": { "@apollo/client": "^3.7.17", "@egjs/flicking-plugins": "^4.7.1", diff --git a/package.json b/package.json index 4a61a13..c43c57a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "netflix-react-apollo", - "version": "1.0.0", + "version": "1.0.1", "private": true, "scripts": { "start": "vite --host 127.0.0.1 --port 3000", diff --git a/src/components/SuggestionCarousel/components/CompactSuggestionController/CompactSuggestionController.tsx b/src/components/SuggestionCarousel/components/CompactSuggestionController/CompactSuggestionController.tsx index 39917e4..b743119 100644 --- a/src/components/SuggestionCarousel/components/CompactSuggestionController/CompactSuggestionController.tsx +++ b/src/components/SuggestionCarousel/components/CompactSuggestionController/CompactSuggestionController.tsx @@ -1,7 +1,7 @@ import { FunctionComponent, useCallback, - useEffect, + useLayoutEffect, useMemo, useReducer, useState, @@ -63,31 +63,46 @@ const CompactSuggestionController: FunctionComponent< fetchPolicy: "no-cache", }); - useEffect(() => { - if (!props.id) { - return; - } - if (props.displayImageUrl) { - return; - } + const intersectionObserver = useMemo( + () => + new IntersectionObserver( + (entries, observer) => { + if (!entries.at(0)?.isIntersecting) { + return; + } + observer.disconnect(); - const exec = () => - getNodeDisplayImage({ - variables: { - id: props.id!, + if ( + // Already included, skip it + props.displayImageUrl || + // Nothing to request, skip it + !props.id + ) { + return; + } + + getNodeDisplayImage({ + variables: { id: props.id! }, + }); }, - }); + { + rootMargin: "-30px 0px 0px -30px", + threshold: 0.02, + }, + ), - if (!lazy) { - exec(); + [getNodeDisplayImage, props.displayImageUrl, props.id], + ); + useLayoutEffect(() => { + if (!element) { return; } - // To save someone the trouble later. I attempted to use IntersectionObserver to load on demand. - // I was defeated by some interaction with the flicking.js library's carousel. All of them - // reported threshold 1 at all times. - requestIdleCallback(exec); - }, [getNodeDisplayImage, lazy, props.displayImageUrl, props.id]); + intersectionObserver.observe(element); + return () => { + intersectionObserver.disconnect(); + }; + }, [intersectionObserver, element]); // Loads the extended node information to support the focused view const [getItem, itemQuery] = useContentItemLazyQuery();