npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-lazyload-list

v1.0.1

Published

A React component for lazy‑loading long lists using IntersectionObserver and MutationObserver, supporting automatic bottom scrolling and optional wrapper preservation.

Readme

react-lazyload-list

react-lazyload-list は、スクロール位置に応じて子要素を遅延ロード(レイジーロード)する汎用的なリストコンポーネントです。
WrapperExposeComponent が低レベルの可視性検知ロジックを提供し、useLazyLoad フックと LazyList がそれらを組み合わせて「一定数ずつ増やす」/「下からスクロールする」リストを実装します。


目次

  1. インストール
  2. 主要エクスポートと API

インストール

# npm / yarn / pnpm いずれか
npm i react-lazyload-list   # ※パッケージ名は例です。実際はローカルで src をコピーしてください。

備考
このコンポーネントは reactreact-dom がインストールされている環境を前提にしています。IntersectionObserverMutationObserver が利用できるブラウザで動作します(IE 11 以前はポリフィルが必要)。


主要エクスポートと API

Wrapper

export function Wrapper({
  children,
  rootMargin = '500px',
}: {
  children: React.ReactNode;
  rootMargin?: string;
}): JSX.Element

役割

  • 子要素 (children) を 可視領域 になるまで 非描画 にし、IntersectionObserver がトリガーされた時点で実際にマウントします。
  • 非表示時は高さを保持(height スタイル)することでレイアウト崩れを防止します。

パラメータ

| パラメータ | 型 | デフォルト | 説明 | |-----------|----|------------|------| | children | ReactNode | - | ラップしたいコンテンツ。可視になるまで実際には DOM に挿入されません。 | | rootMargin | string | '500px' | IntersectionObserver の rootMargin。遠くの要素でも先取りしてロードしたい場合に調整します。 |

使用例

<Wrapper rootMargin="300px">
  <MyHeavyComponent />
</Wrapper>

ExposeComponent

export function ExposeComponent({
  onVisibleChange,
  onContentChange,
  bindElementRef,
  style,
  rootMargin = '1500px',
  children,
}: {
  onVisibleChange: (isVisible: boolean) => void;
  onContentChange?: () => void;
  bindElementRef?: (el: HTMLDivElement | null) => void;
  style?: React.CSSProperties;
  rootMargin?: string;
  children?: React.ReactNode;
}): JSX.Element

役割

  • IntersectionObserverMutationObserver を内部でセットアップし、下記 2 つのイベントを外部に通知します。

    1. onVisibleChange(isVisible) – 要素がビューポートに入った/出たとき。
    2. onContentChange() – 子要素が増減したとき(children が動的に変化した場合)。
  • bindElementRef で外部から DOM 要素への参照を取得でき、ラッパーコンポーネントから高さ取得等に利用できます。

パラメータ

| パラメータ | 型 | デフォルト | 説明 | |-----------|----|------------|------| | onVisibleChange | (isVisible: boolean) => void | - | 可視状態が変化したら呼び出されるコールバック。 | | onContentChange | () => void | undefined | 子要素が増減したときに呼び出されるコールバック。 | | bindElementRef | (el: HTMLDivElement \| null) => void | undefined | ref を外部に渡すための関数。 | | style | React.CSSProperties | null | 表示・非表示時の代替スタイル(幅 1px・高さ 1px 等)。 | | rootMargin | string | '1500px' | IntersectionObserver のマージン。大きくすると早めにロードされます。 | | children | ReactNode | null | 実際に表示したいコンテンツ。null のときは placeholder が描画されます。 |

使用例

<ExposeComponent
  rootMargin="1000px"
  onVisibleChange={v => console.log('visible:', v)}
  onContentChange={() => console.log('content changed')}
  bindElementRef={el => console.log('DOM element:', el)}
>
  <div>遅延ロード対象</div>
</ExposeComponent>

useLazyLoad

export function useLazyLoad({
  initCount = 8,
  stepCount = 3,
  initDataLength,
  rootMargin = '1500px',
}: {
  initCount?: number;
  stepCount?: number;
  initDataLength: number;
  rootMargin?: string;
}): [
  showCount: number,
  lazyLoadTrigger: JSX.Element | null
]

役割

  • 遅延ロードの状態管理 をフックとして提供します。

    • showCount : 現在画面に表示すべきアイテム数。
    • lazyLoadTrigger : IntersectionObserver が付与された透明な ExposeComponent(リスト末端に配置)。この要素が可視になると showCountstepCount 分増加します。
  • initCount (初期表示数) と stepCount (スクロールごとに追加表示数) を自由に設定可能です。

パラメータ

| パラメータ | 型 | デフォルト | 必須 | 説明 | |-----------|----|------------|------|------| | initCount | number | 8 | 任意 | 最初に描画する要素数。 | | stepCount | number | 3 | 任意 | 交差時に追加で描画する要素数。 | | initDataLength | number | - | 必須 | データ全体の長さ(items.length)。全件表示したら lazyLoadTriggernull になります。 | | rootMargin | string | '1500px' | 任意 | ExposeComponent の IntersectionObserver のマージン。 |

戻り値

  • showCount : 現在表示中のアイテム数(LazyList が内部で参照)。
  • lazyLoadTrigger : リストの下端(または上端)に配置すべきコンポーネント。null の場合は全件表示済みです。

使用例

const [showCount, LazyTrigger] = useLazyLoad({
  initCount: 10,
  stepCount: 5,
  initDataLength: items.length,
});

LazyList

export function LazyList(props: {
  className?: string;
  items: React.ReactNode[];
  beginFromBottom?: boolean;
}): JSX.Element

役割

  • useLazyLoad のロジックと Wrapper コンポーネントを組み合わせ、遅延ロード付きスクロールリスト を生成します。
  • beginFromBottomtrue のときは「下から」スクロール(チャットUI など)に最適化し、マウント後に自動で下端へスクロールします。

パラメータ

| パラメータ | 型 | デフォルト | 説明 | |-----------|----|------------|------| | className | string | undefined | コンテナ <div> に付与する CSS クラス名。 | | items | ReactNode[] | - | 表示したい要素の配列。(例:heights.map(h => <div style={{height:h}} />)) | | beginFromBottom | boolean | true | true → リストを下部から描画し、マウント時に自動スクロール。false → 上部から描画。 |

使用例

<LazyList
  className="chat-list"
  items={messages.map(m => <MessageBubble data={m} />)}
  beginFromBottom={true}
/>