[日本語訳]SWR 発展 パフォーマンス


追記: 2021年6月8日

SWR公式日本語訳ページが追加されたので、そちらをご覧ください

このページは Performance – SWRの日本語訳です
SWR日本語訳全体についてはSWR 日本語訳をご覧ください

パフォーマンス

SWRは、あらゆる種類のWebアプリで重要な機能を提供するため、パフォーマンスが最優先事項です。

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キーを持ち、ほぼ同時にレンダリングされるため、一度だけネットワークリクエストが行われます。

パフォーマンスや重複したリクエストを心配することなく、どこでもデータフック(上記の例のuseUserなど)を再利用できます。

デフォルトの dedupingInterval オプションをオーバーライドするための重複排除間隔のオプションもあります。

深い比較

SWRは、デフォルトでデータ変更の深い比較をします。 dataの値が変更されていない場合、再レンダリングはトリガーされません。

動作を変更したい場合は、compareオプションを使用して比較機能をカスタマイズすることもできます。 たとえば、APIレスポンスがサーバーのタイムスタンプを返し、データ差分から除外したい場合など。

依存関係の収集

useSWRは、dataerrorisValidating の3つのステートフルな値を返します。それぞれを個別に更新できます。 たとえば、完全なデータフェッチライフサイクル内でこれらの値を出力すると、次のようになります。


function App () {
  const { data, error, isValidating } = useSWR('/api', fetcher)
  console.log(data, error, isValidating)
  return null
}

最悪のケース(最初のリクエストが失敗し、次の再試行が成功した場合)、5行のログが表示されます。

// console.log(data, error, isValidating)
undefined undefined false // => ハイドレーション / 初回レンダー
undefined undefined true  // => フェッチ開始
undefined Error false     // => フッチ終了、エラーを取得
undefined Error true      // => リトライ開始
Data undefined false      // => リトライ終了、データを取得

状態変化は理にかなっています。 しかし、それはまた、コンポーネントが5回レンダリングされることを意味します。

data のみを使用するようにコンポーネントを変更した場合:


function App () {
  const { data } = useSWR('/api', fetcher)
  console.log(data)
  return null
}

魔法が起こります — 現在、再レンダリングは2回だけです。

// console.log(data)
undefined // => ハイドレーション / 初回レンダー
Data      // => リトライ終了、データを取得

まったく同じプロセスが内部で発生し、最初のリクエストはエラーが発生し、再試行からデータを取得しました。 ただし、SWRは、コンポーネントによって使用されているステートのみを更新します。現在はdataのみです。

これら3つのステートすべてを常に使用しているわけではない場合は、すでにこの機能の恩恵を受けています。 Vercelでは、この最適化により再レンダリングが最大60%少なくなりました。

Tree Shaking

SWRパッケージは、tree-shakeableで副作用がありません。 つまり、コアのuseSWR APIのみをインポートする場合、useSWRInfinite などの未使用のAPIはアプリケーションにバンドルされません。