Vercel Edge Functions cold start 최적화
Vercel Edge Functions의 cold start 시간을 줄이고 성능을 최적화하는 방법을 다룹니다.
Introduction
Vercel Edge Functions은 분산 환경에서 빠른 응답 시간을 제공하지만, cold start 문제가 발생할 수 있습니다. 이번 포스트에서는 cold start를 최적화하는 방법을 살펴보겠습니다.
Environment
# Vercel CLI
vercel --version
# 33.0.0
# Edge Runtime
# @vercel/edge@1.1.1Problem
Edge Functions 호출 시 cold start로 인한 지연이 발생했습니다:
# 성능 측정 결과
Cold start: 800ms-1.2s
Warm start: 50ms-100ms
# 사용자 경험 영향
- 첫 페이지 로드: 1.2초 지연
- 후속 요청: 100ms 이하Analysis
Cold Start 원인
Edge Function 호출
│
├─ Worker 초기화 (200-400ms)
├─ 런타임 로드 (100-200ms)
├─ 모듈 초기화 (100-300ms)
└─ 핫 리로드 (50-100ms)
총 Cold Start: 500ms-1.2s최적화 전후 비교
| 항목 | 최적화 전 | 최적화 후 |
|---|---|---|
| Cold start | 1.2s | 300ms |
| 번들 크기 | 500KB | 150KB |
| 메모리 사용 | 128MB | 64MB |
Solution
1. 번들 크기 최소화
// edge-functions/api.ts
// 불필요한 import 제거
import { NextResponse } from 'next/server';
// 큰 라이브러리 대신 가벼운 대안 사용
// ❌ import { v4 as uuidv4 } from 'uuid';
// ✅ 직접 구현
function generateId() {
return crypto.randomUUID();
}
export const config = {
runtime: 'edge',
};
export default async function handler(req) {
return NextResponse.json({ id: generateId() });
}2. 미리 로드 최적화
// edge-functions/api.ts
// 자주 사용되는 값 미리 로드
const CONFIG = {
apiEndpoint: process.env.API_ENDPOINT,
timeout: 5000,
};
// 동적 import 대신 정적 import 사용
import { verify } from '@tsndr/cloudflare-worker-jwt';
export default async function handler(req) {
const token = req.headers.get('Authorization');
const payload = await verify(token, CONFIG.apiSecret);
return NextResponse.json({ user: payload });
}3. Edge Runtime 설정
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
runtime: 'edge',
},
};
module.exports = nextConfig;4. Edge Middleware 최적화
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
// 미들웨어에서 가벼운 로직만 처리
export function middleware(request: NextRequest) {
// 인증 확인 (가벼운 작업)
const token = request.cookies.get('token');
if (!token && request.nextUrl.pathname.startsWith('/protected')) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/protected/:path*', '/api/:path*'],
};5. Edge Config 활용
import { get } from '@vercel/edge-config';
export default async function handler(req) {
// Edge Config에서 빠르게 설정 가져오기
const featureFlags = await get('feature-flags');
return NextResponse.json({
features: featureFlags,
});
}6. 워밍 요청 설정
// vercel.json
{
"crons": [
{
"path": "/api/warm",
"schedule": "*/5 * * * *"
}
]
}// pages/api/warm.ts
export default function handler(req, res) {
res.status(200).json({ status: 'ok' });
}Lessons Learned
- 번들 크기 관리: Edge Functions의 번들 크기를 최소화하세요
- 정적 import 우선: 동적 import보다 정적 import를 사용하세요
- 가벼운 라이브러리: 무거운 라이브러리 대신 가벼운 대안을 사용하세요
- 설정 미리 로드: 자주 사용되는 설정은 미리 로드하세요
- 워밍 요청: 정기적인 워밍 요청으로 cold start를 줄이세요
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.