第五章:Edge Functions デプロイ実戦:WebSocket接続を高速・安定化し、Vercelの制限を突破する
あなたのAIチャットルームはlocalhost開発環境では高速に動作し、タイプライター効果も滑らかだったため、喜んでVercelにデプロイしてクライアントに披露しようとしました。しかし本番環境では真の災害が始まります:
- AIの返答が時々固まり、突然長文が吐き出される
- AIの生成が10秒以上かかると、Vercelが接続を切断し
504 Gateway Timeoutエラーが発生 - 最初のユーザー質問は常に遅く、AIが応答を開始するまで数秒待たされる
これはAI製品を初めてデプロイする開発者の99%が直面する壁です。本章ではこれらの原因を深掘りし、「Edge Runtime(エッジコンピューティング)」で物理的・クラウドアーキテクチャの制限を突破する方法を解説します。
💀 キラー1:Serverless Functionの「最大実行時間(Max Duration)」制限
Next.jsなどのモダンなフロントエンドフレームワークをVercelにデプロイすると、バックエンドAPIはデフォルトで**Node.js Serverless Function(サーバーレス関数)**環境で実行されます。
Serverlessのビジネスモデルは「実行回数と時間」で課金されるため、クラウドプラットフォームは無限ループを防ぐために厳格なタイムアウト制限を設けています:
- Vercel無料版(Hobby Tier)では、API Routeの最大実行時間は10秒
- 有料版(Pro Tier)でもデフォルト15秒(最大300秒まで拡張可能だが高額)
AIチャットルームへの影響 ユーザーが複雑な質問をした場合、GPT-4やClaude OpusなどのAIモデルが25秒かけて文章を生成・ストリーミングすることがあります。 しかし10秒経過時点でVercelサーバーが強制的にAPI Routeを切断するため、フロントエンドは完全な終了信号を受け取れず、タイプライターがフリーズしたりエラーが発生します。
❄️ キラー2:コールドスタートと地理的な遅延
Serverlessのもう一つの特性は「トラフィックがない時は休眠(Scale to Zero)」することです。 深夜にアクセスがない場合、サーバーは存在しません。 朝最初のユーザーがメッセージを送信すると、Vercelは1~2秒かけてサーバーを「起動(Cold Start)」し、OpenAI APIを呼び出し、米国のVercelサーバーから台湾のユーザーへデータが太平洋を横断して返されます。
この「起動遅延」と「多段階の国際ネットワーク伝送」により、ストリーミング体験が悪化します:タイプライター効果が「カクつき、文字が塊で表示される」ようになります。
💊 解決策:Vercel Edge Runtime(エッジコンピューティングノード)
このタイムアウトと遅延問題を解決するため、Vercel(およびNext.js公式)は革新的な基盤アーキテクチャEdge Runtimeを導入しました。 Edge Runtimeは「超軽量で世界中に分散したマイクロサーバー」と想像してください。
Edge Runtimeの3大優位性:
- 10秒タイムアウト制限なし:ストリーミングデータが継続的に送信されている限り、Edgeは接続を切断しません!AIが1分以上かけてゆっくり話すことも可能
- ゼロコールドスタート:Edgeノードは極度に軽量(V8 Isolateベース)で、サーバー起動待ち時間なし
- ユーザーに極めて近い:Edgeノードは台北・東京を含む世界中に展開。OpenAIからアジアノードを経由し台湾ユーザーへ直接データ配信
🚀 API RouteをEdgeに切り替える方法
驚くほど簡単です。AIストリーミングを処理するRoute Handlerファイル(例:src/app/api/chat/route.ts)の先頭に1行宣言を追加するだけ:
import { NextResponse } from 'next/server';
// 🚀 この魔法の宣言を追加:Next.jsにこのAPIを米国Node.jsサーバーでなく
// グローバルCDNのエッジノードで実行するよう指示
export const runtime = 'edge';
export async function POST(req: Request) {
// 1. ユーザーメッセージ取得
const { message } = await req.json();
// 2. OpenAI APIを呼び出し、streamモード設定
// (Edge環境では全てのfetchがグローバルエッジノードの高速性を享受)
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
},
body: JSON.stringify({
model: 'gpt-4',
stream: true, // 核心!ストリーミング返信を要求
messages: [{ role: 'user', content: message }],
}),
});
// 3. ReadableStreamを直接フロントエンドに転送
return new Response(response.body, {
headers: {
'Content-Type': 'text/event-stream', // 重要:ブラウザに長時間接続であることを通知
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
},
});
}
export const runtime = 'edge'を追加して再デプロイすれば、AI APIは生まれ変わり、10秒タイムアウトの呪縛を突破し、ミリ秒レベルの遅延と滑らかなタイプライター体験を実現します!
💣 Edge Runtimeの致命的な制限と注意点
Edgeが優れているなら、なぜNext.jsは全てをEdgeで実行しないのでしょうか?
Edge環境は「超軽量」であるため、完全なNode.js環境ではありません。 つまり:
fs(ファイルシステム)モジュールでローカルファイルを読み込めないchild_processでターミナルコマンドを実行できない- NodeネイティブC++モジュールに依存するNPMパッケージ(旧版
bcryptや複雑なドライバーを必要とする従来型RDBMS ORMなど)が使用できない
典型的な落とし穴:PrismaとEdgeの衝突
Edge API Routeでimport { PrismaClient } from '@prisma/client'してRDBMSにアクセスしようとすると、本番環境でクラッシュします。従来のPrismaはC++エンジン(Query Engine)に依存しており、軽量なEdge環境では動作しません。
アーキテクトの究極ソリューション
- 責務分離(マイクロアーキテクチャ):「タイプライターストリーミング」を担当するAPIはEdge Runtimeで高速化。会話終了後、別途通常のNode APIにHTTPリクエストを送信し、完全な会話記録をデータベースに保存
- Edge対応データベースサービスの利用:現代SaaS開発でSupabaseが強く推奨される理由です。
@supabase/supabase-jsSDKは標準のfetchHTTPリクエストベースであるため、Edge Runtimeと完全互換です!Edge内で直接Supabaseデータベースを読み書きできます
🎉 コース修了まとめ
リアルタイム接続とストリーミングは、従来のRequest-Responseという思考様式を根本から変える深淵なバックエンド領域です。
この5章で学んだ強力な技術を振り返りましょう:
- 基礎概念:HTTP Pollingの課題からWebSocket・SSEストリーミングの台頭まで
- WebSocket実戦:Supabase Realtimeでデータベース監視を実装し、画面リフレッシュ不要のプッシュ通知を実現
- フロントエンドデコード:ReadableStreamとTextDecoderを使ったコアデコードループの実装
- 状態管理:非効率なContext APIを廃し、業界標準のZustandとlocalStorageで高速な会話履歴切替を構築
- クラウドアーキテクチャ:Vercel Serverlessの10秒タイムアウト制限を看破し、Edge Runtimeエッジコンピューティングノードの導入に成功
これら5つの関門を突破したあなたは、もはや静的なウェブページを作る初級開発者ではありません。百万レベルの同時接続を処理できる、極めて滑らかな現代的なAI SaaS製品を構築する能力を手に入れたのです!あなたの偉大な製品を創造してください!