はじめに
apolloの4つの fetchPolicy を勉強していきます。
最終的なゴール
以下のような構成のアプリを作ることです。
目的
- 仕事で使っている技術のキャッチアップと復習
- 使う可能性がある技術の理解度向上
前回のおさらい
HasuraのGraphQlサーバからデータフェッチした後ComponentA
ではフェッチしたデータを表示させましたが
ComponentB
では、Apolloが作成したキャッシュのデータを取得する実装をしました。
詳細👇
なぜApolloのキャッシュ機構を学ぶのか?
ユーザーにとって良いWeb閲覧体験をしてもらうためです。そのために、パフォーマンスチューニングの理解が必要です。
Apollo Clientは不要な通信処理を防ぐため、様々なキャッシュ機構を備えています。
クエリの結果をブラウザのメモリに保存することで、サーバーからデータを取らずにメモリ上のデータを使用することができます。
apolloの4つの fetchPolicy を勉強
前回の記事では、'network-only'
だけ学びました。
const { data } = useQuery<GetUsersQuery>(GET_USERS, {
fetchPolicy: 'network-only',
})
今回は、コメントした以下も含めて見ていきます。
const { data } = useQuery<GetUsersQuery>(GET_USERS, {
fetchPolicy: 'network-only',
//fetchPolicy: 'cache-and-network',
//fetchPolicy: 'cache-first',
//fetchPolicy: 'no-cache',
})
fetchPolicy: 'cache-first'
デフォルトの場合、こちらのfetchPolicyになります。
const { data } = useQuery<GetUsersQuery>(GET_USERS, {
fetchPolicy: 'cache-first',
})
なので、以下と同じ意味です。
const { data } = useQuery<GetUsersQuery>(GET_USERS)
意味は、データがキャッシュにある場合は、そこから取得するけど、無いならGraphQlからデータフェッチします。
仮に、Hasura側で新たにUser
のデータが作られても、GraphQlからデータフェッチせず、ブラウザのメモリから取得するので、新規作成ユーザーは表示されません。
なので、更新性の高いことが価値のあるWebページでは、このfetchPolicyは採用しない方がいいでしょう。
fetchPolicy: 'no-cache'
キャッシュを使用しないポリシーです。
取得したデータをブラウザ上のメモリに保存(キャッシュ)しないのが特徴です。
クエリを投げた時に、キャッシュのデータを確認せずに、サーバーからデータを取ってきます。
const { data } = useQuery<GetUsersQuery>(GET_USERS, {
fetchPolicy: 'no-cache',
})
ブラウザ確認してみましょう。
hasura-sub
の方が何も表示されなくなりました。
なぜなら、hasura-sub
は、キャッシュからデータを取得するクエリにし(GET_USERS_LOCAL
)
fetchPolicy: 'no-cache'
は、キャッシュデータを作らないようにしているからです。
const { data } = useQuery<GetUsersQuery>(GET_USERS_LOCAL)
gif画像を見ると、Backして再度hasura-main
を見たら、またGraphQlへデータフェッチしていることがわかります。
fetchPolicy: 'no-cache'
は、毎回サーバーサイド(GraphQl)にデータフェッチしていることがわかります。
npmのaxios
でREST APIでデータ取得するイメージと似た感じかもしれません。
fetchPolicy: 'network-only'
サーバーのデータのみを使用するポリシーです。常に最新のデータを扱うことができます。
const { data } = useQuery<GetUsersQuery>(GET_USERS, {
fetchPolicy: 'network-only',
})
ブラウザ確認してみましょう。
こちらは、キャッシュしてそうですね。
そして、これなら、毎回Hasuraからのデータを読みに行っているので、最新のデータを取得できそうですね。
fetchPolicy: 'cache-and-network'
メモリ上のデータとサーバーのデータ両方を使用するポリシーです。レスポンスが早いのと、データの更新を頻繁に行うのが特徴です。
const { data } = useQuery<GetUsersQuery>(GET_USERS, {
fetchPolicy: 'cache-and-network',
})
これもサーバーサイドへ最新のデータを取得しにいくという点では
fetchPolicy: 'network-only'
と同じですが、取得中に既存のキャッシュがあればそれを表示し、
サーバからデータが取得でき次第、それを表示するという点が違います。
少し詳しく話すと。以下のような順番です。
-
- クエリを投げた時に、キャッシュ上にデータがあるかを確認
-
- キャッシュ上にデータがある場合は、キャッシュのデータを返す
-
- サーバーからデータを取ってくる
-
- サーバーから取ってきたデータをメモリ上に保存
-
- クエリの結果を返す
どのページ、どのWebアプリケーションも基本的には、ポリシーは、fetchPolicy: 'network-only'
で問題ないかと思います。
参考
今日のところは以上です。
次の記事では、Hasuraと連携させたCRUDの操作を紹介します。
アウトプット100本ノック実施中