無限スクロールはしばらく前から存在しています。 基本的な考え方: スクロールすると、新しいコンテンツが下部に読み込まれ、一見無限のスクロールが作成されます。 これを実装するのは簡単ですが、慎重に計画しないとパフォーマンスが低下します。 コンテンツを数回再フェッチすると、数百の DOM 要素 (その多くは非表示) が存在する可能性があります。 幸いなことに、これを軽減するパターンが存在するため、Angular を使用してパターンを検討していきます。
これは避けたいことです。
仮想スクロールでは、無限スクロールとは異なり、常に大きなリストのサブセットのみが表示されます。 すべてを一度にレンダリングするのは非効率である大規模なデータセットに最適です。 可視 (および可視に近い) アイテムのみがレンダリングされます。ユーザーがスクロールすると、項目が動的に入れ替わります。 これにより DOM 要素が大幅に削減され、パフォーマンスが向上します。
仮想スクロールは、ビューポートの高さに一致するコンテナを作成することで機能します。 表示可能なアイテム (およびバッファ) のみが、CSS を介して管理され、特定のスクロール深度でこのコンテナ内にレンダリングされます。 スクロールするとコンテナが更新され、新しいアイテムが表示されたり、表示されなくなったアイテムが削除されたり、スクロールの深さが調整されます。 これを無限スクロールと組み合わせると、パフォーマンスを犠牲にすることなく事実上無限のリストが作成されます。
以下の例は数千の項目のリストを示していますが、一度に最大 8 つの項目をレンダリングします。 スクロールすると CSS スクロールの高さが調整され、リストがより長くなったように見えます。
Reddit のページ分割された API からメディアを取得し、それを仮想スクロール リストに表示する Angular アプリケーションを構築してみましょう。 これには、サブレディットを選択するための検索バーとフィルターが含まれます。 下にスクロールすると、さらにコンテンツが読み込まれます。 私たちの主な要件:
@angular/cdk
パッケージ (仮想スクローラー コンポーネントを含む) を使用します。 npm i @angular/cdk
.
この例では Angular を使用していますが、同様のパターンは React、Vue、またはバニラ JavaScript にも適用できます。基礎となる原理を説明する基本的なデモは、ここから入手できます。
まず、Angular の HttpClient
と RxJS Observable を使用して Reddit API からコンテンツを取得し、サブレディット名とフィルターを管理するサービスを作成します。 (簡潔にするために一部のコードは省略されています。完全な実装はここにあります)。
<code class="language-typescript">// ... (Omitted for brevity) ...</code>
コンテンツ取得メソッドは、データ要求中に特定のプロパティを追跡します。 page
プロパティがクエリ文字列に追加され、最後の項目の後に新しいコンテンツがフェッチされるようになります。 また、NSFW コンテンツや投稿ヒントのないアイテムも除外します。これにより、期待されるコンテンツのみが表示されるようになります。
<code class="language-typescript">// ... (Omitted for brevity) ...</code>
query$
オブザーバブル (以前は省略されていました) は、コンテンツを取得する前に、さまざまなオブザーバブル ストリームをマージします。 scan
演算子は、以前のストリーム結果と現在のストリーム結果を結合し、複数のページにわたる大きなデータ配列を構築します。
これにより、広範囲にわたるスクロールが可能になります。サブレディット名またはフィルターの変更のみが完全な再取得をトリガーします。 nextPage
のプロパティである query$
には、現在のセットの最後の項目 ID が格納されます。これは、仮想スクローラーの下部に近づいたときに、次にどのページをフェッチするかを決定するために使用されます。
<code class="language-typescript">// ... (Omitted for brevity) ...</code>
RxJS の威力は、データ ストリームの結合と操作にあります。これにより、ビジネス ロジックがコンポーネントに到達する前に処理できるようになり、コンポーネントをクリーンで再利用可能な状態に保つことができます。
次に、Angular の CdkVirtualScrollViewport
を使用してコンテンツを表示するコンポーネントを設定します。 メソッドはビューポートの下部付近のスクロールを処理し、subRedditPage$
オブザーバブルを介して次のページを取得します。
<code class="language-typescript">// ... (Omitted for brevity) ...</code>
テンプレートは、非同期パイプを使用して query$
をサブスクライブします。 注: 仮想スクローラーは、高さが可変のコンテンツではさらに複雑になります。パフォーマンスを向上させるために、アイテムの高さを一定にすることをお勧めします。
<code class="language-html">// ... (Omitted for brevity) ...</code>
onScroll
メソッドは、ユーザーが一番下に近づくと、より多くのコンテンツを取得します。 nextPage
ID (query$
から) を使用して subRedditPage$
に送信し、次の API 呼び出しをトリガーして、query$
経由でリストを更新します。
<code class="language-typescript">// ... (Omitted for brevity) ...</code>
検索バーとタブのコントロールも統合されています (以下の単純な例)。
<code class="language-typescript">// ... (Omitted for brevity) ...</code>
これにより、実質的に無限のスクローラーが作成されます。 ここでテストできます。 Reddit の API にはレート制限があります。テスト中にぶつかる可能性があります。 追加機能などの詳細については、GitHub リポジトリこちらをご覧ください。
以上がAngular による実質的に無限のスクロールの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。