All Patterns
⚡️ ⏐ Performance Patterns
4. Import on Visibility

Import on Visibility

Load non-critical components when they are visible in the viewport


We just saw how we can dynamically import components base on user interaction. However, we can also dynamically import components based on their visibility within the viewport.

For example, if we wanted to show the listings on smaller viewports, not all listings are instantly visible to the user.

Instead, we can lazy-load the listings, and only load them when they're visible in the viewport when the user scrolls down.


One way to dynamically import components on interaction, is by using the Intersection Observer API. There's a React hook called react-intersection-observer that we can use to easily detect whether a component is visible in the viewport.

Lazy-loading the Footer component would result in something like this:

import { Suspense, lazy } from "react";
import { useInView } from "react-intersection-observer";
const Listing = lazy(() => import("./components/Listing"));

function ListingCard(props) {
  const { ref, inView } = useInView();

  return (
    <div ref={ref}>
      <Suspense fallback={<div />}>{inView && <Listing />}</Suspense>


Faster initial load: Dynamically importing modules reduces the initial bundle size - allowing for a smaller initial load since the client doesn't have to download and execute as much, saving bandwidth.

Layout shift: A layout shift can occur if your fallback component and the component that eventually gets rendered differ a lot in size.