はじめに
ヘッドレスE-commerceでは、パフォーマンスとSEO(検索エンジン最適化)がユーザー体験(UX)とコンバージョン率を大きく左右します。高速なページ読み込みと検索エンジンでの高い可視性は、競争力のあるオンラインストアに不可欠です。この第5部では、Next.jsのServer-Side Rendering (SSR)、Incremental Static Regeneration (ISR)、およびVercel Edge Networkを活用してパフォーマンスを最適化し、Shopify Storefront APIのメタデータを用いてSEOを強化する方法を解説します。開発者向けに、Lighthouseスコアの改善、画像最適化、および構造化データの実装に焦点を当てたコードスニペットを提供します。
パフォーマンス最適化の重要性
E-commerceのパフォーマンスは以下の理由で重要です:
- ユーザー体験: ページ読み込み時間が1秒増加するごとに、コンバージョン率が最大7%低下(Google研究)。
- SEO: GoogleはCore Web Vitals(LCP、FID、CLS)をランキング要因に使用。
- スケーラビリティ: 高トラフィック時の安定性を確保。
- コスト効率: サーバーリソースの最適化で運用コストを削減。
Next.jsとVercelは、パフォーマンス向上のための強力なツールを提供します。
パフォーマンス最適化の実装
1. Next.jsのレンダリング戦略
Next.jsのISRとSSRを活用して、ページ読み込みを高速化します。
ISRの最適化
**Incremental Static Regeneration(ISR)**は、静的ページを生成しつつ、定期的に更新します。第3部で実装した商品ページをさらに最適化:
// pages/products/[handle].tsx (抜粋)
export const getStaticProps: GetStaticProps = async ({ params }) => {
const { data } = await client.query({
query: GET_PRODUCT,
variables: { handle: params?.handle },
});
return {
props: { product: data.product },
revalidate: 60, // 60秒ごとに再生成
};
};
ISRの再生成間隔をトラフィックとデータ更新頻度に応じて調整(例:低トラフィックなら300秒)。以下はキャッシュ戦略の強化:
// next.config.js
module.exports = {
async headers() {
return [
{
source: '/products/:handle',
headers: [
{
key: 'Cache-Control',
value: 'public, max-age=60, stale-while-revalidate=300',
},
],
},
];
},
};
この設定は、Vercel Edge Networkでキャッシュを活用し、stale-while-revalidateで古いコンテンツを再生成中に提供します。
SSRの使用
動的データ(例:リアルタイム在庫)が必要な場合、SSRを適用:
// pages/inventory/[id].tsx
import { GetServerSideProps } from 'next';
import { gql } from '@apollo/client';
import { client } from '../../lib/apollo-client';
const GET_INVENTORY = gql`
query GetInventory($id: ID!) {
product(id: $id) {
id
variants(first: 10) {
edges {
node {
id
inventoryQuantity
}
}
}
}
}
`;
export const getServerSideProps: GetServerSideProps = async ({ params }) => {
const { data } = await client.query({
query: GET_INVENTORY,
variables: { id: params?.id },
});
return {
props: { product: data.product },
};
};
export default function InventoryPage({ product }: { product: any }) {
return (
<div className="container mx-auto p-4">
<h1 className="text-3xl font-bold mb-6">在庫状況</h1>
{product.variants.edges.map(({ node }: { node: any }) => (
<p key={node.id}>バリエーションID: {node.id} - 在庫: {node.inventoryQuantity}</p>
))}
</div>
);
}
SSRはリアルタイム性が求められるページに適していますが、サーバーリソースを考慮して使用します。
2. 画像最適化
Next.js Imageで画像を自動圧縮し、WebP形式を優先:
// components/ProductCard.tsx (抜粋)
import Image from 'next/image';
<Image
src={product.images.edges[0]?.node.src}
alt={product.images.edges[0]?.node.altText || product.title}
fill
className="object-cover rounded"
sizes="(max-width: 768px) 100vw, 33vw"
quality={75} // 品質を調整(デフォルト: 75)
priority={index === 0} // 最初の画像は優先ロード
/>
Vercel Image Optimizationを有効化(next.config.js
):
module.exports = {
images: {
domains: ['cdn.shopify.com'],
formats: ['image/webp'],
minimumCacheTTL: 3600, // キャッシュ期間1時間
},
};
これにより、画像の読み込み時間が短縮され、**Largest Contentful Paint(LCP)**が改善されます。
3. コード分割と遅延読み込み
Next.jsのdynamic importでコンポーネントを遅延読み込み:
// pages/index.tsx (抜粋)
import dynamic from 'next/dynamic';
const ProductList = dynamic(() => import('../components/ProductList'), {
ssr: false, // クライアントサイドでのみレンダリング
loading: () => <p>Loading...</p>,
});
これにより、初回ロード時のJavaScriptバンドルサイズを削減します。
SEO最適化
SEOはトラフィックとコンバージョンを増やすために不可欠です。Shopify Storefront APIのメタデータを利用してSEOを強化します。
1. メタタグの動的設定
商品ページでメタタグとOpen Graphデータを設定:
// pages/products/[handle].tsx (抜粋)
import Head from 'next/head';
export default function ProductPage({ product }: { product: any }) {
const description = product.description.slice(0, 160);
const image = product.images.edges[0]?.node.src;
return (
<>
<Head>
<title>{`${product.title} | YourStore`}</title>
<meta name="description" content={description} />
<meta name="keywords" content={`${product.title}, e-commerce, shopify`} />
<meta property="og:title" content={product.title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={image} />
<meta property="og:type" content="product" />
<link rel="canonical" href={`https://my-ecommerce.vercel.app/products/${product.handle}`} />
</Head>
{/* 残りのコード */}
</>
);
}
2. 構造化データの追加
JSON-LDで商品データを構造化し、Googleのリッチリザルトをサポート:
// pages/products/[handle].tsx (抜粋)
<Head>
<script type="application/ld+json">
{JSON.stringify({
"@context": "https://schema.org",
"@type": "Product",
name: product.title,
image: product.images.edges[0]?.node.src,
description: product.description.slice(0, 160),
offers: {
"@type": "Offer",
priceCurrency: product.priceRange.minVariantPrice.currencyCode,
price: product.priceRange.minVariantPrice.amount,
availability: "https://schema.org/InStock",
},
})}
</script>
</Head>
3. サイトマップの生成
動的サイトマップを生成して、検索エンジンにページを通知:
// pages/sitemap.xml.tsx
import { GetServerSideProps } from 'next';
import { gql } from '@apollo/client';
import { client } from '../lib/apollo-client';
const GET_ALL_PRODUCTS_AND_COLLECTIONS = gql`
query GetAllProductsAndCollections {
products(first: 100) { edges { node { handle } } }
collections(first: 100) { edges { node { handle } } }
}
`;
export const getServerSideProps: GetServerSideProps = async ({ res }) => {
const { data } = await client.query({ query: GET_ALL_PRODUCTS_AND_COLLECTIONS });
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url><loc>https://my-ecommerce.vercel.app/</loc></url>
${data.products.edges
.map(({ node }: { node: any }) => `<url><loc>https://my-ecommerce.vercel.app/products/${node.handle}</loc></url>`)
.join('')}
${data.collections.edges
.map(({ node }: { node: any }) => `<url><loc>https://my-ecommerce.vercel.app/collections/${node.handle}</loc></url>`)
.join('')}
</urlset>`;
res.setHeader('Content-Type', 'text/xml');
res.write(sitemap);
res.end();
return { props: {} };
};
export default function Sitemap() {
return null;
}
Google Search Consoleでサイトマップを送信:
# Search Consoleでのサイトマップ送信
1. Google Search Consoleにアクセス
2. プロパティを追加(https://my-ecommerce.vercel.app)
3. サイトマップ(/sitemap.xml)を送信
Vercel Edge Networkの活用
VercelのEdge Networkを活用して、グローバルなパフォーマンスを向上:
# Vercelでのキャッシュ設定
1. Vercelダッシュボードにログイン
2. 「Project Settings」→「Edge Config」を有効化
3. キャッシュポリシーを設定:
- Cache-Control: public, max-age=60, stale-while-revalidate=300
4. グローバルCDNを活用(自動有効)
パフォーマンステストとデバッグ
以下のテストを実施:
- Lighthouseテスト: スコア90以上を目指す(Performance, SEO, Accessibility)。
- Core Web Vitals: LCP(2.5秒以下)、FID(100ms以下)、CLS(0.1以下)。
- キャッシュテスト: ページが正しくキャッシュされるか。
- SEOテスト: Google Search Consoleでインデックス状況を確認。
Lighthouse CLIの実行:
npm install -g lighthouse
lighthouse https://my-ecommerce.vercel.app --output html --output-path report.html
まとめ
この第5部では、Next.jsとVercelを使ったパフォーマンスとSEOの最適化を解説しました。ISR、画像最適化、構造化データ、およびEdgeキャッシュにより、高速で検索エンジンに最適化されたE-commerceを構築しました。次の第6部では、セキュリティとデータ管理について掘り下げます。
Qiitaの皆さん、この記事が役に立ったら「いいね」や「ストック」をお願いします!コメントで技術的な質問や提案もお待ちしています!