フロントエンドのデプロイ方法:静的ファイルか、稼働するサーバーか

フロントエンドアプリケーションの構築を始めるとき、フレームワークの選択以上にデプロイパイプライン全体を左右する質問があります。それは、「このアプリケーションは常時稼働するサーバーを必要とするのか、それとも単なるファイルのフォルダとして存在できるのか」というものです。

これは理論的なアーキテクチャの議論ではありません。ビルド方法、デプロイ先、起こりうる問題、そしてその修正方法を決定する実践的な判断です。

静的フロントエンド:ファイルが語る

企業のプロフィールページ、ドキュメントサイト、マーケティング用ランディングページを構築する場合を想像してください。HTMLを書き、CSSを追加し、画像をいくつか配置して、どこかにアップロードします。ブラウザがそれらのファイルをダウンロードしてレンダリングします。それで完了です。

これが静的フロントエンドです。ブラウザが必要とするものはすべてビルド時に準備されています。HTML、CSS、JavaScript、フォント、画像 — これらはすべて、基本的なWebサーバー、CDN、またはS3バケットに配置できるファイルになります。デプロイ後にサーバープロセスが実行されることはありません。ランタイムの起動を待つ必要もありません。ファイルはただそこにあり、配信されるのを待っています。

しかし、静的であることは単純であることを意味しません。APIからデータを取得するReactやVueのアプリケーションも、静的ファイルとしてビルドできます。違いは、ブラウザがJavaScriptを実行してAPI呼び出しを行うまでデータが表示されないことです。これはクライアントサイドレンダリングと呼ばれます。初期のHTMLはシェルであり、実際のコンテンツはページの読み込み後に埋め込まれます。

静的フロントエンドのパイプラインは単純です:

  1. ビルドコマンドを実行する。
  2. 出力ファイルを収集する。
  3. ストレージまたはCDNにアップロードする。

サーバーの再起動は不要。ヘルスチェックも不要。プロセスが準備できるのを待つ必要もありません。デプロイは、バケット内のファイルを置き換えるか、CDNのポインタを更新するだけで完了します。問題が発生した場合は、以前のファイルに戻すだけです。高速で、低コストで、壊れにくい方法です。

SSRフロントエンド:リクエストに応じて調理されるページ

次に、リアルタイムの価格、在庫状況、パーソナライズされたレコメンデーションを表示するEコマースサイトを考えてみましょう。これを静的ファイルとしてビルドすると、ブラウザがJavaScriptを実行して最新情報を取得するまで、ユーザーには古いデータが表示されます。この遅延は売上を損ない、顧客を混乱させ、アプリケーションを遅く感じさせます。

ここでサーバーサイドレンダリング(SSR)が登場します。ユーザーがページをリクエストすると、サーバーが最新のデータを取得し、HTMLをレンダリングし、完全に形成されたページをブラウザに送信します。ユーザーはJavaScriptの読み込みと実行を待つことなく、すぐにコンテンツを表示できます。

SSRは、フロントエンドが単なるファイルではなくなることを意味します。サーバー、依存関係、環境変数、適切な起動シーケンスを必要とする実行中のアプリケーションです。パイプラインはバックエンドのデプロイに近づきます:

  1. アプリケーションをサーバー対応のコードにビルドする。
  2. ランタイムの依存関係をインストールする。
  3. ターゲット環境の環境変数を設定する。
  4. サーバープロセスを起動するか、コンテナにデプロイする。
  5. サーバーがリクエストを受け付けていることを確認するためにヘルスチェックを実行する。
  6. 新しいバージョンにトラフィックをルーティングする。
  7. 切り替え後のエラーを監視する。

問題が発生した場合、ロールバックはファイルの交換ではなく、サーバーバージョンの復元を意味します。データベース接続、セッション状態、キャッシュの無効化を処理する必要があります。複雑にはなりますが、ユーザーがページを読み込むたびに最新のデータを必要とする場合には不可欠です。

中間の選択肢:静的サイト生成

