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

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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide