Upgrade to Pro — share decks privately, control downloads, hide ads and more …

巨大tableのパフォーマンスを改善する

 巨大tableのパフォーマンスを改善する

hbsnow

July 14, 2023
Tweet

More Decks by hbsnow

Other Decks in Programming

Transcript

  1. 巨大tableのパフォーマンスを改善する
    1
    クラスメソッド株式会社 高橋ゆうき
    2023.06.22 Front-End Deep Dive

    View Slide

  2. 2
    自己紹介
    高橋ゆうき
    クラスメソッド株式会社 CX事業本部Delivery部
    フロントエンドチーム チームリーダー
    @hbsnow

    View Slide

  3. 3
    ある日、POに言われた
    ページの切替時に表示が
    遅いんだけど
    なんとかなりませんか?

    View Slide

  4. 4
    そこには巨大なテーブルがあった
    ● よく使われるページのテーブルはデフォルト状態だと
    だいたい行100*列20
    ○ 行数はPagerで設定をかなり大きな数値に変更
    ○ 列は設定で最大130近くになる

    View Slide

  5. 5
    指摘された問題はAPIのせいではない
    ● このプロジェクトではページ切替時、切り替えた先の
    ページを一度でも開いていればリクエストを再取得し
    ていない
    ● 今回指摘されたのはこのときの切替時、なぜAPIのリク
    エストがないのに表示に時間がかかるのかという点
    ※これは参考なので
    あくまでこんな感じというイメージです

    View Slide

  6. 6
    windowing / 仮想スクロール の話でしょ?
    react-virtuoso
    react-window
    react-table + react-virtual

    View Slide

  7. 7
    違うんです……
    react-virtuoso
    react-window
    react-table + react-virtual

    View Slide

  8. 8
    テーブルが複雑すぎて
    ● 開発開始から3年の月日が経っているため、テーブルが
    多くの複雑な機能を持っていて厳しかった……
    ○ 列のD&D
    ○ 列・行のフィルター・検索機能
    ○ 列の一時非表示機能
    ○ 行ソート
    ○ 展開行
    ○ チェックボックスでの行絞り込み
    ○ タグでの行絞り込み
    ○ お気に入り など、さらに日々機能も追加される

    View Slide

  9. 9
    requestIdleCallbackを使ってみる
    ● 表示したい要素をchunk
    ● requestIdleCallbackでCPUに余裕があるときに順次表
    示するようにするDeferコンポーネントを作った
    参考: Improving slow mounts in React apps
    https://itnext.io/improving-slow-mounts-in-react-apps-cff5117696dc

    View Slide

  10. 10
    サンプルで作ったのはこんなテーブル

    View Slide

  11. 11
    サンプルはこちら
    https://hbsnow-sandbox.github.io
    /react-heavy-table/
    サイト
    コード
    https://github.com/hbsnow-sandbox
    /react-heavy-table

    View Slide

  12. 12
    before - Lighthouse

    View Slide

  13. 13
    before - Performance

    View Slide

  14. 14
    requestIdleCallback: after - Lighthouse

    View Slide

  15. 15
    requestIdleCallback: after - Performance

    View Slide

  16. 16
    requestIdleCallbackをつかったDeferコンポーネントの問題点
    ● 結局処理に時間がかかっていることには変わらないの
    で、微妙なスペックのPCだとtimeoutの時間をいくら
    長くしたところで処理が終わらなくなってくる
    ● 小刻みに行が増えていくので、セルの幅が突然変化す
    ることがある(幅を固定できるなら問題にならない)

    View Slide

  17. 17
    メリットもあります
    ● 導入コストが圧倒的に低い

    View Slide

  18. 18
    ある日、POに言われた Part2
    今度の新規ページのテーブル
    は3000行くらいで、Pagerは
    なしでお願いします

    View Slide

  19. 19
    そもそも初期表示ですべて表示する必要はないのでは?
    ● 数値Min-MAXでのフィルター
    ● 文字列検索機能
    ● チェックボックスでのフィルター
    ● タグでのフィルター

    View Slide

  20. 20
    なら素直にIntersectionObserverで良かった
    ● 表示したい要素をchunk
    ● IntersectionObserverで最下部まで到達したら以降の
    コンテンツを読み込む

    View Slide

  21. 21
    IntersectionObserver: Lighthouse

    View Slide

  22. 22
    IntersectionObserver: Performance

    View Slide

  23. 23
    だいぶ良くなったのでこれで終わり……?
    Pagerを作り、1ページにつき500件を表示してみる。
    このときにnextを二回押すとどうなるか

    View Slide

  24. 24
    Page1がスキップされる
    Page: 1 の表示は完全にスキップされて Page: 2 が表示される
    表示に時間がかかる場合、UIがブロックされてユーザーは自分が
    いまどういう状況なのかわかりにくい

    View Slide

  25. 25
    つまりUIをブロックせずに状態を更新したい
    useTransition

    View Slide

  26. 26
    処理中であることをわかりやすく
    ついでにisPending中にLoaderを出しました

    View Slide

  27. 27
    まとめ
    ● 最初に思い浮かんだ方法が唯一の解決方法ではないかも
    しれません
    ● 顧客が本当に解決したい課題は何かをヒアリングして、
    実装方法に問題ないか確認する
    ● requestIdleCallback・IntersectionObserverは便利
    ○ 今回話にだしていませんが、requestIdleCallbackは
    polyfillが必要なので注意してください
    ● UIがブロックされるとき、useTransitionが使えるかもし
    れません

    View Slide

  28. 28
    おわり
    ありがとうございました
    [ad] 7/7・7/8 DevelopersIO 2023 もよろしくお願いします!
    [ad] フロントエンドエンジニア募集中です!

    View Slide