https://anotherworks.connpass.com/event/285095/
巨大tableのパフォーマンスを改善する1クラスメソッド株式会社 高橋ゆうき2023.06.22 Front-End Deep Dive
View Slide
2自己紹介高橋ゆうきクラスメソッド株式会社 CX事業本部Delivery部フロントエンドチーム チームリーダー@hbsnow
3ある日、POに言われたページの切替時に表示が遅いんだけどなんとかなりませんか?
4そこには巨大なテーブルがあった● よく使われるページのテーブルはデフォルト状態だとだいたい行100*列20○ 行数はPagerで設定をかなり大きな数値に変更○ 列は設定で最大130近くになる
5指摘された問題はAPIのせいではない● このプロジェクトではページ切替時、切り替えた先のページを一度でも開いていればリクエストを再取得していない● 今回指摘されたのはこのときの切替時、なぜAPIのリクエストがないのに表示に時間がかかるのかという点※これは参考なのであくまでこんな感じというイメージです
6windowing / 仮想スクロール の話でしょ?react-virtuosoreact-windowreact-table + react-virtual
7違うんです……react-virtuosoreact-windowreact-table + react-virtual
8テーブルが複雑すぎて● 開発開始から3年の月日が経っているため、テーブルが多くの複雑な機能を持っていて厳しかった……○ 列のD&D○ 列・行のフィルター・検索機能○ 列の一時非表示機能○ 行ソート○ 展開行○ チェックボックスでの行絞り込み○ タグでの行絞り込み○ お気に入り など、さらに日々機能も追加される
9requestIdleCallbackを使ってみる● 表示したい要素をchunk● requestIdleCallbackでCPUに余裕があるときに順次表示するようにするDeferコンポーネントを作った参考: Improving slow mounts in React appshttps://itnext.io/improving-slow-mounts-in-react-apps-cff5117696dc
10サンプルで作ったのはこんなテーブル
11サンプルはこちらhttps://hbsnow-sandbox.github.io/react-heavy-table/サイトコードhttps://github.com/hbsnow-sandbox/react-heavy-table
12before - Lighthouse
13before - Performance
14requestIdleCallback: after - Lighthouse
15requestIdleCallback: after - Performance
16requestIdleCallbackをつかったDeferコンポーネントの問題点● 結局処理に時間がかかっていることには変わらないので、微妙なスペックのPCだとtimeoutの時間をいくら長くしたところで処理が終わらなくなってくる● 小刻みに行が増えていくので、セルの幅が突然変化することがある(幅を固定できるなら問題にならない)
17メリットもあります● 導入コストが圧倒的に低い
18ある日、POに言われた Part2今度の新規ページのテーブルは3000行くらいで、Pagerはなしでお願いします
19そもそも初期表示ですべて表示する必要はないのでは?● 数値Min-MAXでのフィルター● 文字列検索機能● チェックボックスでのフィルター● タグでのフィルター
20なら素直にIntersectionObserverで良かった● 表示したい要素をchunk● IntersectionObserverで最下部まで到達したら以降のコンテンツを読み込む
21IntersectionObserver: Lighthouse
22IntersectionObserver: Performance
23だいぶ良くなったのでこれで終わり……?Pagerを作り、1ページにつき500件を表示してみる。このときにnextを二回押すとどうなるか
24Page1がスキップされるPage: 1 の表示は完全にスキップされて Page: 2 が表示される表示に時間がかかる場合、UIがブロックされてユーザーは自分がいまどういう状況なのかわかりにくい
25つまりUIをブロックせずに状態を更新したいuseTransition
26処理中であることをわかりやすくついでにisPending中にLoaderを出しました
27まとめ● 最初に思い浮かんだ方法が唯一の解決方法ではないかもしれません● 顧客が本当に解決したい課題は何かをヒアリングして、実装方法に問題ないか確認する● requestIdleCallback・IntersectionObserverは便利○ 今回話にだしていませんが、requestIdleCallbackはpolyfillが必要なので注意してください● UIがブロックされるとき、useTransitionが使えるかもしれません
28おわりありがとうございました[ad] 7/7・7/8 DevelopersIO 2023 もよろしくお願いします![ad] フロントエンドエンジニア募集中です!