Menu

クライアントサイドレンダリング (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) => {
      // handle the error as needed
      console.error('An error occurred while fetching the data: ', e)
    })
  }, [])
 
  return <p>{data ? `Your data: ${data}` : 'Loading...'}</p>
}

上記の例では、コンポーネントは最初にLoading...をレンダリングします。その後、データがフェッチされると再レンダリングし、データを表示します。

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>Failed to load.</p>
  if (isLoading) return <p>Loading...</p>
 
  return <p>Your Data: {data}</p>
}

補足:

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