レンダリング方式ごとの組み込み方法
Webアプリ/Webサイトは、そのHTMLのレンダリング方式としていくつかの種類があります。
特にNext.jsのようなモダンなWebアプリケーションフレームワークでは、ページごとにレンダリング方式を制御することも可能です。
こうした、Webフロントエンド開発を取り巻く環境下では、それぞれのレンダリング方式のメリット/デメリットを理解し、ページの性質に合った方式を選択することが重要となります。
このページでは、各レンダリング方式の概要とメリット/デメリット、加えてmicroCMSを利用する場合の組み込み方法について解説します。
- Information
サンプルコードはNext.js(Pages Router)での実装例となります。
レンダリング方式の一覧
CSR(Client Side Rendering/クライアントサイドレンダリング)
CSRはJavaScriptを使用してWebページを動的に生成する方法です。
CSRでは、まずサーバから空のHTMLファイル、CSS、JavaScriptを取得します。その後、APIサーバ(もしくはmicroCMSのようなヘッドレスCMSなど)から初期データを取得し、HTMLをレンダリングします。
メリット
- ユーザーのUI操作に応じて、リアルタイムでデータを更新できる
- 静的HTMLとして運用しているサイトに対して組み込みやすい
- すでに構築済みのアプリケーションの中に部分的に組み込みやすい
デメリット
- 静的ファイルの読み込み後にデータを取得しに行くので、初期表示は早いものの、データの表示が遅くなる場合がある
- SEOに悪影響を及ぼす場合がある(検索エンジンのクローラーが、コンテンツを正確に認識できない可能性がある)
- OGPを正確に表示するのが難しい場合がある
- ブラウザでJavaScriptを無効にしているユーザーには正常に表示されない場合がある
- APIキーが秘匿できない(ただし、サーバサイド経由でアクセスすることで回避できる場合もある)
CSRが向いているケース
- リッチなUI操作やアニメーションが多いWebアプリケーション
- SEOに重要でないコンテンツや、ログインが必要なプライベートなコンテンツを提供するアプリケーション
実装例
import { useEffect, useState } from 'react';
import { createClient } from 'microcms-js-sdk';
const client = createClient({
serviceDomain: 'YOUR_DOMAIN',
apiKey: 'YOUR_API_KEY',
});
const Announcements = () => {
const [announcements, setAnnouncements] = useState([]);
useEffect(() => {
const getAnnouncements = async () => {
const data = await client.get({ endpoint: 'announcements' });
setAnnouncements(data.contents);
};
getAnnouncements();
}, []);
return (
<div>
{announcements.map((announcement) => (
<div key={announcement.id}>
<h2>{announcement.title}</h2>
<p>{announcement.content}</p>
</div>
))}
</div>
);
};
export default Announcements;
SSR(Server Side Rendering/サーバサイドレンダリング)
SSRは、サーバ側でHTMLを生成する方法です。
クライアントからのリクエストを受けたサーバが、APIのリクエストなどを通じて必要なコンテンツを取得した後にHTMLを生成し、クライアントに返却します。
クライアントは、レンダリング済みのHTMLを受け取り、CSSやJavaScriptの読み込みを行い、ページを表示します。
クライアント側ではなくサーバ側でHTMLを生成する点で、CSRとは対照的な方式です。
メリット
- リクエストごとにHTMLを生成するため、ページごとの動的な要素に対応できる
- サーバでHTMLを生成してクライアントに送信するため、動的なデータ表示のラグがない
- サーバサイドでHTMLが完全に生成されるため、クローラーがコンテンツを簡単に把握でき、SEOに有効
- サーバで処理が行われるため、クライアント側の負荷が軽減され、低スペックなデバイスやインターネットの回線速度が低い場合でもパフォーマンスが維持できる
デメリット
- リクエストごとにHTMLを生成する必要があるため、サーバ側の負荷が高くなり、大量のアクセスがある場合はサーバのスケーリングが必要になることがある
SSRが向いているケース
- 動的な要素があり、かつSEOの最適化が必要なウェブサイト
実装例
import { createClient } from 'microcms-js-sdk';
const client = createClient({
serviceDomain: 'YOUR_DOMAIN',
apiKey: 'YOUR_API_KEY',
});
export const getServerSideProps = async () => {
const data = await client.get({ endpoint: 'announcements' });
return {
props: {
announcements: data.contents,
},
};
};
const Announcements = ({ announcements }) => {
return (
<div>
{announcements.map((announcement) => (
<div key={announcement.id}>
<h2>{announcement.title}</h2>
<p>{announcement.content}</p>
</div>
))}
</div>
);
};
export default Announcements;
SSG(Static Site Generation/スタティックサイトジェネレーション)
SSGは、事前に静的なHTMLを生成する方法です。
SSGではコンテンツやテンプレートが更新された際に、ビルドプロセスを実行してすべてのページを事前に生成しておきます。それらの静的ファイルをホスティングサーバにデプロイし、クライアントのリクエストに対してレスポンスします。
SSGの特性を活かすため、CDNに配置し配信することが一般的となっています。
メリット
- 静的ファイルを使用するため、サーバからクライアントへの応答速度が速く、ウェブサイトのパフォーマンスが向上する
- 静的ファイルを生成するだけでデプロイできるため、デプロイが簡単で、サーバに対する要求も低くなる
デメリット
- サイトのページ数が多い場合、すべてのページを生成するためにビルド時間が長くなることがある
- コンテンツの更新にはビルドプロセスが必要なため、リアルタイムなデータ更新が難しい(ただし、一部のデータはクライアントサイドで動的に取得することで対処できる)
- 静的ファイルを使用しているため、ユーザー認証や動的な機能の実装が制限される(ただし、JavaScriptやAPIを利用してクライアントサイドで動的機能を実現することができる)
SSGが向いているケース
- 静的なコンテンツが多く、リアルタイムな更新が不要なウェブサイト(コーポレートサイトやブログなど)
実装例
import { createClient } from 'microcms-js-sdk';
const client = createClient({
serviceDomain: 'YOUR_DOMAIN',
apiKey: 'YOUR_API_KEY',
});
export const getStaticProps = async () => {
const data = await client.get({ endpoint: 'announcements' });
return {
props: {
announcements: data.contents,
},
};
};
const Announcements = ({ announcements }) => {
return (
<div>
{announcements.map((announcement) => (
<div key={announcement.id}>
<h2>{announcement.title}</h2>
<p>{announcement.content}</p>
</div>
))}
</div>
);
};
export default Announcements;
ISR(Incremental Static Regeneration/インクリメンタルスタティックリジェネレーション)
ISRは、SSGとSSRの特徴を組み合わせたハイブリッドなレンダリング方式です。
ISRではSSGのようにサイト全体を事前に構築するのではなく、必要なページを必要なタイミングで生成します。生成されたページはキャッシュされ、以降のリクエストでは静的なコンテンツとして提供されます。
また、キャッシュには有効期限を指定でき、有効期限が過ぎた後にアクセスがあると、改めてページの再生成を行います。この機構によってある程度鮮度の高いコンテンツを提供できます。
なお現在ISRは、Next.jsなどの一部のフレームワークでサポートされています。
メリット
- 生成されたページはキャッシュされるため、次回以降のアクセス時に高速で提供できる
- 全てのページをコンテンツ公開時に生成する必要がなく、ビルド時間が大幅に短縮できる
- 指定された更新間隔でページが再生成されるため、頻繁に更新されるコンテンツにも対応できる
デメリット
- 初回アクセス時にページがオンデマンドで生成されるため、その際の表示速度が遅くなる可能性がある
- 指定された更新間隔でのみページが再生成されるため、リアルタイム性が必要な場合には制限がある
- 利用できるフレームワークとインフラが限られる
ISRが向いているケース
- 全ページのビルドに多量な時間がかかる大規模なWebサイト
- 頻繁に更新されるコンテンツがあるWebサイト
実装例
import { createClient } from 'microcms-js-sdk';
const client = createClient({
serviceDomain: 'YOUR_DOMAIN',
apiKey: 'YOUR_API_KEY',
});
export const getStaticPaths = async () => {
const data = await client.get({ endpoint: 'announcements' });
const paths = data.contents.map((announcement) => ({
params: { id: announcement.id.toString() },
}));
return {
paths,
fallback: true,
};
};
export const getStaticProps = async ({ params }) => {
const data = await client.get({ endpoint: `announcements/${params.id}` });
return {
props: {
announcement: data,
},
revalidate: 10,
};
};
const Announcement = ({ announcement }) => {
return (
<div>
<h2>{announcement.title}</h2>
<p>{announcement.content}</p>
</div>
);
};
export default Announcement;