Skip to Content
PatternsLazy Loading

Lazy Loading

TikTok-style sequential mounting from mukoko-weather. Only one section mounts at a time through a global FIFO queue, preventing OOM crashes on mobile devices.

Install from registry

npx shadcn@latest add https://registry.mukoko.com/api/v1/ui/lazy-section npx shadcn@latest add https://registry.mukoko.com/api/v1/ui/use-memory-pressure

Live demonstration

The first section loads eagerly. All subsequent sections wait in a FIFO queue and mount one at a time with skeleton fallbacks.

Memory API not available (Chrome only)

Sections mount one at a time through a FIFO queue (150ms mobile / 50ms desktop delay). Scroll down to see them appear.

Current Conditionsmounted

This section mounted after a 0ms delay in the queue. Scroll it far away and it will unmount to reclaim memory.

Mobile delay: 150ms|Desktop delay: 50ms|Unmount distance: 1500px

How it works

FIFO Queue

Global mount queue ensures only ONE section loads at a time. Lower priority numbers mount first.

Settle Delay

150ms between mounts on mobile (768px), 50ms on desktop. Prevents jank from simultaneous hydration.

Memory Reclaim

Sections unmount when scrolled 1500px past viewport. useMemoryPressure monitors JS heap usage.

Usage

app/dashboard/page.tsx
import { LazySection } from "@/components/lazy-section" import { SectionErrorBoundary } from "@/components/section-error-boundary" import { Skeleton } from "@/components/ui/skeleton" export default function DashboardPage() { return ( <main> {/* First section: always eager */} <SectionErrorBoundary section="Current Conditions"> <CurrentConditions /> </SectionErrorBoundary> {/* Sequential loading: one at a time */} <LazySection section="Hourly Forecast" fallback={<Skeleton className="h-64" />} > <SectionErrorBoundary section="Hourly Forecast"> <HourlyForecast /> </SectionErrorBoundary> </LazySection> <LazySection section="Weather Chart" priority={1} // mount after forecast fallback={<Skeleton className="h-80" />} > <SectionErrorBoundary section="Weather Chart"> <WeatherChart /> </SectionErrorBoundary> </LazySection> {/* Low priority — mounts last */} <LazySection section="Community Reports" priority={2}> <SectionErrorBoundary section="Community Reports"> <CommunityReports /> </SectionErrorBoundary> </LazySection> </main> ) }

Memory Pressure

Monitor JS heap usage and react to memory pressure. Chrome-only API with graceful no-op fallback on other browsers.

hooks/use-memory-pressure.ts
import { useMemoryPressure } from "@/hooks/use-memory-pressure" function App() { const { isUnderPressure, usedMB, totalMB, usagePercent } = useMemoryPressure(85) if (isUnderPressure) { // Reduce quality, unmount heavy components return <LightweightDashboard /> } return <FullDashboard /> }

LazySection props

PropTypeDefaultDescription
sectionstringSection name for logging (required)
fallback?ReactNodepulse skeletonShown while queued
priority?number0Lower = mounts first
unmountDistance?number1500Pixels past viewport to unmount
disabled?booleanfalseBypass lazy loading
Last updated on