コンテンツへスキップ
ドキュメント
プリフェッチ

データのプリフェッチ

トップレベルのページデータ

SWRのデータをプリフェッチする方法はたくさんあります。トップレベルのリクエストには、rel="preload" (新しいタブで開きます) を強く推奨します。

<link rel="preload" href="/api/data" as="fetch" crossorigin="anonymous">

HTMLの<head>内に入れるだけです。簡単、高速、かつネイティブです。

JavaScriptのダウンロードが始まる前でも、HTMLのロード時にデータをプリフェッチします。同じURLへのすべての着信フェッチリクエストは、結果を再利用します(もちろんSWRも含まれます)。

プログラムによるプリフェッチ

SWRは、リソースをプログラムでプリフェッチし、結果をキャッシュに保存するためのpreload APIを提供します。preloadは、引数としてkeyfetcherを受け入れます。

Reactの外でもpreloadを呼び出すことができます。

import { useState } from 'react'
import useSWR, { preload } from 'swr'
 
const fetcher = (url) => fetch(url).then((res) => res.json())
 
// Preload the resource before rendering the User component below,
// this prevents potential waterfalls in your application.
// You can also start preloading when hovering the button or link, too.
preload('/api/user', fetcher)
 
function User() {
  const { data } = useSWR('/api/user', fetcher)
  ...
}
 
export default function App() {
  const [show, setShow] = useState(false)
  return (
    <div>
      <button onClick={() => setShow(true)}>Show User</button>
      {show ? <User /> : null}
    </div>
  )
}

Reactのレンダリングツリー内では、イベントハンドラーやuseEffectでもpreloadを使用できます。

function App({ userId }) {
  const [show, setShow] = useState(false)
 
  // preload in effects
  useEffect(() => {
    preload('/api/user?id=' + userId, fetcher)
  }, [userId])
 
  return (
    <div>
      <button
        onClick={() => setShow(true)}
        {/* preload in event callbacks */}
        onHover={() => preload('/api/user?id=' + userId, fetcher)}
      >
        Show User
      </button>
      {show ? <User /> : null}
    </div>
  )
}

Next.jsのページプリフェッチ (新しいタブで開きます)のようなテクニックと組み合わせることで、次のページとデータを瞬時にロードできます。

Suspenseモードでは、ウォーターフォール問題を回避するためにpreloadを利用する必要があります。

import useSWR, { preload } from 'swr'
 
// should call before rendering
preload('/api/user', fetcher);
preload('/api/movies', fetcher);
 
const Page = () => {
  // The below useSWR hooks will suspend the rendering, but the requests to `/api/user` and `/api/movies` have started by `preload` already,
  // so the waterfall problem doesn't happen.
  const { data: user } = useSWR('/api/user', fetcher, { suspense: true });
  const { data: movies } = useSWR('/api/movies', fetcher, { suspense: true });
  return (
    <div>
      <User user={user} />
      <Movies movies={movies} />
    </div>
  );
}

データの事前入力

既存のデータをSWRキャッシュに事前に入力する場合は、fallbackDataオプションを使用できます。例えば

useSWR('/api/data', fetcher, { fallbackData: prefetchedData })

SWRがまだデータをフェッチしていない場合、このフックはフォールバックとしてprefetchedDataを返します。

<SWRConfig>fallbackオプションを使用して、すべてのSWRフックと複数のキーに対してこれを構成することもできます。詳細については、Next.js SSGとSSRを確認してください。