パフォーマンス
SWRはあらゆる種類のウェブアプリで重要な機能を提供するため、パフォーマンスは最優先事項です。
SWRに組み込まれているキャッシュと重複排除は不要なネットワークリクエストをスキップしますが、useSWR
フック自体の パフォーマンスも重要です。 複雑なアプリでは、1回のページレンダリングで数百のuseSWR
呼び出しが発生する可能性があります。
SWRは、あなたのアプリが
- 不要なリクエストがないこと
- 不要な再レンダリングがないこと
- 不要なコードがインポートされていないこと
を、コードを変更することなく保証します。
重複排除
アプリでSWRフックを再利用することは非常に一般的です。 例えば、現在のユーザーのアバターを5回レンダリングするアプリを考えてみましょう。
function useUser () {
return useSWR('/api/user', fetcher)
}
function Avatar () {
const { data, error } = useUser()
if (error) return <Error />
if (!data) return <Spinner />
return <img src={data.avatar_url} />
}
function App () {
return <>
<Avatar />
<Avatar />
<Avatar />
<Avatar />
<Avatar />
</>
}
それぞれの<Avatar>
コンポーネントには、useSWR
フックが内部にあります。 SWRキーが同じで、ほぼ同時にレンダリングされるため、ネットワークリクエストは1回だけ行われます。
パフォーマンスやリクエストの重複を心配することなく、データフック(上記の例ではuseUser
など)をどこでも再利用できます。
デフォルトの重複排除間隔を上書きするためのdedupingInterval
オプションもあります。
詳細比較
SWRはデフォルトでデータの変更を詳細に比較します。 data
値が変更されていない場合、再レンダリングはトリガーされません。
動作を変更したい場合は、compare
オプションを使用して比較関数をカスタマイズすることもできます。 例えば、一部のAPIレスポンスは、データの差分から除外したいサーバタイムスタンプを返す場合があります。
依存関係の収集
useSWR
は、4つの状態を持つ値を返します。data
、error
、isLoading
、isValidating
です。それぞれ独立して更新できます。 例えば、データフェッチのライフサイクル全体でこれらの値を出力すると、次のようになります。
function App () {
const { data, error, isLoading, isValidating } = useSWR('/api', fetcher)
console.log(data, error, isLoading, isValidating)
return null
}
最悪のケース(最初のリクエストが失敗し、再試行が成功した場合)では、4行のログが表示されます。
// console.log(data, error, isLoading, isValidating)
undefined undefined true true // => start fetching
undefined Error false false // => end fetching, got an error
undefined Error true true // => start retrying
Data undefined false false // => end retrying, get the data
状態の変化は理にかなっています。しかし、それはコンポーネントが4回レンダリングされたことも意味します。
コンポーネントをdata
のみを使用するように変更した場合
function App () {
const { data } = useSWR('/api', fetcher)
console.log(data)
return null
}
魔法が起こります。再レンダリングは2回だけになります。
// console.log(data)
undefined // => hydration / initial render
Data // => end retrying, get the data
内部ではまったく同じプロセスが発生しました。最初のリクエストでエラーが発生し、再試行からデータを取得しました。 ただし、SWRはコンポーネントで使用されている状態のみを更新します。この場合はdata
のみです。
これらの3つの状態を常にすべて使用しているわけではない場合、あなたはすでにこの機能の恩恵を受けています。 Vercel (新しいタブで開きます)では、この最適化により再レンダリングが約60%削減されます。
ツリーシェイキング
SWRパッケージはツリーシェイク可能 (新しいタブで開きます)で、副作用がありません。 つまり、コアのuseSWR
APIのみをインポートしている場合、useSWRInfinite
などの未使用のAPIはアプリケーションにバンドルされません。