開発者向け
事前レンダリング、サーバーレンダリング、またはハイブリッド:どちらを使用する必要がありますか?
By Tom Marshall
ウェブは以前はもっとシンプルな場所でした。サイトを静的HTMLドキュメントとして提供するか、PHPなどの動的サーバーレンダリングテンプレートとして提供しました。では、2021年に最新のWebエクスペリエンスを設計する際に、何が変わり、何を考慮する必要がありますか?
現在、サイトの配信方法を決定する際にナビゲートするためのさまざまなアーキテクチャとアプローチがあります。最新のJamstackフレームワークは、さまざまなレンダリングオプションを利用できるため、この図をさらに複雑にしました。単一のサイト内にある場合もあります。
この記事では、各レンダリング方法がどのように機能するか、長所と短所を探り、最も重要なこととして、どのアプローチが自分とプロジェクトに適しているかを判断する方法について説明します。
まず、最も単純な事前レンダリングされた静的コンテンツ、サーバーレンダリング、2つのハイブリッドアプローチの順で開始し、Next.jsのインクリメンタル静的再生(ISR)を使用した高度なアプローチのボーナスセクションで締めくくります。
事前にレンダリングされた静的コンテンツ
静的生成の背後にある考え方は単純なものです。リクエストごとにページをレンダリングするのではなく、サイトの展開時に、ビルド時にページが事前にレンダリングされます。ビルド中に生成された静的ファイルは、グローバルCDNにプッシュできるため、静的サイトを高速、安価、簡単にホストできます。

他にも利点があります。静的ホスティングを使用すると、バックエンドアプリケーションサーバーの維持と保守に関連するセキュリティ上の懸念を心配する必要はありません。静的サイトは、サイトが依存する外部サービスで停止が発生した場合、ダウンタイムに対して回復力があります。たとえば、サイトの再構築でデータのフェッチ中にエラーが発生したとします。その場合、問題を調査して解決する間、エンドユーザーに影響を与えずに以前のビルドをそのままにして、失敗します。
ただし、事前にレンダリングされた静的サイトにはいくつかの欠点があります。ビルド中にページを事前にレンダリングするのは素晴らしいことですが、そうするために必要な時間は、サイトのページ数に比例します。たとえば、eコマースサイトに5万個の商品があり、各商品ページのレンダリングに250ミリ秒かかる場合、サイトのそのセクションを構築するだけで3時間以上かかります。
サイトがコンテンツの外部ソース(たとえば、Kentico Kontentや製品カタログAPIなどのヘッドレスCMS)に依存しているとします。その場合、その外部コンテンツを変更するたびに、Webhookを介してサイトの再構築をトリガーする必要があり、コンテンツ編集者は更新されたコンテンツがサイトに反映されるまで何時間も待たなければならず、問題がさらに悪化します。
長いビルドはコンテンツ編集者にとって苛立たしいだけでなく、ホスティングプラットフォームによっては、コンテンツの変更ごとにサイト全体を再構築するためにコンピューティングリソースが非効率的に費やされるため、コストの問題も考慮する必要があります。
良い... | あまり良くない... |
|
|
サーバーレンダリング
必要なデータをフェッチし、要求時にサーバー側でそれをレンダリングするという概念は、Webにとって新しいものではありません。 PHP(およびその前身)などの最初の動的Webページ以来、Webサイトを配信するためのこのメカニズムがあります。
強みは変わっていません。デプロイは高速で、コンテンツは常に最新であり、リクエスト時間までレンダリングを延期することで、リクエストのコンテキストに基づいて、応答コンテンツをその場で動的に調整(パーソナライズなど)するのが簡単です。

残念ながら、この柔軟性にはトレードオフが伴います。サーバーレンダリングは、コンテンツが変更されるたびにサイト全体を再構築するという計算の非効率性を回避しますが、計算リソースは、要求ごとにページを再レンダリングするために費やされます。これはエンドユーザーの観点からは遅いだけでなく、サイトの性質によっては非常に非効率的である可能性があります。ページの内容がすべてのユーザーで同じである場合、サーバーは不必要に同じ作業を繰り返し、すべての要求に対して同じ応答を再現します。
これはホスティングコストに影響を与える可能性がありますが、バックエンドにアプリケーションサーバーが必要なため、そもそも(事前にレンダリングされた静的サイトと比較して)ほぼ確実に高くなります。
CDN(またはVarnishなどのリバースキャッシングプロキシ)でキャッシュすることで、その非効率性を軽減し、パフォーマンスを向上させることができますが、これにより、サイトが古いコンテンツを提供することがあるモデルに戻ります。また、サーバーレンダリングモデルを利用してコンテンツをパーソナライズすると、事態はすぐに複雑になります。
良い... | あまり良くない... |
|
|
ハイブリッドアプローチ
大規模なサイトの場合、サイトの特定の領域が事前レンダリングに適していることがよくありますが、他の領域は動的すぎるか、事前レンダリングするにはページが多すぎて実行できません。
幸いなことに、Next.jsのような最新のフレームワークでは、さまざまなサイトセクションの事前レンダリングモデルとサーバーレンダリングモデルを簡単に切り替えることができ、両方の長所を活用できます。
例としてeコマースサイトを使用すると、ホームページとサポートマーケティングページはビルド中に事前にレンダリングされる可能性がありますが、製品ページはサーバーでレンダリングされるため、ビルド時間が短縮され、顧客に常に最新の可用性が表示されます。価格設定。
.png)
Next.jsのようなフレームワークは、利用可能なコンピューティングリソースを利用して、リクエスト時にドラフトコンテンツを使用してページコンテンツを再生成できるため、ハイブリッドアーキテクチャは、事前にレンダリングされた静的ページのインスタントプレビューの機会も提供します。
もちろん、サーバーレンダリングの要素には、バックエンドサーバーの追加の維持管理が必要です。それでも、ホームページなどのトラフィックの多い領域に事前レンダリングを活用することで、このハイブリッドアプローチは、サーバーレンダリングの配信に必要なコンピューティングリソースの量と、それに伴うコストを削減します。
良い... | あまり良くない... |
|
|
ボーナスセクション:インクリメンタル静的再生
現在、すべての最新のフレームワークから利用できるわけではありませんが、 Next.jsが提供する追加のレンダリングアプローチであるインクリメンタルスタティックリジェネレーション(ISR)について説明する価値があります。
Next.jsのISRを使用すると、すべてのページを事前にレンダリングしなくても、ビルドプロセス中にページを事前にレンダリングできます。サイトが公開された後、サイトのこれらの領域内にページを更新したり、追加したりすることもできます。
ISRは、stale-while-revalidate(SWR)キャッシングモデルを利用して、要求が受信されたときに以前にレンダリングされた応答が存在する場合、それが応答で即座に返されるようにします。 Next.jsは、その応答が古くなっているかどうか(指定された期間に基づいて期限切れになっている)を確認し、古くなっている場合は、バックグラウンドでページを再生成して、次のリクエストで更新されたコンテンツが表示されるようにします。

