$30 off During Our Annual Pro Sale. View Details »

GraphQLにおけるクライアントキャッシュ戦略

 GraphQLにおけるクライアントキャッシュ戦略

KazukiHayase

March 16, 2023
Tweet

More Decks by KazukiHayase

Other Decks in Technology

Transcript

  1. GraphQLにおけるクライアントキャッシュ戦略
    2023.03.15リクルート × BASE × バイセル 【第1回フロントエンド勉強会】React & GraphQL
    2023.03.15

    View Slide

  2. 自己紹介
    名前:早瀬和輝
    出身:愛知県名古屋市
    経歴:BuySell Technologiesに2021年に新卒入社
    趣味:開発、マンガ、アニメ、ベース、バスケ
    Twitter:@KazukiHayase

    View Slide

  3. はじめに
    ● 今回話すのはクライアント側のキャッシュについて
    ● CDNなどのキャッシュについては触れないです

    View Slide

  4. アジェンダ
    キャッシュの仕組み
    01
    キャッシュにおける課題
    02
    課題解決へのアプローチ
    03
    まとめ
    04

    View Slide

  5. アジェンダ
    キャッシュの仕組み
    01
    キャッシュにおける課題
    02
    課題解決へのアプローチ
    03
    まとめ
    04

    View Slide

  6. キャッシュの仕組み
    ● いくつかのGraphQL Clientにはキャッシュ機構が備わっている
    ○ Apollo Client, Relay, urql
    ● キャッシュを活用することで無駄なリクエストが減る
    ● そのためにはキャッシュ機構の正しい理解が必要

    View Slide

  7. キャッシュ機構において重要な要素
    データの正規化
    01
    キャッシュの
    利用条件
    02

    View Slide

  8. データの正規化
    ● レスポンスデータは正規化されてキャッシュに保存される
    ● 正規化することで
    ○ キャッシュへのアクセスが早くなる
    ○ データサイズを小さくすることができる

    View Slide

  9. 正規化の流れ
    1. Queryの結果を個別のオブジェクトに分割
    2. 分割したオブジェクトに一意な識別子を割り当て
    3. フラットなデータ構造に格納

    View Slide

  10. 正規化の流れの例
    右図のような
    SchemaとQueryを考える
    ※ Apollo Clientを例に解説しますが、
    他のClientでも大枠の流れは同じです

    View Slide

  11. 正規化の流れの例
    Queryの実行結果として
    右図のようなレスポンスを受け取る

    View Slide

  12. 正規化の流れの例
    1. Queryの結果を個別の
    オブジェクトに分割
    2. 分割したオブジェクトに一意
    な識別子を割り当て
    3. フラットなデータ構造に格納

    View Slide

  13. 正規化の流れの例
    1. Queryの結果を個別の
    オブジェクトに分割
    2. 分割したオブジェクトに一意
    な識別子を割り当て
    3. フラットなデータ構造に格納
    Task:1
    Task:2
    Task:3

    View Slide

  14. 正規化の流れの例
    1. Queryの結果を個別の
    オブジェクトに分割
    2. 分割したオブジェクトに一意
    な識別子を割り当て
    3. フラットなデータ構造に格納

    View Slide

  15. キャッシュの利用条件
    ● データが全てキャッシュにある場合はキャッシュを利用
    ● 一部でもデータがキャッシュにない場合はリクエストを実行

    View Slide

  16. キャッシュの利用条件
    ● FetchTasks→FetchTasks2
    ○ キャッシュが利用できない
    ○ リクエストは2回
    ● FetchTasks2→FetchTasks
    ○ キャッシュが利用できる
    ○ リクエストは1回

    View Slide

  17. アジェンダ
    キャッシュの仕組み
    01
    キャッシュにおける課題
    02
    課題解決へのアプローチ
    03
    まとめ
    04

    View Slide

  18. キャッシュにおける課題
    一部でもデータがキャッシュにない場合はリクエストが実行される
    Queryの定義によっては全くキャッシュが利用されない

    View Slide

  19. キャッシュにおける課題
    逆に常にキャッシュが利用されるようにしようとすると
    考慮するべきことが多い

    View Slide

  20. キャッシュにおける課題
    仮に常にキャッシュが利用されるようにしようとすると
    ● Queryの実行順序を工夫する
    ● オブジェクト単位でQueryをまとめる
    ● アプリケーション全体でQueryを使い回す

    View Slide

  21. できなくはないが、、

    View Slide

  22. 個人的にはデメリットの方が大きいと判断

    View Slide

  23. キャッシュにおける課題
    ● Queryの実行順序を工夫する
    ○ →実行順序まで考慮するのは現実的ではない
    ● オブジェクト単位でQueryをまとめる
    ○ →オーバーフェッチにつながる、RESTとほぼ変わらない
    ● アプリケーション全体でQueryを使い回す
    ○ →Query変更時の影響範囲が広い

    View Slide

  24. アジェンダ
    キャッシュの仕組み
    01
    キャッシュにおける課題
    02
    課題解決へのアプローチ
    03
    まとめ
    04

    View Slide

  25. 課題解決へのアプローチ
    ページ単位での
    キャッシュ最適

    01
    データを
    3種類に分類
    02

    View Slide

  26. ページ単位でのキャッシュ最適化
    ● ページ単位でキャッシュ最適化を考える
    ● アプリケーション全体でのキャッシュの利用は考慮しない
    ○ Queryによってはキャッシュが利用される場合もある

    View Slide

  27. ページ単位でのキャッシュ最適化
    ページを跨いだキャッシュの利用を考慮しないことで
    ● ページで使用するデータを宣言的に定義できる
    ○ GraphQLの良さを最大限活かす
    ● ページ同士が疎結合になる
    ○ Queryの変更の影響範囲が閉じる

    View Slide

  28. データを3種類に分類
    データを3種類に分類して、分類ごとにQueryを定義
    することでキャッシュを利用しやすくする

    View Slide

  29. データを3種類に分類
    コンテンツデータ マスタデータ 汎用マスタデータ
    01 02 03

    View Slide

  30. コンテンツデータ
    ● コンテンツ表示用のデータ
    ● アクションに応じてQueryを定義する
    ○ e.g. 初回表示、検索、モーダル
    ○ 1ページに複数のQueryが定義されていることもある
    ● 同じアクションであればキャッシュが利用される

    View Slide

  31. マスタデータ
    ● マスタデータやメタデータなどのシステム的に必要なデータ
    ● 最初のレンダリング時のみリクエストが必要
    ● 2回目以降はキャッシュを利用する

    View Slide

  32. 汎用マスタデータ
    ● 基本的には使用しない
    ○ コンテンツデータ・マスタデータのみの運用をまずは考える
    ● アプリケーション全体で利用するかつサイズの大きいデータ
    ● どうしてもアプリケーション全体でキャッシュしたい際に使用
    ● オーバーフェッチを許容

    View Slide

  33. データ分類フロー
    ユーザーのアクションによって取得データが変わるか?
    コンテンツデータ
    マスタデータ
    汎用マスタデータ
    Yes
    ページごとで重複して取得する事に
    パフォーマンス上の懸念があるか?
    No
    Yes No

    View Slide

  34. 全体像
    PageComponentA
    PageComponentA
    ContentQuery
    PageComponentA
    MasterQuery
    GeneralMasterQuery
    PageComponentB
    PageComponentB
    ContentQuery
    PageComponentB
    MasterQuery
    ページコンポーネントごとに
    コンテンツ・マスタデータのQueryを定義
    汎用マスタデータのQueryは
    コンポーネントの外で定義

    View Slide

  35. データ分類の例
    タスク検索画面

    View Slide

  36. コンテンツデータ
    ● タスクの検索結果のデータ
    ● 検索の度に表示内容が変わる
    ● 同じ検索条件ならキャッシュ
    を利用

    View Slide

  37. マスタデータ
    ● 検索で利用する選択肢データ
    ● 検索結果に関係なくデータは
    同じ
    ● 初回以降はキャッシュを利用

    View Slide

  38. 汎用マスタデータ
    ● 検索で利用する選択肢データ
    ● 数千規模のデータかつ
    他の画面でも使うと仮定
    ● この画面のみの利用であれば
    マスタデータに含める

    View Slide

  39. アジェンダ
    キャッシュの仕組み
    01
    キャッシュにおける課題
    02
    課題解決へのアプローチ
    03
    まとめ
    04

    View Slide

  40. まとめ
    ● キャッシュの仕組みを踏まえた上での戦略
    ○ ページ単位でのキャッシュ最適化
    ○ データを3種類に分類
    ● GraphQLの良さを生かしつつ、キャッシュも活用できる
    ● ただし懸念はある
    ○ 汎用データが増えすぎると今回紹介した課題が再度浮上する

    View Slide

  41. THANK YOU

    View Slide