Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rohan-deshpande/2faf70ad61d52f5e539a6f4c5692382a to your computer and use it in GitHub Desktop.
Save rohan-deshpande/2faf70ad61d52f5e539a6f4c5692382a to your computer and use it in GitHub Desktop.
What is the best way to conditionally async load components based on initial viewport size?

Question:

Thinking about this in a nextjs context, let's say we have two components Video and AnimatedGif. For larger screens, we want to load the video, but for smaller screens, and perhaps slower devices, we want to show the gif. We also want to async load these, because they shouldn't block the rest of the page. They are media items so they don't need to be SSR'd, and also it would be good if this could be done with Suspense in mind. Any ideas?

Answer:

Create a custom hook, something like useDeviceAndViewport() that returns the relevant info. You need to know the network status, the viewport dimensions and whether the element is within the viewport.

Library wise, react-adaptive-hooks or react-use both look good.

Pseudo Code Implementation

const VideoThing = React.lazy(() => import('./VideoThing'));
const GifThing = React.lazy(() => import('./GifThing'));

export const GifOrVideo = props => {
  const ref = React.useRef()
  const { isSlow, isSmallDevice, isVisible } = useDeviceAndViewport(ref)
  const Comp = isSlow || isSmallDevice ? GifThing : VideoThing

  return (
    <div ref={ref}>
      {isVisible ? (
        <Suspense fallback={<div>Loading...</div>}>
          <Comp {...props} />
        </Suspense>
      ) : null}
    </div>
  )
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment