無限スクロールはちょくちょく実装することはあるが、追加するコンテンツの読み込みや挿入はともかく、ローディング画像の処理で悩むことがある。その表示の切り替えには実装と処理のどちらにおいてもそこそこコストがかかるからだ。かなり前に色々考えるのが面倒になり、常に表示しておくという雑な手をよく使うようになった。

Demo: Easy Loading Marker for Infinite Scroll

デモでは90%ほどスクロールすると無限スクロールっぽくコンテンツが少し時間をおいてから追加される。コンテナーである#contentの最下部には常にローディング画像を背景画像として表示してあるので、特に操作することなく無限スクロールのためにコンテンツを読込中であることを示すことができる。SVGアニメーションでローディング画像を作ったためInternet Explorer 11では回らないが、おおまかにどういう挙動をするのかはわかることだろう。

こういった雑なローディング画像の実装には利点が3つ挙げられる。

コード

単純にローディング画像の挿入と削除を担当するコードがなくなり、ローディング画像の状態を保存する必要もなくなる。アニメーションGIFではなくスケーラブルにしたい場合も、デモのようにSVGアニメーションで完結させれば、HTMLへ空要素の挿入が必要ない(CSSでやる場合は擬似要素のアニメーションという点でいろいろあるので空要素などが必要になる)。もちろんCSSのコードが単純明快になるという点も見逃せない。

ローディング画像の表示

常に表示されているので、パフォーマンスを考慮したスクロール・イベントの間引きによる若干の遅延に影響を受けない。もちろんコンテンツの挿入そのもの自体は影響を受けるが、ローディング画像の表示においては影響を受けず、長めにアニメーションするだけになる。

レンダリング・コスト

画面外で常にアニメーションをさせることにはそれなりにコストはあるが、突然DOMに要素を追加(リフローやリレイアウト)し、アニメーションを開始(アニメーションの初期化コスト)するよりは低い。デモの場合はSVG内で完結させており、GPUのサポートも期待できる。


欠点としては無限スクロール中のエラーに対して弱いことだ。追加コンテンツの読み込みとローディング画像の表示が完全に分離しているので、エラーが起きた時だけ両者を連動させる必要が出てくる。追加コンテンツの読み込み側ではエラー時にクラスを振るだけに留め、ローディング画像の表示と同じく簡単なCSSで見えなくしてやるのが妥当か。


無限スクロールにおいては、ローディング画像などを表示することなく必要そうになる前に読み込み挿入しておく方が実装としては理想に近い。しかしその理想を実現するまでには、コンテンツを送る側のパフォーマンスやいつ読み込み始めるかのタイミング、ユーザーの回線への負担など解決が必要な問題がいくつもある。まずは実装ということを考えると、この雑なローディング画像は面倒がなく、便利に使っている。