From aa077e000df94db2348fa6d744909a67706b09e1 Mon Sep 17 00:00:00 2001 From: ukimsanov Date: Wed, 5 Aug 2026 05:54:49 -0700 Subject: [PATCH] docs(examples): intersection-gate the recreate pair too ReplicaCompare now assigns/decodes its reference+replica only near the viewport and releases both (pause + removeAttribute + load) on exit, closing the last eager-load surface from Magi's #5. Sync + reduced-motion guard preserved. --- docs/snippets/replica-compare.jsx | 49 ++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/docs/snippets/replica-compare.jsx b/docs/snippets/replica-compare.jsx index e3d77ec58..49b241a27 100644 --- a/docs/snippets/replica-compare.jsx +++ b/docs/snippets/replica-compare.jsx @@ -6,9 +6,27 @@ export const ReplicaCompare = ({ replicaSrc, replicaPoster, }) => { + const wrapRef = useRef(null); const refVideo = useRef(null); const repVideo = useRef(null); const [muted, setMuted] = useState(true); + const [inView, setInView] = useState(false); + + // Only assign/decode the two films near the viewport, so the pair doesn't + // download offscreen. Falls back to eager if there's no observer. + useEffect(() => { + const el = wrapRef.current; + if (!el || typeof IntersectionObserver !== "function") { + setInView(true); + return; + } + const observer = new IntersectionObserver( + (entries) => setInView(entries[0]?.isIntersecting ?? false), + { rootMargin: "200px" }, + ); + observer.observe(el); + return () => observer.disconnect(); + }, []); // Lazy initializer, not a post-mount effect: with useState(false) the first // committed render would emit `