クライアントサイドレンダリング (CSR)

React を使用したクライアントサイドレンダリング (CSR) では、ブラウザは最小限の HTML ページとそのページに必要な JavaScript をダウンロードします。その後、JavaScript を使用して DOM を更新し、ページをレンダリングします。アプリケーションが最初に読み込まれるとき、ユーザーは完全なページが表示される前にわずかな遅延を感じる場合があります。これは、すべての JavaScript がダウンロード、解析、実行されるまでページが完全にレンダリングされないためです。

最初にページが読み込まれた後、同じウェブサイト内の他のページに移動する場合は、通常より高速です。必要なデータのみを取得し、JavaScript でページの一部を再レンダリングできるため、ページ全体をリフレッシュする必要がないからです。

Next.js では、クライアントサイドレンダリングを実装する方法が2つあります:

  1. サーバーサイドレンダリングメソッド (getStaticPropsgetServerSideProps) の代わりに、ページ内で React の useEffect() フックを使用する。
  2. SWRTanStack Query などのデータ取得ライブラリを使用してクライアント側でデータを取得する(推奨)。

以下は、Next.js ページ内で useEffect() を使用する例です:

pages/index.js
import React, { useState, useEffect } from 'react'

export function Page() {
  const [data, setData] = useState(null)

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch('https://api.example.com/data')
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }
      const result = await response.json()
      setData(result)
    }

    fetchData().catch((e) => {
      // 必要に応じてエラーを処理
      console.error('データ取得中にエラーが発生しました: ', e)
    })
  }, [])

  return <p>{data ? `あなたのデータ: ${data}` : '読み込み中...'}</p>
}

上記の例では、コンポーネントは最初に「読み込み中...」をレンダリングします。その後、データが取得されると再レンダリングされ、データが表示されます。

useEffect 内でデータを取得するパターンは古い React アプリケーションで見られるかもしれませんが、パフォーマンス、キャッシュ、楽観的更新などを向上させるため、データ取得ライブラリの使用を推奨します。以下は、SWR を使用してクライアント側でデータを取得する最小限の例です:

pages/index.js
import useSWR from 'swr'

export function Page() {
  const { data, error, isLoading } = useSWR(
    'https://api.example.com/data',
    fetcher
  )

  if (error) return <p>読み込みに失敗しました。</p>
  if (isLoading) return <p>読み込み中...</p>

  return <p>あなたのデータ: {data}</p>
}

知っておくと便利:

CSR は SEO に影響を与える可能性があることに注意してください。一部の検索エンジンのクローラーは JavaScript を実行しないため、アプリケーションの初期の空の状態や読み込み中の状態しか認識しない場合があります。また、インターネット接続が遅いユーザーやデバイスでは、すべての JavaScript が読み込まれ実行されるまで完全なページが表示されないため、パフォーマンスの問題を引き起こす可能性があります。Next.js では、アプリケーション内の各ページのニーズに応じて、サーバーサイドレンダリング静的サイト生成、クライアントサイドレンダリングを組み合わせて使用できるハイブリッドアプローチを推奨しています。App Router では、Suspense を使用したローディング UI を使用して、ページがレンダリングされている間にローディングインジケーターを表示することもできます。