Next.jsアプリケーションの本番環境への最適化方法
Next.jsアプリケーションを本番環境へ移行する前に、最高のユーザー体験、パフォーマンス、セキュリティを実現するために検討すべき最適化とパターンがあります。
このページでは、アプリケーション構築時と本番環境への移行前に参考にできるベストプラクティス、および認識しておくべきNext.jsの自動最適化を提供します。
自動最適化
これらのNext.js最適化はデフォルトで有効になっており、設定は不要です:
- Server Components: Next.jsはデフォルトでServer Componentsを使用します。Server Componentsはサーバー上で実行され、クライアント側でレンダリングするためにJavaScriptを必要としません。そのため、クライアント側のJavaScriptバンドルのサイズに影響を与えません。その後、必要に応じてClient Componentsを使用できます。
- Code-splitting: Server Componentsはルートセグメント別の自動code-splittingを実現します。必要に応じて、lazy loadingによるClient Componentsとサードパーティライブラリの読み込みも検討してください。
- Prefetching: ユーザーのビューポートに新しいルートへのリンクが入ると、Next.jsはそのルートをバックグラウンドで事前読み込みします。これにより、新しいルートへのナビゲーションはほぼ瞬時に行われます。必要に応じて、事前読み込みをオプトアウトできます。
- Static Rendering: Next.jsはビルド時にサーバー上でServer ComponentsとClient Componentsを静的にレンダリングし、レンダリング結果をキャッシュしてアプリケーションのパフォーマンスを向上させます。必要に応じて、特定のルートに対してDynamic Renderingをオプトインできます。
- Caching: Next.jsはデータリクエスト、Server ComponentsとClient Componentsのレンダリング結果、静的アセットなどをキャッシュして、サーバー、データベース、バックエンドサービスへのネットワークリクエスト数を削減します。必要に応じて、キャッシングをオプトアウトできます。
これらのデフォルト設定は、アプリケーションのパフォーマンスを向上させ、各ネットワークリクエストのコスト及びデータ転送量を削減することを目的としています。
開発中
アプリケーション構築時には、最高のパフォーマンスとユーザー体験を確保するために、以下の機能の使用を推奨します:
ルーティングとレンダリング
- Layouts: レイアウトを使用してページ間でUIを共有し、ナビゲーション時の部分的なレンダリングを実現します。
<Link>component: クライアント側ナビゲーションと事前読み込みのために<Link>コンポーネントを使用します。- Error Handling: カスタムエラーページを作成して、本番環境でキャッチオールエラーと404エラーを適切に処理します。
- Client and Server Components: Server ComponentsとClient Componentsの推奨される構成パターンに従い、
"use client"境界の配置を確認して、クライアント側のJavaScriptバンドルの不必要な増加を避けます。 - Dynamic APIs:
cookiesやsearchParamsプロップなどのDynamic APIsはルート全体をDynamic Renderingにオプトインします(またはRoot Layout内で使用された場合はアプリケーション全体)。Dynamic API使用は意図的であることを確認し、必要に応じて<Suspense>境界でラップしてください。
補足: Partial Prerendering(実験的)により、ルート全体をdynamic renderingにオプトインせずに、ルートの一部を動的にすることが可能になります。
データ取得とキャッシング
- Server Components: Server Componentsを使用したサーバー側でのデータ取得のメリットを活かします。
- Route Handlers: Client ComponentsからバックエンドリソースにアクセスするためにRoute Handlersを使用します。ただし、追加のサーバーリクエストを回避するため、Server ComponentsからRoute Handlersを呼び出さないようにしてください。
- Streaming: Loading UIとReact Suspenseを使用してサーバーからクライアントへUIを段階的に送信し、データ取得中にルート全体がブロッキングされることを防ぎます。
- Parallel Data Fetching: 必要に応じて並列でデータを取得してネットワークウォーターフォールを削減します。また、必要に応じてデータの事前読み込みも検討してください。
- Data Caching: データリクエストがキャッシュされているかどうかを確認し、必要に応じてキャッシングをオプトインします。
fetchを使用しないリクエストがキャッシュされていることを確認してください。 - Static Images:
publicディレクトリを使用してアプリケーションの静的アセット(画像など)を自動的にキャッシュします。
UIとアクセシビリティ
- Forms and Validation: Server Actionsを使用してフォーム送信、サーバー側検証、エラー処理を行います。
- Global Error UI:
app/global-error.tsxを追加して、アプリケーション全体のキャッチされないエラーに対して一貫性のあるアクセシブルなフォールバックUIとリカバリーを提供します。 - Global 404:
app/global-not-found.tsxを追加して、アプリケーション全体でマッチしないルートに対してアクセシブルな404を提供します。
- Font Module: Font Moduleを使用してフォントを最適化します。これは自動的にフォントファイルを他の静的アセットと共にホストし、外部ネットワークリクエストを削除し、layout shiftを削減します。
<Image>Component: Image Componentを使用して画像を最適化します。これは自動的に画像を最適化し、layout shiftを防止し、WebPなどの最新フォーマットで提供します。<Script>Component: Script Componentを使用してサードパーティスクリプトを最適化します。これは自動的にスクリプトを遅延させ、メインスレッドのブロッキングを防ぎます。- ESLint: 組み込みの
eslint-plugin-jsx-a11yプラグインを使用してアクセシビリティの問題を早期に検出します。
セキュリティ
- Tainting: データオブジェクトまたは特定の値をtaintして、機密データがクライアント側に露出することを防ぎます。
- Server Actions: ユーザーがServer Actionsを呼び出す権限を持つことを確認します。推奨されるセキュリティプラクティスをレビューしてください。
- Environment Variables:
.env.*ファイルが.gitignoreに追加されており、公開変数のみがNEXT_PUBLIC_でプレフィックスされていることを確認してください。 - Content Security Policy: クロスサイトスクリプティング、クリックジャッキング、その他のコードインジェクション攻撃などの様々なセキュリティ脅威からアプリケーションを保護するためにContent Security Policyの追加を検討してください。
メタデータとSEO
- Metadata API: Metadata APIを使用してページタイトル、説明などを追加し、アプリケーションの検索エンジン最適化(SEO)を向上させます。
- Open Graph (OG) images: ソーシャルシェアのためにアプリケーションを準備するためのOG画像を作成します。
- SitemapsとRobots: サイトマップとrobotファイルを生成してSearchEnginesがページをクロール及びインデックスするのを支援します。
型安全性
- TypeScriptとTS Plugin: TypeScriptとTypeScript pluginを使用して、より良い型安全性を確保し、エラーを早期に検出します。
本番環境への移行前
本番環境への移行前に、next buildを実行してアプリケーションをローカルでビルドしビルドエラーを検出してから、next startを実行して本番環境に近い環境でアプリケーションのパフォーマンスを計測することができます。
Core Web Vitals
- Lighthouse: incognitoモードでLighthouseを実行して、ユーザーがサイトをどのように体験するかをより良く理解し、改善が必要な領域を特定します。これはシミュレーションテストであり、フィールドデータ(Core Web Vitalsなど)を確認することと組み合わせて行うべきです。
useReportWebVitalshook: このhookを使用してCore Web Vitalsデータを分析ツールに送信します。
バンドルの分析
@next/bundle-analyzerプラグインを使用してJavaScriptバンドルのサイズを分析し、アプリケーションのパフォーマンスに影響を与える可能性のある大きなモジュールと依存関係を特定します。
さらに、以下のツールはアプリケーションへの新しい依存関係の追加の影響を理解するのに役立ちます: