Skip to content

LazyMount

SM · 950B gzip budget

Defers mounting expensive children until visible, sooner on good connections.

Category
Media & layout
Budget
sm, single-purpose control
External runtime
React / React DOM only
axe fixtureSSR rendersource scanbundle budget

Preview

Live fixture
Preview locale

Mounted content

Try the component here. Locale-aware formatting and direction follow the selected language; example content and labels are not automatically translated. Overlay demos use interactive launchers.

Install

npx shadcn@latest add https://gear5-ui.vercel.app/r/lazy-mount.json

Copies the source into your project. Pulls in 1 shared registry item: use-network.

New here? Set up Tailwind and import aliases first →

Source & props

Edit on GitHub ↗

Prop types and inline documentation are included below. This is repository source; the installer rewrites shared imports for your project.

"use client";

import { useEffect, useRef, useState } from "react";
import { useNetwork } from "../lib/use-network";

export interface LazyMountProps {
  children: React.ReactNode;
  fallback?: React.ReactNode;
  /** Mount immediately regardless of visibility or connection. */
  eager?: boolean;
}

/**
 * Defers mounting expensive children (a video embed, a map, a chart library)
 * until they scroll into view — and, on a constrained connection, until the
 * user has already shown intent to be on this part of the page, rather than
 * paying for it the moment it exists in the DOM.
 */
export function LazyMount({ children, fallback = null, eager = false }: LazyMountProps) {
  const [visible, setVisible] = useState(eager);
  const ref = useRef<HTMLDivElement>(null);
  const { constrained } = useNetwork();

  useEffect(() => {
    if (eager || visible || !ref.current) return;

    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting) setVisible(true);
      },
      { rootMargin: constrained ? "0px" : "200px" },
    );

    observer.observe(ref.current);
    return () => observer.disconnect();
  }, [eager, visible, constrained]);

  return <div ref={ref}>{visible ? children : fallback}</div>;
}

What CI checks

Quality contract
  • Bundled, minified and gzipped against its tier budget
  • Audited by axe in the state previewed above
  • Rendered through react-dom/server with no browser globals
  • Scanned for network calls, dangerous sinks, and unguarded animation