N.N. LLC. ロゴ - 千葉県船橋市のIT企業N.N. LLC.
技術ブログ

Vercelで実現する高速デプロイとエッジ配信 — 日本向けWebサイトの最適解

17分で読めます
Vercelで実現する高速デプロイとエッジ配信 — 日本向けWebサイトの最適解

Vercelプラットフォームの全体像

Vercelは、Next.jsの開発元であるVercel Inc.が提供するクラウドプラットフォームです。単なるホスティングサービスではなく、Edge Network、Serverless Functions、Build Pipelineを統合したフロントエンド開発のためのプラットフォームとして進化を続けています。

N.N. LLC.のコーポレートサイト(n-n.tokyo)もVercelでホスティングしており、日本国内のユーザーに対して安定した高速配信を実現しています。本記事では、Vercelの各機能を実践的に解説します。

Vercel Edge Network — 東京リージョン(hnd1)の活用

Vercelは世界中に分散されたEdge Networkを持ち、日本では東京リージョン(hnd1)が利用可能です。Edge Networkの仕組みを理解することで、パフォーマンス最適化の方針が明確になります。

静的アセットの配信

HTML、CSS、JavaScript、画像などの静的アセットは、ユーザーに最も近いEdgeロケーションからキャッシュ配信されます。日本国内のユーザーの場合、東京エッジからの配信となるため、RTT(Round Trip Time)は通常10ms以下です。

Serverless Functionsのリージョン指定

Serverless Functions(API Routes、Server Components)は、指定したリージョンで実行されます。日本向けサイトでは、東京リージョン(hnd1)を指定することで、データベースとの通信遅延を最小限に抑えられます。

// vercel.json でリージョンを指定
{
  "regions": ["hnd1"],
  "functions": {
    "app/**/*.ts": {
      "maxDuration": 10
    }
  }
}

// または、個別のAPI Routeでリージョンを指定
// app/api/blog/route.ts
export const runtime = "edge"; // Edge Runtimeで実行
export const preferredRegion = "hnd1"; // 東京リージョン

Edge RuntimeとNode.js Runtimeの使い分け

Vercelでは2つのランタイムが選択できます。

  • Edge Runtime: 軽量なV8エンジンベース。コールドスタートがほぼゼロ(起動時間 < 1ms)。ただし、Node.js APIの一部(fsなど)は利用不可
  • Node.js Runtime: フルNode.js環境。すべてのNode.js APIが利用可能。コールドスタートは100〜250ms程度

レスポンス速度が重要なページ(トップページ、ブログ一覧など)にはEdge Runtime、重い処理が必要なAPI(画像処理、PDF生成など)にはNode.js Runtimeを使うのが定石です。

Next.jsのゼロコンフィグデプロイ

VercelとNext.jsの統合は、他のどのプラットフォームよりも深いレベルで行われています。GitHubリポジトリを接続するだけで、以下が自動的に設定されます。

  • ビルドコマンド: next build の自動検出と実行
  • 出力ディレクトリ: .next ディレクトリの自動認識
  • ルーティング: App Router / Pages Routerの自動判定
  • Server Components: Serverless Functionsへの自動変換
  • Static Generation: 静的ページのEdge Networkへの自動配信
  • Image Optimization: next/image の最適化APIの自動提供

つまり、vercel.jsonすら不要で、git pushするだけで本番環境にデプロイされます。

Preview Deploymentsによるプルリクエストレビュー

Vercelの最も便利な機能の一つが、Preview Deploymentsです。プルリクエストを作成するたびに、自動的に一意のURLでプレビュー環境が生成されます。

// プルリクエスト #42 のプレビューURL例
// https://project-name-git-feature-branch-team.vercel.app

// GitHub上のプルリクエストにVercelボットがコメント
// ✅ Preview: https://project-name-xxxxx.vercel.app
// 📊 Lighthouse: Performance 96, Accessibility 100

この機能により、コードレビュー時にレビュアーが実際の動作を確認できるため、UIの崩れや意図しない挙動を本番デプロイ前に発見できます。デザイナーやプロダクトマネージャーなど、非エンジニアのステークホルダーにも確認を依頼しやすくなります。

Environment Variables管理

Vercelでは、環境変数を3つのスコープで管理できます。

  • Production: 本番環境(mainブランチへのデプロイ)でのみ利用可能
  • Preview: プレビュー環境(プルリクエスト)でのみ利用可能
  • Development: vercel env pull でローカル開発環境に展開
# 環境変数をローカルに展開
$ vercel env pull .env.local

# .env.local に以下が出力される
NEXT_PUBLIC_SUPABASE_URL=https://xxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGci...
SUPABASE_SERVICE_ROLE_KEY=eyJhbGci...

この設計により、本番環境のAPIキーが誤ってプレビュー環境で使用されるリスクを防止できます。特にSupabaseのService Role Keyのような機密性の高い鍵は、Production環境にのみ設定するのがベストプラクティスです。

Vercel Analytics / Speed Insightsでのパフォーマンス監視

Vercelは、2つのパフォーマンス監視ツールを提供しています。

Vercel Analytics

リアルユーザーモニタリング(RUM)ベースのアクセス解析です。Google Analyticsのような外部ツールなしで、ページビュー、ユーザー数、リファラーなどの基本的な解析が可能です。

Speed Insights

