T-CREATOR

一瞬で表示!Next.js × Edge Runtimeで始める超低遅延サーバーレス開発

一瞬で表示!Next.js × Edge Runtimeで始める超低遅延サーバーレス開発

従来のサーバーレス環境の課題として、「初回起動の遅さ」や「地理的距離による遅延」などがありました。

それらを大きく打破するのが、Next.jsのEdge Runtimeです。

本記事では、Next.jsのApp RouterとEdge Runtimeを組み合わせて、グローバルに超低遅延なサーバーレスAPIやページ配信を実現する方法を、丁寧に解説します。

Edge Runtimeによる次世代Webの可能性

Next.jsは13以降、app/ディレクトリでApp Routerを採用し、Edge Runtimeへの対応が進みました。

以下に、Edge Runtimeの特長を簡単にまとめます。

特徴説明
超低レイテンシCloudflare WorkersやVercel Edge Functions上で、リクエストと同時に即実行
グローバル展開地理的に最も近いエッジロケーションで実行され、レイテンシが劇的に改善
スタートアップ不要Lambdaなどと異なり、コールドスタートが実質ゼロ
標準API互換Request / Response ベースのWeb標準API互換

詳しくは Next.js公式ドキュメント をご参照ください。

Edge Runtimeで動くハンドラの基本構成

App RouterでEdge Runtimeを使うには、Route Handlerをapp/api以下に配置し、runtimeを明示します。

tsx// app/api/hello/route.ts
import { NextResponse } from 'next/server'

export const runtime = 'edge'

export async function GET() {
  return NextResponse.json({ message: 'Hello from the edge!' })
}

このコードは、/api/hello にアクセスされた際に、エッジ環境上でJSONレスポンスを即座に返します

動作確認

bashcurl https://your-deployment-url.vercel.app/api/hello

通常のNode.jsランタイムに比べて、エッジで動作することで数倍高速な応答が得られる場合があります。

ページ配信にEdge Runtimeを活用する

APIだけでなく、Next.jsではページコンポーネントでもEdge Runtimeが使用可能です。

tsx// app/page.tsx
export const runtime = 'edge'

export default function Page() {
  return <h1>Edgeから配信されたページ</h1>
}

この指定により、静的配信のような速度で、動的な処理を伴ったページをユーザーの近くで処理・配信できるようになります。

Edge Runtime対応の制約事項

ただし、Edge Runtimeでは以下の制限に注意が必要です。

制限内容詳細
fs, net, child_process などのNode.jsコアモジュール使用不可(完全なNode API非対応)
Bufferの使用Edge環境用にポリフィルが必要な場合あり
外部ライブラリの互換性Node依存の強いライブラリ(例:bcrypt)は使えないことが多い

そのため、純粋なWeb API互換で書かれたライブラリの採用が推奨されます。

デプロイ先:VercelでのEdge Functions

Next.jsのEdge RuntimeはVercel上での運用を前提に高い互換性があります。

VercelでEdge FunctionsとしてデプロイされたAPIは、次のように確認可能です。

  • ダッシュボードで FunctionsEdge と表示される
  • Logsに edge と出力されるランタイムログ
bashvercel deploy --prod

Vercel以外でも、Cloudflare Pages / Workers や Netlify Edge Functions などと連携できますが、現状ではVercelが最も安定的な運用環境です。

キャッシュ戦略と組み合わせる

超低遅延をさらに活かすには、Edge Runtimeとキャッシュ制御の組み合わせが重要です。

例えば、次のようにしてレスポンスヘッダーにキャッシュ制御を付与できます。

tsexport async function GET() {
  const response = NextResponse.json({ data: 'Edge cached' })
  response.headers.set('Cache-Control', 'public, max-age=60')
  return response
}

CDNのキャッシュとEdge Functionsの速さを組み合わせることで、ほぼ静的配信に近い速度感が得られます。

フォーム送信とEdge Runtimeの相性

Edge Runtimeでは、POSTリクエストに対するハンドリングも可能です。以下は、フォームからの送信を処理するサンプルです。

tsx// app/api/contact/route.ts
import { NextResponse } from 'next/server'

export const runtime = 'edge'

export async function POST(req: Request) {
  const data = await req.json()
  console.log('送信内容:', data)

  return NextResponse.json({ status: 'ok', received: data })
}

フロントエンド側からは以下のように送信します。

