Next.js × microCMSで作ったブログのパフォーマンス改善
はじめに
Next.js と microCMS を使ってブログアプリを作成したのですが、Lighthouseスコアが伸びず、UXにも課題 がありました。パフォーマンス改善をしてみました。Xとか技術記事を書いても、「オセぇ」とはならないはず!!
この記事ではその具体的な施策と学びについてまとめます。
↓ブログ
next/image
に priority={true}
を追加
✅ Next.jsの<Image />
コンポーネントでファーストビューに表示される画像に priority={true}
を指定することで、優先的に読み込んでくれるとのこと。
<Image src="/main.jpg" width={1200} height={630} priority />
✅ microCMSの画像を軽量化
microCMSを見てみると、アイキャッチ画像を圧縮せずにアップロードしていたので、以下のサイトで画像を圧縮&リサイズしました。
✅ スケルトンUIの導入
ローディング時にスケルトンを表示するようにしました。以前は画面に大きく Loading...となっていたのですが、見栄えがよくなかったので改善しました。ちなみに調べるとUX的にも良きみたいです!!
スケルトンはShadcnから拝借しました。
今回導入したArticleListSkelton(V0産)
const ArticleListItemSkeleton = () => {
return (
<div className="bg-white rounded-lg shadow-lg overflow-hidden w-full max-w-sm">
<div className="relative h-48 w-full">
<Skeleton className="h-full w-full" />
</div>
<div className="p-4">
<Skeleton className="h-6 w-3/4 mb-2" />
<Skeleton className="h-4 w-1/2" />
</div>
<div className="flex items-center space-x-2 px-2 py-1 pb-4">
<Skeleton className="h-4 w-4" />
<Skeleton className="h-4 w-16" />
</div>
</div>
);
};
const ArticleListSkeleton = () => {
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-5 gap-6 p-4">
{Array.from({ length: 6 }).map((_, index) => (
<ArticleListItemSkeleton key={index} />
))}
</div>
);
};
export default ArticleListSkeleton;
✅ SWRでデータ取得 + キャッシュ
fetch
から SWR
に切り替えることで、キャッシュ戦略と再取得の制御が可能になりました。
const { data, error , isLoading } = useSWR("/api", fetcher ,{
refreshInterval: 30000, // 30秒ごとに自動で再フェッチ
dedupingInterval: 60000 // 1分以内の同一リクエストはまとめて1回に
});
ただこれはrefreshIntervalの効果をdedupingInterbalが打ち消してあるので、修正が必要です。
✅ リストとリストアイテムの責務分離
コンポーネントを以下のように分離しました:
- PostList.tsx(一覧全体の描画)
- PostItem.tsx(個別アイテムの描画)
これによりコードの責務が明確になり、再レンダリング最小化・保守性向上にも繋がりました。
✅ API Routes にキャッシュ制御を追加
Next.jsのAPIルートに Cache-Control ヘッダーを追加し、CDNレベルでのキャッシュ戦略を設定しました。
res.setHeader(
"Cache-Control",
"s-maxage=300, stale-while-revalidate=60"
);
これにより、APIレスポンスも速くなり、全体のUXとスコアが改善されました!!
まとめ
かなり体感速度早くできました!!
まだまだ遅い部分はありますがとりあえず、Speed Insightでは高い数値ができたので、一旦終了!!
Discussion