Core Web Vitalsのリアルタイム計測に特化したツールです。以下の指標を、実際のユーザーのブラウザから収集します。

  • LCP(Largest Contentful Paint): メインコンテンツの表示時間。目標は2.5秒以内
  • FID(First Input Delay): 最初の操作への応答時間。目標は100ms以内
  • CLS(Cumulative Layout Shift): レイアウトのズレ量。目標は0.1以内
  • INP(Interaction to Next Paint): 操作から次の描画までの応答性。目標は200ms以内
  • TTFB(Time to First Byte): 最初のバイトが届くまでの時間。目標は800ms以内
// Speed Insightsの導入(Next.js App Router)
// app/layout.tsx
import { SpeedInsights } from "@vercel/speed-insights/next";
import { Analytics } from "@vercel/analytics/next";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <SpeedInsights />
        <Analytics />
      </body>
    </html>
  );
}

カスタムドメイン設定とSSL証明書の自動管理

Vercelでのカスタムドメイン設定は非常にシンプルです。ダッシュボードからドメインを追加し、DNSレコードを設定するだけで完了します。

  • SSL証明書: Let's Encryptによる証明書が自動発行・自動更新される。設定作業は一切不要
  • リダイレクト: wwwあり/なしの統一、HTTPからHTTPSへのリダイレクトが自動設定
  • 複数ドメイン: 1つのプロジェクトに複数ドメインを設定可能(例: n-n.tokyo と www.n-n.tokyo)
// DNSレコード設定例(n-n.tokyo の場合)
// Aレコード: @ → 76.76.21.21
// CNAMEレコード: www → cname.vercel-dns.com

Vercel Cron Jobsの実践

Vercel Cron Jobsを使えば、定期的なバッチ処理をサーバーレスで実行できます。外部のcronサービスが不要になります。

// vercel.json
{
  "crons": [
    {
      "path": "/api/cron/update-sitemap",
      "schedule": "0 3 * * *"
    },
    {
      "path": "/api/cron/cleanup-sessions",
      "schedule": "0 */6 * * *"
    }
  ]
}

// app/api/cron/update-sitemap/route.ts
import { NextResponse } from "next/server";

export async function GET(request: Request) {
  // Cron Jobからの呼び出しを検証
  const authHeader = request.headers.get("authorization");
  if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  // サイトマップ更新処理
  await generateSitemap();

  return NextResponse.json({ success: true });
}

Edge MiddlewareとISRの実践

Edge Middleware

Edge Middlewareは、リクエストがサーバーに到達する前にEdge上で実行される処理です。認証チェック、リダイレクト、A/Bテスト、地域別コンテンツ配信などに利用できます。

// middleware.ts(プロジェクトルート)
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export function middleware(request: NextRequest) {
  // 管理画面へのアクセスを認証チェック
  if (request.nextUrl.pathname.startsWith("/admin")) {
    const token = request.cookies.get("admin_token");
    if (!token) {
      return NextResponse.redirect(new URL("/admin/login", request.url));
    }
  }

  // 日本語ユーザーへのジオロケーション対応
  const country = request.geo?.country;
  if (country && country !== "JP" && request.nextUrl.pathname === "/") {
    // 海外ユーザーには英語ページを表示(将来の多言語対応用)
    // return NextResponse.rewrite(new URL("/en", request.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: ["/admin/:path*", "/"],
};

ISR(Incremental Static Regeneration)

ISRは、静的サイト生成(SSG)の利点を維持しつつ、コンテンツの更新にも対応する仕組みです。ブログ記事のような頻繁に更新されるコンテンツに最適です。

// app/blog/[slug]/page.tsx
// ISRの設定: 60秒ごとにバックグラウンドで再生成
export const revalidate = 60;

// オンデマンドISRの実装
// app/api/revalidate/route.ts
import { revalidatePath, revalidateTag } from "next/cache";

export async function POST(request: Request) {
  const { path, tag, secret } = await request.json();

  if (secret !== process.env.REVALIDATION_SECRET) {
    return Response.json({ error: "Invalid secret" }, { status: 401 });
  }

  if (tag) {
    revalidateTag(tag); // タグベースの再検証
  } else if (path) {
    revalidatePath(path); // パスベースの再検証
  }

  return Response.json({ revalidated: true, now: Date.now() });
}

たとえば、管理画面からブログ記事を更新した際に、/api/revalidateエンドポイントを呼び出すことで、該当ページを即座に再生成できます。ユーザーは常に最新のコンテンツを閲覧でき、かつ静的配信のパフォーマンスも享受できます。

パフォーマンス実績

当社サイト(n-n.tokyo)のVercel + Next.js構成でのパフォーマンス実績です。

  • Lighthouse Performance: 95+
  • Lighthouse Accessibility: 100
  • Lighthouse Best Practices: 100
  • Lighthouse SEO: 100
  • TTFB(東京): 平均 45ms
  • LCP(東京): 平均 1.2秒
  • CLS: 0.01以下

東京エッジからの配信とISRの組み合わせにより、日本国内のユーザーに対して極めて高速なレスポンスを実現しています。

まとめ

Vercelは、Next.jsプロジェクトのデプロイ・ホスティング・パフォーマンス最適化をワンストップで実現するプラットフォームです。東京リージョンのEdge配信、ゼロコンフィグデプロイ、Preview Deployments、ISR、Edge Middleware。これらの機能を活用することで、日本向けWebサイトの最適なインフラ基盤を構築できます。設定の複雑さに悩む時間を開発に集中し、ユーザーに最高の体験を届けることに専念しましょう。

Vercel
Next.js
デプロイ
エッジ配信
パフォーマンス

関連記事