【Next.js & microCMS】SSGのビルドパフォーマンスチューニング
前提
- Next.jsとmicroCMSを使用し、数百ページのWebサイトを構築している
- App Routerは使用していない(Next.jsの採用時にApp Routerがまだ正式採用されていなかったため)
- ISRも使用していない(業務要件の兼ね合いから使っていない)
- Amplify上で、SSGして静的サイトを構築している
課題
- ページ数が増えることで、ビルドのパフォーマンスが気になってきた
- 当初から想定していたが、想定よりも遅いことが気になってきた
microCMSの簡単なデータ構造
- microCMSでは下図にある通り、各ページからヘッダーとフッターのデータを参照している。また、ヘッダーとフッターからは、グローバルナビゲーションやフッターメニューで表示する、各ページのデータを参照している。

アプローチ
- ページ生成時のmicroCMS API通信処理の回数を減らす、もしくは、通信データサイズを減らすことを検討。
- 基本的には、Webページに合わせてデータ登録しているので、通信回数を減らすことは難しそう。
- 通信データサイズを減らすための工夫を検討。
各ページの getStaticProps からmicroCMS APIを呼び出しているレスポンス内容を解析すると、想定しているよりもデータサイズが大きいことが分かりました。これは、ヘッダーとフッターで設定しているページ内容を取得するために、microCMS APIのdepthパラメータに 2 を設定しているからでした。
depthは、API単位で設定するもので、各階層に対して個別設定はできないので、depthの値を 1 に変更し、ヘッダーとフッターのデータは個別に取得するように変更しました。また、ヘッダーとフッターの値は、各ページで同じものを使用することが多いため、キャッシュできるような仕組みを用意しています。
具体的には、以下のような共通関数を1つ作成し、一度取得したヘッダーまたはフッターであれば、通信処理を介さずにデータを返すようにしています。
import client from '@/lib/client';
import { FooterData } from '@/types/footerData';
import { HeaderPcData, HeaderSpData } from '@/types/headerData';
const globalCache: Record<string, HeaderPcData | HeaderSpData | FooterData> =
{};
const getHeaderFooterCachedData = async (
endpoint: string,
contentId: string,
): Promise<HeaderPcData | HeaderSpData | FooterData> => {
const key = `${endpoint}-${contentId}`;
if (globalCache[key]) {
// console.log('cache hit');
return globalCache[key];
}
const data = await client.get<HeaderPcData | HeaderSpData | FooterData>({
endpoint,
contentId,
});
globalCache[key] = data;
return data;
};
export default getHeaderFooterCachedData;
まとめ
元々8分くらい掛かっていたビルド処理から30秒くらいの削減が見込まれることを確認できました。今回は一例ですが、Webサイト全体で扱う共通コンポーネントがあれば、同様のアプローチでキャッシュ化することも検討できるので、地道に積み重ねていくともう少し改善できそうです!