Next.js 16.4: instant() で「クリック前に表示できるUI」をテストし、プリフェッチを調整する
@next/playwright の instant() で囲んだ範囲では、遷移が始まってから届くデータが止められる。だから「プリフェッチ済みの内容だけで何が見えるか」をアサートできる。このテストを先に書いてから、キャッシュとプリフェッチの設定を直していく。
どんな問題を解決する?
- 一度開いたページに戻ってもスケルトンが出る
prefetch={true}で一覧のカードを全部先読みしてしまい、リクエスト数やコストが増える- 「速くなったはず」を目視でしか確認できず、あとで知らないうちに元に戻る
やり方
前提: Cache Components と Partial Prefetching が有効(16.4 の create-next-app では既定)。
ts
// next.config.ts
const nextConfig: NextConfig = { cacheComponents: true, partialPrefetching: true };ルート単位で試すなら、そのルートで export const prefetch = 'partial' を宣言する。
- 目標をテストにする
ts
import { instant } from '@next/playwright'; import { expect, test } from '@playwright/test'; test('詳細のヘッダーはクリック前に用意されている', async ({ page }) => { await page.goto('/templates'); await instant(page, async () => { await page.getByTestId('template-card-link').first().click(); await page.waitForURL('**/templates/*'); await expect(page.getByTestId('detail-skeleton')).toHaveCount(0); await expect(page.getByTestId('detail-title')).toBeVisible(); }); });今の UI で通るテストを書く。次に目標のアサーションを足して、失敗することを確認する。
- データの種類ごとにキャッシュを分ける
- 全員で共有できる公開データは
'use cache: remote'。Vercel では Runtime Cache に入る。自前のnext startでは、cacheHandlers.remoteを設定しないとメモリに置かれる。 - ユーザーごとのデータは
'use cache: private'(ブラウザ側に保持)。[scope]などを引数で渡すと、その値がキャッシュキーに入る。 - 寿命は
cacheLife('hours')やcacheLife({ stale: 300 })、無効化のキーはcacheTag(...)で指定する。更新時はrevalidateTag()(後のリクエストで更新)か、Server Action 内でupdateTag()(その往復ですぐ反映)を呼ぶ。
- 全員で共有できる公開データは
- キャッシュした先を
<Link prefetch={true}>でプリフェッチする。動的ルートでも、行き先の URL を解決してキャッシュ済みの部分まで先読みする。 - 大きな一覧ではユーザーの意図が見えてから先読みする
tsx
const [intent, setIntent] = useState(false); <Link href={href} prefetch={intent ? true : 'auto'} onMouseEnter={() => setIntent(true)} onFocus={() => setIntent(true)} onTouchStart={() => setIntent(true)} /> - 優先度の低い部分は
navigation()の後ろに回す。import { navigation } from 'next/cache'をawaitした後のキャッシュ処理は、プリフェッチでは走らない。実際に遷移したときに実行され、戻ってきたときは再利用される。<Suspense>で囲んで使う。 - ビルドしてテストを再実行し、通るまで 2〜5 を繰り返す。通ったテストは CI に残して、退行を防ぐ。
注意点
- v0 の例では、全カードを先読みしたせいで詳細ページへのプリフェッチが 2.9 倍に増えた。そこで手順 4 のホバー起点に変えた。リクエスト数やキャッシュ費用をあわせて監視すること。
- 公式の
next-partial-prefetching-optimizerスキルを使うと、この繰り返しをエージェントに任せることもできる(AI 運用の話は ai-coding 分野で扱う)。 - 関連: Next.js 16.4: ensureStatic で静的レスポンスを保証し、navigation() でプリフェッチ対象を絞る
出典
- @nextjs · 2026-10-17
- Next.js Blog「Improving navigation experience in v0 with Next.js 16.4」: nextjs.org