要約: DOM 要素を再利用し、 表示されなくなります。プレースホルダを使用して、遅延データを考慮します。こちらの demo とコードを スクローラーです。
無限のスクローラーがインターネット上に出現します。Google ミュージックのアーティスト リストは Facebook のタイムラインと Twitter のライブフィードがありますマイページ 下にスクロールすると、新しいコンテンツが魔法のように表示されます。 どこから来たのかな?ユーザーにとってのシームレスなエクスペリエンスで、 再審査請求をご覧ください
しかし、無限スクローラーの背後にある技術的な課題は、それよりも難しい 考えてみましょう。The Right ThingTM をやろうとしたときに直面するさまざまな問題 広大ですまず、フッター内のリンクが コンテンツによってフッターが押し下げられるため、実質的にアクセス不能になります。しかし、 問題が難しくなりますサイズ変更イベントを処理する方法は、 スマートフォンを縦向きから横向きに変える方法 スマートフォンのひび割れを防ぐには リストが長くなりすぎると つまずくのはやめましょう
The RightsTM
これこそが、リファレンス実装を考案した十分な理由であると考えました。 さまざまな問題に再利用可能な方法で対処すると同時に、 パフォーマンス基準を維持します。
目標を達成するために、DOM のリサイクル、tombstone の 3 つの手法を使用します。 スクロールのアンカーなどです
デモケースは、スクロール可能なハングアウトのようなチャット ウィンドウです。 確認できます。まず必要なのは、無限のチャットソース ブロックすることもできます。技術的には、世界の無限スクローラーは 無限に生成できますが、これらのデータに取り出せるデータの量が スクロールユーザーを増やすこともできますわかりやすくするために、ここでは、変数をハードコードして メッセージ、投稿者、必要に応じて添付する画像を選択します。 遅延を掛けてランダム化させ、 接続します。
DOM リサイクル
DOM のノード数を少なくするための DOM リサイクル手法は、あまり利用されていません。「 一般的には、画面外の既製の DOM 要素を使って、 時間をかける必要がありません確かに DOM ノード自体は安価ですが それぞれがメモリ、レイアウト、スタイル、ペイントに追加コストがかかるため、無料ではありません。 ローエンド デバイスは、完全に使用できなければ、 DOM が大きすぎて管理できませんまた、すべての再レイアウトは スタイルの再適用、つまりクラスメートが呼び出されたときにトリガーされる ノードの追加または削除 – 大きな DOM ほどコストが増加します。 DOM ノードをリサイクルすると、DOM の総数は今後も維持される 大幅に削減され、すべてのプロセスが高速化されます。
最初のハードルはスクロールそのものですデータセットはごく小さなサブセットなので 常に DOM で利用可能なすべてのアイテムの 表示されるコンテンツの量がブラウザのスクロールバーに 理論上はそこです変換では 1 x 1 ピクセルのセンチネル要素を使用します。 アイテムを含む要素(滑走路)に、意図したとおりに あります。ランウェイのすべての要素を独自のレイヤにプロモートして、 滑走路自体の層を完全に空にするためです。背景色なし、 ありません。ランウェイのレイヤが空でない場合、ブラウザの グラフィックス カードにテクスチャを保存しておき、 高さは数十万ピクセルですクラウドプロバイダが提供する 接続します
スクロールのたびに、ビューポートが 終わりですその場合は、標識を動かしてランウェイを延長します。 要素を使用し、ビューポートから離れたアイテムを 新しいコンテンツを流用できます
<ph type="x-smartling-placeholder">
逆方向のスクロールについても同様です。ただし、Google が 実装でランウェイを縮小し、スクロールバーの位置が固定されるようにする 必要があります。
Tombstone
先ほど述べたように、データソースを 実世界での体験です。ネットワーク レイテンシなどつまり、 ユーザーはフリッキースクロールを活用して 最後の要素まで簡単にスクロールできます データがありますその場合は、Tombstone アイテムを配置します。 プレースホルダ – これは、 確認しましたTombstone もリサイクルされ、専用のプールで 再利用できます。移行を円滑に進めるために、 コンテンツが入力されたアイテムに tombstone を割り当てると、 ユーザーが不快に感じるだけでなく、実際に何をしていたのかわからなくなる可能性があります。 学習します
ここで興味深い課題は、実際のアイテムの高さは Tombstone のアイテムは、アイテムや添付されたファイルごとに 説明します。この問題を解決するために、現在のスクロール位置が毎回調整され、 データを受信し、tombstone がビューポートの上に置き換えられる。アンカー スクロール位置をピクセル値ではなく要素に設定します。このコンセプトは スクロールアンカーという機能を使用します
スクロールのアンカー
スクロールのアンカーは、tombstone が次のように置き換えられるときにも呼び出されます。 ウィンドウのサイズが変更されると 表示されます。最も目立つ要素は何か、 定義します。この要素は部分的にしか表示されないため、 ビューポートを開始する要素の上からのオフセットを格納します。
ビューポートのサイズが変更され、滑走路が変更された場合、 視覚的にユーザーと同じ感覚を持たせることができます。勝ちましょう!サイズが変更されたものを除く 各アイテムの高さが変更された可能性があるという意味です。 アンカー コンテンツの配置場所を把握するにはどうすればよいでしょうか。いいえ。確認する アンカー アイテムの上にすべての要素をレイアウトし、すべての要素を 身長。サイズ変更後に大幅な一時停止が 発生する可能性があります 望んでいます。代わりに、上記のすべてのアイテムが同じサイズであると仮定しています。 スクロール位置を調整します。要素が スクロール位置が調整されて レイアウトの動作を調整できます。
レイアウト
重要な詳細の説明をスキップしました。「レイアウト」です。DOM 要素のリサイクルのたびに 通常は滑走路全体が再レイアウトされるため 60 フレーム/秒を目標にしていますこれを避けるために、Google は 絶対配置された要素を変換で使用することです。 こうして、滑走路上のすべての要素がまだ 実際には空きスペースしかなくても スペースを占拠しますここでは、 各アイテムの最終的な位置をキャッシュして ユーザーが後方にスクロールしたときに、すぐにキャッシュから正しい要素を読み込むようにします。
アイテムが DOM に接続されたときに 1 回だけ再ペイントするのが理想的 また、ランウェイ内でのアイテムの追加や削除に煩わされずに済みます。つまり 最新のブラウザでのみ利用できます。
最先端の調整
先日、Chrome に「CSS Containment」のサポートを追加しました。
要素が境界線であることをブラウザに知らせることができます。
ペイント作業を行いますここではレイアウトを作成するので、
封じ込める必要がありますランウェイに要素を追加するときはいつでも、私たちは認識しています
他のアイテムは再レイアウトの影響を受けなくて済みます。各アイテムは
contain: layout
。ウェブサイトの他の部分への影響もしたくない
ランウェイ自体もこのスタイル ディレクティブを取得する必要があります。
もう一つ検討したのは
IntersectionObservers
:
リサイクルを開始し、新しい要素を読み込むのに十分な数までスクロールしました。
分析できますただし、IntersectionObservers はレイテンシが高くなるように指定されています(
requestIdleCallback
を使用するなど)、実際に反応が鈍くなる可能性があります。
IntersectionObserver は行わなくても大丈夫。現在の実装でさえ
scroll
イベントでは、スクロール イベントが
「ベスト エフォート」方式で対応します。最終的に Houdini のコンポジター ワークレットが
この問題にフィデリティの高いソリューションが
適しているでしょう
まだ完璧ではない
すべての要素が追加されるため、Google が現在実装している DOM リサイクルは理想的とは言えません。 ビューポートを通過する要素ではなく、 実際に画面に表示されます。つまり、非常に速くスクロールすると、 Chrome のレイアウトやペイントに 多くの手間がかかりすぎて追いつけません終了 背景しか見えません。世界の終わりではなく 必ず改善すべき点があります
実際にやってみると、単純な問題がどれほど難しくなるか、おわかりいただけたでしょうか。 優れたユーザー エクスペリエンスと高パフォーマンス標準を兼ね備えています。あり プログレッシブ ウェブアプリがスマートフォンの中核的なエクスペリエンスとなり、 ますます重要性が高まっており、ウェブ デベロッパーは パフォーマンスの制約を尊重するパターンを使用します
すべてのコードはリポジトリにあります。Google の 再利用できるよう努めていますが、実際のライブラリとして npm または個別のリポジトリとして提供します。主な用途は教育である。