• #nuxt
  • #ssr
  • #performance
  • #troubleshooting
未分類

Nuxt SSRエラー対策: データ分割と<ClientOnly>

背景・問題

eps-per-scatter.vueページで以下のエラーが発生:

Error: worker exited with code 0

原因

  • actual-consensus-data.ts(約35MB)という大きな静的データファイルをインポート
  • Nuxtはデフォルトで**SSR(Server-Side Rendering)**を行う
  • SSR時にサーバー側でこの大きなファイルを処理しようとしてワーカープロセスがメモリ不足でクラッシュする

解決策

推奨: データ分割(根本解決)

ページで必要なデータだけを抽出した軽量ファイルを生成する。

本プロジェクトでの実装例:

ファイルサイズ用途
actual-consensus-data.ts35MB全メトリクス(売上、利益、EPS、PER等)
scatter-data.ts52KB散布図用(EPS成長率、PERのみ)
# 散布図用データの再生成
cd apps/web
node scripts/generate-scatter-data.mjs

メリット:

  • SSRが正常動作(ClientOnly不要)
  • ページ読み込みが高速
  • ブラウザのメモリ使用量削減

代替案: <ClientOnly>(応急処置)

ClientOnlyとは

Nuxtが提供するビルトインコンポーネントでクライアント側(ブラウザ)でのみレンダリングするよう指定できる。

<template>
  <div>
    <h1>タイトル(SSRされる)</h1>

    <ClientOnly>
      <!-- この中身はブラウザでのみレンダリング -->
      <HeavyComponent :data="largeData" />
    </ClientOnly>
  </div>
</template>

なぜ安定するのか

処理SSR(サーバー側)CSR(クライアント側)
実行環境Node.jsワーカーブラウザ
メモリ制限厳しい(ワーカー単位)緩い(ユーザーのPC依存)
大きなデータクラッシュしやすい通常問題なし

<ClientOnly>を使うと:

  1. SSR時: 中身をスキップ(空のプレースホルダーのみ)
  2. ブラウザ読み込み後: JavaScriptが実行されて中身をレンダリング

これにより、サーバー側で大きなデータを処理する必要がなくなり、クラッシュを回避できる。

実装例

Before(エラー発生)

<template>
  <div>
    <h1>散布図</h1>
    <div class="chart">
      <svg><!-- 大きなデータを使用 --></svg>
    </div>
  </div>
</template>

<script setup>
import { actualConsensusData } from '~/composables/actual-consensus-data' // 35MB
</script>

After(修正後)

<template>
  <div>
    <h1>散布図</h1>

    <ClientOnly>
      <div class="chart">
        <svg><!-- 大きなデータを使用 --></svg>
      </div>
    </ClientOnly>
  </div>
</template>

<script setup>
import { actualConsensusData } from '~/composables/actual-consensus-data' // 35MB
</script>

注意点

デメリット

  1. 初期表示が遅くなる可能性
    • SSRされないため、JavaScriptが読み込まれるまで空白になる
  2. SEOへの影響
    • <ClientOnly>内のコンテンツは検索エンジンにインデックスされにくい
    • ただしチャートやインタラクティブなUIは元々SEO対象外なので問題なし
  3. フラッシュ(ちらつき)
    • ページ読み込み時に一瞬空白が見える場合がある

フォールバック表示

読み込み中の表示を設定できる:

<ClientOnly>
  <template #fallback>
    <div class="loading">読み込み中...</div>
  </template>

  <HeavyComponent />
</ClientOnly>

いつ使うべきか

ケースClientOnly使用
大きなデータファイルを使用✅ 推奨
ブラウザAPIを使用(window, document等)✅ 必須
チャート・グラフ✅ 推奨
テキストコンテンツ❌ SSRした方がよい
SEO重要なコンテンツ❌ SSRした方がよい

参考