• #nuxt
  • #performance
  • #prefetch
  • #troubleshooting

ブログ一覧→記事ページ遷移が遅い問題の調査

問題

/blog から記事ページへのクリック遷移に約1秒のラグがある。静的サイトなのに遅すぎる。


調査結果

Chrome DevToolsで計測

ページ遷移時のネットワークリクエストを確認したところ、65個のリクエストが発生していた。

問題の原因:過剰なプリフェッチ

1. 大量の_payload.jsonリクエスト(10個以上)

/blog/openai-vs-google-considerations/_payload.json
/blog/nvidia-moat/_payload.json
/blog/tax-consultation-form/_payload.json
/blog/tax-accountant-inquiry/_payload.json
/blog/drawio-viewer-test/_payload.json
/blog/blood-medicine-world/_payload.json
/blog/blood-type-basics/_payload.json
/blog/ai-native-future-scenarios/_payload.json
/blog/investment-critical-point/_payload.json
/blog/scenario4-tipping-point/_payload.json
/blog/data-value-breakthrough-analysis/_payload.json
/blog/brownian_motion_infographic/_payload.json

2. 各記事のCSS/JSも個別にロード

openai-vs-google-considerations.T4dg9TZR.css
nvidia-moat.BnXyxzET.css
tax-consultation-form.CLOIx3Et.css
... など

3. 巨大な/blog/_payload.json

全記事のメタデータ(140件以上)を含む巨大なJSON。


原因の分析

NuxtLinkのデフォルト動作

Nuxtは<NuxtLink>コンポーネントで、ビューポート内のリンクを自動的にプリフェッチする。

<!-- これがデフォルト動作 -->
<NuxtLink to="/blog/article-name">記事タイトル</NuxtLink>

ブログ一覧ページには多数のリンクがあるため:

  1. ページ表示時にビューポート内の全リンクを検出
  2. 各リンク先の_payload.jsonをプリフェッチ
  3. 各記事のCSS/JSもプリロード
  4. 結果:大量の同時リクエストでネットワークが詰まる

なぜ「遷移時」に遅く感じるか

実際は「遷移前のプリフェッチ完了待ち」と「遷移後のハイドレーション」が重なっている。


解決策

対策1: NuxtLinkのprefetch無効化(推奨)

<!-- ブログ一覧のリンクでprefetchを無効化 -->
<NuxtLink :to="article.path" :prefetch="false">
  {{ article.title }}
</NuxtLink>

対策2: nuxt.config.tsでグローバル設定

export default defineNuxtConfig({
  experimental: {
    // 全体的にprefetchを無効化
    payloadExtraction: false
  },
  // または
  router: {
    options: {
      // プリフェッチを完全に無効化
      linkPrefetchedClass: false
    }
  }
})

対策3: ページネーションの導入(既に導入済み)

注意: 本プロジェクトでは既にArticleTableコンポーネントで20件ページネーションを導入済み。

<!-- 既存の実装 -->
<ArticleTable :articles="allArticles" :items-per-page="20" />

しかし、ページネーション導入だけでは不十分。NuxtLinkのprefetchがデフォルトで有効なため、表示されている20件分のプリフェッチは依然として発生する。

つまり、ページネーション + prefetch無効化の両方が必要。

対策4: インターセクションオブザーバーで遅延プリフェッチ

ユーザーがスクロールして近づいた時だけプリフェッチ:

// nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    // ビューポートに入った時だけprefetch
    viewTransition: true
  }
})

優先度と推奨対応

対策効果実装難易度推奨度
prefetch無効化⭐⭐⭐
ページネーション⭐⭐
payloadExtraction無効化⭐⭐
遅延プリフェッチ

最も手軽で効果的なのは、ブログ一覧の<NuxtLink>:prefetch="false"を追加すること。


関連ドキュメント

参考リンク