6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

apolloの4つの fetchPolicy を理解する

Last updated at Posted at 2021-11-07

はじめに

apolloの4つの fetchPolicy を勉強していきます。

最終的なゴール

以下のような構成のアプリを作ることです。

スクリーンショット 2021-10-18 17.27.41.png

目的

  • 仕事で使っている技術のキャッチアップと復習
  • 使う可能性がある技術の理解度向上

前回のおさらい

HasuraのGraphQlサーバからデータフェッチした後ComponentAではフェッチしたデータを表示させましたが

ComponentBでは、Apolloが作成したキャッシュのデータを取得する実装をしました。

スクリーンショット 2021-11-03 21.21.15.png

詳細👇

なぜ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'

キャッシュを使用しないポリシーです。
取得したデータをブラウザ上のメモリに保存(キャッシュ)しないのが特徴です。

クエリを投げた時に、キャッシュのデータを確認せずに、サーバーからデータを取ってきます。

pages/hasura-main.tsx
const { data } = useQuery<GetUsersQuery>(GET_USERS, {
  fetchPolicy: 'no-cache',
})

ブラウザ確認してみましょう。

022e469508a54008f17ba4facd073c3b.gif

hasura-subの方が何も表示されなくなりました。

なぜなら、hasura-subは、キャッシュからデータを取得するクエリにし(GET_USERS_LOCAL

fetchPolicy: 'no-cache'は、キャッシュデータを作らないようにしているからです。

pages/hasura-sub.tsx
const { data } = useQuery<GetUsersQuery>(GET_USERS_LOCAL)

gif画像を見ると、Backして再度hasura-mainを見たら、またGraphQlへデータフェッチしていることがわかります。

fetchPolicy: 'no-cache'は、毎回サーバーサイド(GraphQl)にデータフェッチしていることがわかります。

npmのaxiosでREST APIでデータ取得するイメージと似た感じかもしれません。

fetchPolicy: 'network-only'

サーバーのデータのみを使用するポリシーです。常に最新のデータを扱うことができます。

pages/hasura-main.tsx
const { data } = useQuery<GetUsersQuery>(GET_USERS, {
  fetchPolicy: 'network-only',
})

ブラウザ確認してみましょう。

ec851185a88b0f74cf250b20b9d31018.gif

こちらは、キャッシュしてそうですね。

そして、これなら、毎回Hasuraからのデータを読みに行っているので、最新のデータを取得できそうですね。

fetchPolicy: 'cache-and-network'

メモリ上のデータとサーバーのデータ両方を使用するポリシーです。レスポンスが早いのと、データの更新を頻繁に行うのが特徴です。

pages/hasura-main.tsx
const { data } = useQuery<GetUsersQuery>(GET_USERS, {
  fetchPolicy: 'cache-and-network',
})

これもサーバーサイドへ最新のデータを取得しにいくという点では

fetchPolicy: 'network-only'と同じですが、取得中に既存のキャッシュがあればそれを表示し、

サーバからデータが取得でき次第、それを表示するという点が違います。

少し詳しく話すと。以下のような順番です。

    1. クエリを投げた時に、キャッシュ上にデータがあるかを確認
    1. キャッシュ上にデータがある場合は、キャッシュのデータを返す
    1. サーバーからデータを取ってくる
    1. サーバーから取ってきたデータをメモリ上に保存
    1. クエリの結果を返す

どのページ、どのWebアプリケーションも基本的には、ポリシーは、fetchPolicy: 'network-only'で問題ないかと思います。

参考

今日のところは以上です。

次の記事では、Hasuraと連携させたCRUDの操作を紹介します。

アウトプット100本ノック実施中

6
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?