はじめに
現在の開発では、API 通信に REST API ではなく GraphQL を使用しており、そのデータ取得には Apollo Client(以下 AC)を利用しています。
AC にはデータ取得時に fetchPolicy
を設定できる機能があり、毎回ネットワークにアクセスしてデータを取得するのか、それともキャッシュを利用するのかなどを制御できます(公式Doc)。
私自身、開発の際に fetchPolicy
を意識していませんでしたが、その結果として「データを更新したのに最新データが反映されない」といった軽微なバグが発生することがありました。一方で、fetchPolicy
を適切に設定することで、パフォーマンスの向上にもつながることがわかりました。
本記事では、AC の fetchPolicy
について簡単にまとめていきます。
そもそもfetchPolicyって?
fetchPolicy
とは、AC が GraphQL のデータを どのように取得するか を制御するための設定です。
例えば、
-
キャッシュがあればそれを使うのか?
-
毎回ネットワークから取得するのか?
-
キャッシュとネットワークの両方を使うのか?
といった動作を決めることができます。
fetchPolicyの種類と使い方
fetchPolicyには6つの種類があります
fetchPolicy | 説明 |
---|---|
cache-first |
デフォルト。キャッシュがあればキャッシュを優先し、なければネットワークから取得 |
cache-and-network |
キャッシュを すぐに返しつつ、並行してネットワークから最新データを取得 |
network-only |
常にネットワークからデータを取得し、キャッシュを使用しない |
cache-only |
キャッシュのデータのみを使用し、ネットワークリクエストを行わない |
no-cache |
常にネットワークからデータを取得し、キャッシュには保存しない |
standby |
クエリは実行せず、後で明示的に実行されるまで待機 |
という風になっています。個人的に一番したのstandby
は使用したことがないので、あまり使い所はわかっていません。
cache-first(デフォルト)
const { data, loading, error } = useQuery(GET_USERS, {
fetchPolicy: "cache-first",
});
-
初回リクエスト時: ネットワークからデータを取得し、キャッシュに保存。
-
2回目以降: キャッシュがある場合はそれを利用し、ネットワークリクエストは行わない。
パフォーマンスには最適だが、最新のデータを取得しづらい...。refetch
を頻繁に使うケースとかはあまり使わない
ユーザーのプロフィール画像とかはこれが最適
cache-and-network
const { data, loading, error } = useQuery(GET_USERS, {
fetchPolicy: "cache-and-network",
});
- キャッシュにデータがあれば すぐに表示 する
- 並行して ネットワークリクエストを実行し、最新データが取得できたら UI を更新
これは結構便利、refetch
の際はこちらを設定することが多い。
network-only
const { data, loading, error } = useQuery(GET_USERS, {
fetchPolicy: "network-only",
});
- 常にネットワークから取得し、キャッシュを使わない
- 最新のデータが保証されるが、ネットワークエラー時に表示できるデータがない
常に最新のデータが保証されて欲しい時はこちらを使うことが多い。ダッシュボードではこの設定してる
cache-only
const { data, loading, error } = useQuery(GET_USERS, {
fetchPolicy: "cache-only",
});
- キャッシュがあれば表示、なければ何もしない(エラー)
- ネットワークリクエストを行わない ため、オフライン時などに有用
この設定を使ったことがない。オフラインアプリや事前にキャッシュ読み込ませたい時などに使えそう
no-cache
const { data, loading, error } = useQuery(GET_USERS, {
fetchPolicy: "no-cache",
});
- 常にネットワークから取得するが、キャッシュには保存しない
- キャッシュ汚染を防げるが、毎回 API を叩くので効率は悪い
今の所開発でキャッシュに保存したくないという場面がないので使ったことがない。一回限りの検索とか、一時的なデータ取得の時は便利そう
network-only
とno-cache
の違いって?
network-only
と no-cache
の違いは、最初はあまり明確に理解できてなかったのですが、
例えば、network-only
は 毎回ネットワークから最新のデータを取得し、取得したデータはキャッシュに保存されます。そのため、同じデータ (A) を別のコンポーネントや処理で再度取得する場合、キャッシュに保存されたデータを利用できます。
一方、no-cache
は 毎回ネットワークからデータを取得し、取得したデータをキャッシュに保存しません。そのため、同じ A のデータを別の場所で取得しようとすると、再度ネットワークリクエストが発生します。
このように、network-only
は最新データを取得しつつキャッシュを活用できるのに対し、no-cache
は 常にネットワークリクエストを発生させ、キャッシュを一切使用しない という違いがありそうです。
まとめ
意識しなくても開発は進めることはできますが、fetchPolicy
を適切に設定することで パフォーマンスの最適化や軽微なバグの防止 につながります。
さまざまな設定を試しながら、どのような挙動をするのかを確認し、楽しみながら開発を進めるといいかもです!