目標
- Next.jsでパフォーマンスを向上させる方法を学ぶ。
-
next/image
で画像を最適化する。 - SEOを強化するためにメタデータを追加する。
- Incremental Static Regeneration (ISR)で効率的な更新を実現する。
1. 画像の最適化
ウェブサイトの読み込み速度を向上させるため、next/image
を使って画像を最適化します。
手順:
-
public/
にサンプル画像(例:sample.jpg
)を追加。 -
app/page.tsx
を編集して画像を表示:import { supabase } from '../lib/supabase'; import Image from 'next/image'; export default async function Home() { const { data: posts } = await supabase .from('posts') .select('*') .order('created_at', { ascending: false }); return ( <div className="min-h-screen flex flex-col items-center bg-gray-100 py-8"> <h1 className="text-4xl font-bold text-blue-600 mb-8">データベースからの投稿</h1> <Image src="/sample.jpg" alt="サンプル画像" width={600} height={400} className="mb-8 rounded" /> <ul className="space-y-4 max-w-2xl w-full"> {posts?.map((post) => ( <li key={post.id} className="bg-white p-4 rounded shadow"> <a href={`/posts/${post.id}`} className="text-xl font-semibold text-blue-500 hover:underline"> {post.title} </a> <p className="text-gray-600">{post.content}</p> </li> ))} </ul> </div> ); }
ポイント:
-
next/image
は自動で画像を圧縮し、遅延読み込み(lazy loading)を適用。 -
width
とheight
を指定してレイアウトシフトを防ぐ。
2. メタデータでSEOを強化
検索エンジンに最適化されたメタデータを追加します。
app/layout.tsx
の更新:
import './globals.css';
import Link from 'next/link';
import { auth } from 'next-auth';
import { signIn, signOut } from 'next-auth/react';
export const metadata = {
title: 'Next.js 2025ブログ',
description: '2025年の最新技術で作られたブログサイト',
openGraph: {
title: 'Next.js 2025ブログ',
description: 'Next.jsとSupabaseで構築されたモダンなブログ',
url: 'https://your-site.com',
images: ['/sample.jpg'],
},
};
export default async function RootLayout({ children }) {
const session = await auth();
return (
<html lang="ja">
<body className="font-sans antialiased">
<header className="bg-blue-800 text-white p-4">
<nav className="max-w-4xl mx-auto flex justify-between items-center">
<Link href="/" className="text-xl font-bold">ホーム</Link>
<div className="space-x-4">
<Link href="/about" className="hover:underline">About</Link>
<Link href="/add-post" className="hover:underline">投稿追加</Link>
{session ? (
<>
<span>{session.user?.name}</span>
<button onClick={() => signOut()} className="hover:underline">ログアウト</button>
</>
) : (
<button onClick={() => signIn('google')} className="hover:underline">Googleでログイン</button>
)}
</div>
</nav>
</header>
<main>{children}</main>
<footer className="bg-gray-200 p-4 text-center text-gray-600">
© 2025 Next.js学習シリーズ
</footer>
</body>
</html>
);
}
ポイント:
-
openGraph
でSNS共有時の表示を最適化。 - 個別ページでは
generateMetadata
を使って動的にメタデータを設定可能。
3. ISR(Incremental Static Regeneration)の利用
ISRを使えば、静的ページを定期的に更新できます。
app/page.tsx
の更新:
import { supabase } from '../lib/supabase';
import Image from 'next/image';
export const revalidate = 60; // 60秒ごとに再生成
export default async function Home() {
const { data: posts } = await supabase
.from('posts')
.select('*')
.order('created_at', { ascending: false });
return (
<div className="min-h-screen flex flex-col items-center bg-gray-100 py-8">
<h1 className="text-4xl font-bold text-blue-600 mb-8">データベースからの投稿</h1>
<Image
src="/sample.jpg"
alt="サンプル画像"
width={600}
height={400}
className="mb-8 rounded"
/>
<ul className="space-y-4 max-w-2xl w-full">
{posts?.map((post) => (
<li key={post.id} className="bg-white p-4 rounded shadow">
<a href={`/posts/${post.id}`} className="text-xl font-semibold text-blue-500 hover:underline">
{post.title}
</a>
<p className="text-gray-600">{post.content}</p>
</li>
))}
</ul>
</div>
);
}
ポイント:
-
revalidate
で指定した秒数ごとにページが再生成。 - 静的生成の速度と動的更新の柔軟性を両立。
4. パフォーマンスの確認
GoogleのLighthouseを使ってパフォーマンスを測定します。
手順:
- Chrome DevToolsを開き、「Lighthouse」タブを選択。
-
http://localhost:3000
でテストを実行。 - スコアを確認し、改善点を検討(例:画像サイズの削減、CSSの最適化)。
実践:最適化されたブログ
-
画像:
next/image
で最適化されたサンプル画像を追加。 - SEO: メタデータで検索エンジンとSNSに対応。
- ISR: 投稿リストを60秒ごとに更新。
確認:
- Lighthouseスコアが80以上になるように調整。
エピソード8の終了
- パフォーマンスとSEOを最適化しました。
- ウェブサイトがより高速で検索エンジンに優しくなりました。
次回のエピソード:Vercelにデプロイし、実際に公開します。
この記事が役に立ったと思ったら、ぜひ「いいね」を押して、ストックしていただければ嬉しいです!次回のエピソードもお楽しみに!