このキャッシュメカニズムは、事前にレンダリングされた静的コンテンツからパフォーマンスと復元力の利点を提供しますが、大量のページがあるサイトの領域のビルド時間が長くなるという欠点はありません。
Next.jsを使用したISRの設定
ISRを推進するために、Next.jsはURLルートごとに3つの決定を行う必要があります。
1.ビルド時に事前レンダリングするページ
Next.jsですべてのページ、ページのサブセットを事前にレンダリングするか、まったくレンダリングしないかを指定できます。ここで考慮すべき主な要因はページの量です。
サービスセクション内に5つのページがある場合、これらすべてを事前にレンダリングすることはおそらく理にかなっています。ただし、50kの製品がある場合は、ビルド時間が遅くなるのを避けるために、事前にレンダリングしないこと、またはサブセット(たとえば、最も人気のある上位50の製品のみ)を事前にレンダリングせず、残りを要求時に生成することをお勧めします。
2.要求されたページがまだレンダリングされていない場合の動作方法
Next.jsには、 `blocking`、` true`、 `false`の3つのフォールバックオプションがあります。
リクエストが届いたときにページがまだレンダリングされていない場合は、次のようにします。
- `blocking`はサーバーレンダリングと同じように動作します。ページは同期的にレンダリングされ、同じ応答で返されます。
- `true`次に、プレースホルダーを使用してページテンプレートの一般的なフォールバックバージョンを提供し、ページのレンダリングが完了したら、ブラウザーのコンテンツ全体でフォールバックバージョンをハイドレイトする前に、バックグラウンドでページを非同期にレンダリングします。
- `false`は404になります。
フォールバックを `true`に設定すると、最初のバイト(TTFB)までの時間が短縮されますが、検索エンジンによってインデックスが作成された公開サイトでは、` blocking`が採用したいアプローチである可能性があります。
3.再生前にレンダリングされた結果をキャッシュする時間
ISRを有効にするには、Next.jsで「再検証」期間を秒単位で設定する必要があります。この期間は1秒ほどで、サーバーレンダリングのようにほぼリアルタイムのデータを提供しますが、事前にレンダリングされたコンテンツのパフォーマンスと復元力が向上します。
または、最新のコンテンツの重要性が低い場合、またはホスティングと外部サービスの両方の負荷を軽減したい場合は、より高く設定できます。
ただし、「再検証」の期間が非常に短い場合でも、再検証期間が終了すると、古いコンテンツが次のユーザーに配信されることを覚えておく必要があります。したがって、最新のコンテンツが最重要であるシナリオ、たとえば、製品ページの例の在庫情報や価格情報では、追加のクライアント側データフェッチを追加しない限り、ISRは適切でない場合があります。
再生メカニズムがWebhookを介して再構築をトリガーする外部データソースの必要性を否定するため、私たちはISRの大ファンであり、ページボリュームが大きくないサイトの領域にも使用しています。
ただし、ここでAPIの使用法を検討することが重要です。再検証期間が短いと、ページが頻繁に再生成され、トラフィックの多いサイトの外部データソースに望ましくない負荷と追加コストがかかる可能性があります。
良い... | あまり良くない... |
|
|
要約すれば…
サイトが小さく、コンテンツが異なるユーザー間で一貫している場合、事前レンダリングにより、ホストが簡単で安価なパフォーマンスと復元力のあるサイトが得られます。
大規模なWebサイトの場合、サイト全体を事前にレンダリングすることは現実的ではありません。ページの量が少ないサイトのセクションでは、ハイブリッドアプローチを採用し、それらを事前にレンダリングする場合があります。ただし、Next.jsのISRを利用して、外部ソースからのWebhookに依存して完全な再構築をトリガーするのではなく、ページが自動的に再生成されるようにする場合は、そうする可能性があります。
ページボリュームが大きいサイトの領域では、ISRを選択します。そのセクション内で最も価値の高いページを事前にレンダリングする場合がありますが、残りのページはリクエスト時にビルドして、ビルド時間を短縮します。
最後に、ユーザーに基づいてページコンテンツをカスタマイズする必要がある場合(A / Bテストや認証済みコンテンツなど)でも、サーバー側のレンダリングに到達します。
私たちは、人を動力源とするテクノロジーエージェンシーであるKyanです。