🙌

LINEのトーク一覧が、仮想スクロールを考える上でとても役立った話

2024/11/29に公開

仮想スクロールは、パフォーマンスを向上させるために使用される技術で、連続するコンテンツ(記事一覧など)を表示する時に、表示領域(+α)のみのコンテンツをレンダリングする技術です。スクロールしないとみれない(ユーザからしたら不可視状態の)コンテンツはレンダリングされず、スクロールすると表示されるようになります。また、表示されているコンテンツも、表示領域外に入るとレンダリングされなくなります。

WebにおいてDOMのレンダリングはメモリを消費し大量になるとパフォーマンスが低下するため、パフォーマンス向上のために採用されます。現実的に数十万のアイテムを仮想スクロールしないとそもそもスクロールできなかったりします。

更に詳しく知りたい方は以下が詳しいです。

https://zenn.dev/yuma99313/articles/fb277c0a7cac5c

仮想スクロールは計算との戦い

仮想スクロールとは、DOMの高さの計算との戦いでもあります。簡単な例で紹介すると

  • 表示領域の高さが1,000px
  • スクロールする時にちらつかないように余裕をもって上下100pxはレンダリングしておく
  • ひとつのアイテムの高さは50px

と決め打ちになっていると、

  • 表示領域ではアイテムは20個表示される
  • 余裕をもってレンダリングしておくのは上下2つ
  • そのため、22個のアイテムがレンダリングされる

と簡単に計算しておけますよね。これが一番シンプルであり、ブラウザにとっても計算量が少ないスタイルです。ただ、現実的にはアイテムの高さが固定であることは少なく、例えばLINEトーク画面をみてもらうとわかるのですが、メッセージの長さによって高さが変わります。この場合、アイテムの高さを固定で計算することはできません。しかも、横幅を変えると一行あたりに表示できる文字数が変わるので、また高さが変わります。そして、これはブラウザにレンダリングしないと「真の高さ」は得ることができないので、アイテムごとに高さを取得する必要があり、本当ややこしい。また、それを同時に走らせるため、計算量も馬鹿になりません。

LINEのトーク一覧の工夫がすごかった

まずはこのトーク一覧をご覧ください。

73141a76d25564.png

LINEのトーク一覧って、1〜2行、最新のトーク内容がグレーで表示されるんですよね。ですので、本来でいえば、アイテムの高さは可変になります。また、横幅が変われば一行あたりも文字数が変化することによって行数が変わり、アイテムの高さも変わるはずです。

けれど、実際は最新のトーク内容が1行でも2行でも、アイテムの高さは同じになるようになっています。ただ、1行の場合はアイテムの高さを変えるのではなく、トークルーム名とトーク内容が vertical-align: middle の配置になるようにして、上下に不自然な高さをつくらないようにしています。けれど、日付は別です。等間隔になるように、アイテムに対しての絶対位置で表示されるようになってます。

これだけをみると、「デザイン的な意図があるのかな」で終わる話なのですが、仮想スクロールの観点でみると、

  • 最新のトーク内容の行数にかかわらず高さを揃えることで計算量を削減
  • けれど、アイコンと日付が固定化されているので等間隔であることに違和感を感じない
  • これを考えると、最新のトーク内容は3行は表示できないよね

と、実装上も、デザイン上も合理的であることに気付かされます。

まとめ

LINEのチームが実際に仮想スクロール的観点でこのようなデザインにしているかは不明です。ただ、自分自身で仮想スクロールを交えて実装することがあるなら、とてもこの観点は役立つかと思います。ご参考になれば幸いです。

それではまた。

Discussion