diff --git a/packages/visx-demo/src/components/GalleryTile.tsx b/packages/visx-demo/src/components/GalleryTile.tsx index d563981a5..46f3e5b58 100644 --- a/packages/visx-demo/src/components/GalleryTile.tsx +++ b/packages/visx-demo/src/components/GalleryTile.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import Link from 'next/link'; import ParentSize from '@visx/responsive/lib/components/ParentSize'; import { WidthAndHeight } from '../types'; @@ -18,6 +18,44 @@ type Props = { const renderLinkWrapper = (url: string | undefined, node: React.ReactNode) => url ? {node} : node; +/** + * hook which returns if the ref was ever visible. + * used for better perf/not rendering all tiles on load. + */ +function useEverVisible() { + const ref = useRef(); + const [everVisible, setIsVisible] = useState(false); + + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + setIsVisible((visible) => visible || entry.isIntersecting); + }); + }, + { + root: null, // viewport is the root + threshold: 0.01, + }, + ); + + let curr; + if (ref.current) { + curr = ref.current; + observer.observe(ref.current); + } + + return () => { + if (curr) { + observer.unobserve(curr); + observer.disconnect(); + } + }; + }, []); + + return { everVisible, ref }; +} + export default function GalleryTile({ description, detailsHeight = 76, @@ -28,21 +66,25 @@ export default function GalleryTile({ tileStyles, title, }: Props) { + const { everVisible, ref } = useEverVisible(); return ( <> {renderLinkWrapper( exampleUrl, -
+
- - {({ width, height }) => - React.createElement(exampleRenderer, { - width, - height: height + (title || description ? detailsHeight : 0), - ...exampleProps, - } as ExampleProps) - } - + {/** lazy render */} + {everVisible && ( + + {({ width, height }) => + React.createElement(exampleRenderer, { + width, + height: height + (title || description ? detailsHeight : 0), + ...exampleProps, + } as ExampleProps) + } + + )}
{(title || description) && (