tsxawait fetch('/api/contact', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: '山田', message: 'こんにちは' }),
})

JSONの処理は問題なく対応しています。ただし、formData()のようなブラウザ特有APIに依存する処理には注意が必要です。

クッキー操作とEdge Runtime

ユーザーのセッションを管理する場合、Edge RuntimeでもCookie操作が可能です。Next.js 13以降では、cookies()関数が提供されています。

tsx// app/api/login/route.ts
import { cookies } from 'next/headers'
import { NextResponse } from 'next/server'

export const runtime = 'edge'

export async function POST() {
  cookies().set('token', 'abc123', {
    httpOnly: true,
    path: '/',
    maxAge: 60 * 60,
  })

  return NextResponse.json({ status: 'cookie set' })
}

ただし、クライアントサイドでのCookie操作とは異なり、Server ActionやMiddleware内でのみ安全に操作できます。

公式ガイド:https://nextjs.org/docs/app/api-reference/functions/cookies

外部APIとの連携(例:OpenWeather API)

Edge RuntimeはfetchベースのAPIなので、外部APIとの連携にも適しています

tsxexport const runtime = 'edge'

export async function GET() {
  const res = await fetch(
    `https://api.openweathermap.org/data/2.5/weather?q=Tokyo&appid=${process.env.WEATHER_KEY}`
  )
  const weather = await res.json()

  return NextResponse.json(weather)
}

エッジから直接外部APIにアクセスすることで、バックエンドの待機時間を最小化できます。ただし、環境変数の扱いには注意してください。

開発環境での制約と注意点

Edge Runtimeを利用する際、ローカル開発には以下の制限があります。

制限内容解説
next dev はNodeで実行Edgeの正確な挙動を確認するにはVercelなどでのデプロイが必要
console.log が一部無効Cloudflare Workersのようにログ出力に制限がある
環境変数の制限.envからの読み込みは一部環境で反映されないことがある(公開変数優先)

Edge Runtimeのローカルエミュレーションは?

現時点(2025年時点)では、Edge Runtimeをローカルで100%再現する手段は公式には提供されていません。そのため、以下のような方針で開発を行うのが現実的です。

  • runtime = 'nodejs' として開発 → 動作確認後に edge に変更
  • デプロイ先で edge の動作ログをしっかり取得

Middlewareとの組み合わせ

App Router環境では、middleware.tsでもEdge Runtimeがデフォルトです。これはリクエストの前段に処理を差し込める強力な機構です。

ts// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(req: NextRequest) {
  const url = req.nextUrl.clone()

  if (!req.cookies.has('visited')) {
    const res = NextResponse.next()
    res.cookies.set('visited', 'true')
    return res
  }

  return NextResponse.next()
}
  • 特定パスへのアクセス制御
  • ABテストの切り替え
  • 国別の言語リダイレクト

などが高速に実装できます。

詳細:https://nextjs.org/docs/app/building-your-application/routing/middleware

使用可能なAPI一覧(Edge互換)

Edge Runtimeでは、以下のような標準APIがサポートされています。

API名使用可否補足
fetchフル対応
Request/ResponseWeb標準の型で利用可能
Headers読み書き可能
URL/URLSearchParamsクエリ処理やパス操作に利用可
cryptoSubtleCrypto などのWeb Crypto API利用可
TextEncoder/DecoderBufferの代替で使用可能

まとめ:Edge Runtimeで得られる3つの価値

Next.js × Edge Runtimeの導入によって得られる価値は、以下の3点に集約されます。

  1. 一瞬で表示される体験を提供可能

    • コールドスタートがなく、ユーザーの近くで実行されるため、UXが大幅に向上します。
  2. シンプルな記述で高速APIやページを構築

    • 通常のroute.tsmiddleware.tsを使うだけで、グローバルエッジ配信が実現可能です。
  3. Web標準APIベースのモダンな開発体験

    • fetch, cookie, headersなど、Node.jsに依存しないサーバーレス実装が可能となります。

VercelとNext.jsのEdge Runtimeは、フロントエンドエンジニアにとって高速で安全、かつ運用負荷の少ない開発基盤を提供してくれます。

今後、Webアプリケーションの体験向上を目指す上で、Edgeファーストな設計はますます重要になるでしょう。

次に構築するプロジェクトでは、ぜひ一歩踏み出して「Edgeで動く」サーバーレスを体験してみてください。

Next.jsの記事Nextjs