静的サイト生成(SSG)と呼ばれるハイブリッドなアプローチがあります。ビルド時にはSSRのように見えますが、ランタイムでは静的サイトのように動作します。レンダリングはリクエストごとではなく、ビルド時に一度だけ行われます。結果として、静的に配信できる事前レンダリングされたHTMLファイルのセットが生成されます。

SSGは、毎秒変化しないコンテンツに適しています。ブログ記事、ドキュメントページ、CMSから取得した商品ページなどは、ビルド時にレンダリングして静的ファイルとして配信できます。ユーザーは高速なページ読み込みを体験でき、サーバーランタイムを管理する必要もありません。

しかし、SSGにはトレードオフがあります。コンテンツが頻繁に変更される場合、サイト全体を再ビルドして再デプロイする必要があります。週に1回新しい投稿があるブログでは問題ありませんが、毎分在庫が更新されるEコマースサイトでは、SSGは非現実的になります。

これがパイプラインに与える影響

静的、SSR、SSGの選択は、単なるアーキテクチャの問題ではありません。コンテンツがどのくらいの頻度で変更されるか、ユーザーが更新をどのくらい迅速に確認する必要があるか、チームが処理できる運用オーバーヘッドの量によって決まります。

以下は、考え方を整理するためのクイックガイドです:

以下の図は、判断の流れと各パスに対応するパイプラインを示しています。

flowchart TD A[アプリケーションはサーバーを必要とするか?] -->|いいえ| B[静的フロントエンド] A -->|はい| C[コンテンツは常に変化するか?] C -->|いいえ| D[SSG - 静的サイト生成] C -->|はい| E[SSR - サーバーサイドレンダリング] B --> F[静的ファイルをビルド] F --> G[CDN / S3にアップロード] G --> H[ファイルを配信] D --> I[ビルド&HTMLを事前レンダリング] I --> J[静的出力をアップロード] J --> K[静的ファイルとして配信] E --> L[サーバーコードをビルド] L --> M[ランタイム依存関係をインストール] M --> N[サーバープロセスを起動] N --> O[ヘルスチェック&トラフィックルーティング]
  • 静的:コンテンツがほとんど変更されない。ユーザーはデータが表示されるまでのわずかな遅延を許容できる。可能な限りシンプルなデプロイを望む場合。
  • SSR:コンテンツが常に変化する。ユーザーはページを読み込むたびに最新のデータを必要とする。サーバーランタイムを管理する意思がある場合。
  • SSG:コンテンツが定期的に変更される。サーバーを実行せずに高速なページ読み込みを望む。コンテンツが更新されたときにサイトを再ビルドできる場合。

パイプラインはこの判断に従うべきであり、それに逆らうべきではありません。静的を選択した場合は、不要なサーバー管理を追加しないでください。SSRを選択した場合は、それが単なるファイルのフォルダであるかのように扱ってはいけません。

決定前の実践的なチェックリスト

デプロイ戦略を決定する前に、以下の質問に答えてください:

  • このページのコンテンツはどのくらいの頻度で変更されますか?毎秒、毎時間、それとも毎週?
  • ユーザーはページ読み込み後にJavaScriptがデータを取得するのを待てますか、それともコンテンツをすぐに必要としますか?
  • チームには、監視、再起動、ロールバックを含むサーバーランタイムを管理する能力がありますか?
  • 問題のあるデプロイからどのくらい迅速に復旧する必要がありますか?ファイルの交換はサーバーの再起動よりも高速です。
  • 同じページが、ユーザーのセッションや場所に基づいて異なる表示になりますか?

これらの答えが、適切なアプローチを示してくれます。フレームワークや流行に判断を委ねないでください。

具体的な結論

静的フロントエンドはファイルのフォルダです。SSRフロントエンドは実行中のアプリケーションです。パイプラインでこれらを異なるものとして扱うことで、不必要な複雑さを避け、重要なステップを見逃すことを防げます。ユーザーの最新コンテンツへのニーズを満たす最もシンプルなアプローチから始め、データがそれを要求する場合にのみサーバーサイドレンダリングを追加してください。