エッジコンピューティング×フロントエンド:Cloudflare Workers/Vercel Edgeでサイトを驚異的に高速化

前端工程(更新: 2026年6月2日)

なぜフロントエンドにエッジコンピューティングが必要か?

従来のアーキテクチャでは、ユーザーリクエストはインターネットの半分を横断してオリジンサーバーに到達します:

ユーザー(東京)→ CDNノード(東京、静的キャッシュのみ)→ オリジン(米西海岸、動的計算)
遅延:~10ms          ~150ms 太平洋横断                ~50ms 計算
合計:~210ms

エッジコンピューティングは計算ロジックをユーザーに最も近いノードにプッシュします:

ユーザー(東京)→ エッジノード(東京、直接計算)
遅延:~10ms        ~5ms ローカル計算
合計:~15ms

14倍の遅延削減—これがエッジコンピューティングの力です。


三大エッジプラットフォームの比較

次元 Cloudflare Workers Vercel Edge Functions Deno Deploy
ランタイム V8 Isolate V8 Isolate Deno
コールドスタート <5ms <5ms ~20ms
グローバルノード 300+都市 30+リージョン 35+リージョン
無料枠 10万リクエスト/日 プロジェクトごと課金 100万リクエスト/月
言語 JS/TS/WASM JS/TS JS/TS/WASM
バンドルサイズ制限 10MB 4MB 無制限
KVストレージ Workers KV Edge Config Deno KV
フレームワーク統合 フレームワーク非依存 Next.js深層統合 Fresh

実践シナリオ1:Geoルーティング

ユーザーの地理的位置に基づいて異なるコンテンツにルーティング、ゼロ遅延

// Cloudflare Workers
export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext) {
    const country = request.cf?.country as string;

    const routes: Record<string, string> = {
      CN: 'https://cn.example.com',
      JP: 'https://jp.example.com',
      US: 'https://us.example.com',
      EU: 'https://eu.example.com',
    };

    const target = routes[country] || routes['US'];

    return Response.redirect(target, 302);
  },
};

Vercel Edge版

// middleware.ts (Next.js)
import { NextRequest, NextResponse } from 'next/server';

export function middleware(request: NextRequest) {
  const country = request.geo?.country || 'US';

  const localeMap: Record<string, string> = {
    CN: '/zh-CN',
    TW: '/zh-TW',
    JP: '/ja',
  };

  const locale = localeMap[country] || '/en';

  if (!request.nextUrl.pathname.startsWith(locale)) {
    return NextResponse.redirect(new URL(locale, request.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: ['/((?!api|_next/static).*)'],
};

実践シナリオ2:A/Bテスト

クライアントJS不要、エッジ層で直接トラフィックを振り分け:

export default {
  async fetch(request: Request, env: Env) {
    const url = new URL(request.url);

    // 実験グループの読み取りまたは割り当て
    let variant = getCookie(request, 'ab-variant');

    if (!variant) {
      variant = Math.random() < 0.5 ? 'control' : 'experiment';
    }

    // KVから対応バージョンのHTMLを読み取り
    const html = await env.KV.get(`landing:${variant}`);

    const response = new Response(html, {
      headers: { 'Content-Type': 'text/html' },
    });

    // グループ一貫性を維持するCookieを設定
    response.headers.append(
      'Set-Cookie',
      `ab-variant=${variant}; Path=/; Max-Age=86400`
    );

    return response;
  },
};

function getCookie(request: Request, name: string): string | null {
  const cookies = request.headers.get('Cookie') || '';
  const match = cookies.match(new RegExp(`${name}=([^;]+)`));
  return match ? match[1] : null;
}

利点比較

方式 ファーストビューのちらつき パフォーマンス影響 SEO対応 実装複雑度
クライアントJS振り分け ❌ ちらつきあり LCP低下
サーバーサイド振り分け ✅ ちらつきなし 遅延増加
エッジ振り分け ✅ ちらつきなし ほぼ影響なし

実践シナリオ3:パーソナライズドコンテンツ

export default {
  async fetch(request: Request, env: Env) {
    const country = request.cf?.country;
    const timezone = request.cf?.timezone;

    // タイムゾーンに基づいて現地時間を表示
    const localTime = new Date().toLocaleTimeString('ja-JP', {
      timeZone: timezone,
    });

    // 国に基づいて現地通貨を表示
    const currencyMap: Record<string, { symbol: string; rate: number }> = {
      CN: { symbol: '¥', rate: 7.2 },
      JP: { symbol: '¥', rate: 150 },
      US: { symbol: '$', rate: 1 },
    };

    const currency = currencyMap[country] || currencyMap['US'];

    // ベースページを取得しパーソナライズデータを注入
    const response = await fetch(request);
    const html = await response.text();

    const personalized = html
      .replace('{{LOCAL_TIME}}', localTime)
      .replace('{{CURRENCY_SYMBOL}}', currency.symbol);

    return new Response(personalized, {
      headers: response.headers,
    });
  },
};

実践シナリオ4:API集約とキャッシング

エッジ層で複数のAPIを集約し、クライアントリクエストを削減:

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext) {
    const cache = caches.default;
    const cacheKey = new Request(request.url);

    // 1. エッジキャッシュをチェック
    let response = await cache.match(cacheKey);
    if (response) return response;

    // 2. 複数APIに並列リクエスト
    const [user, posts, notifications] = await Promise.all([
      fetch('https://api.example.com/user', { headers: request.headers }),
      fetch('https://api.example.com/posts?limit=10'),
      fetch('https://api.example.com/notifications/unread'),
    ]);

    // 3. レスポンスを集約
    const data = {
      user: await user.json(),
      posts: await posts.json(),
      notifications: await notifications.json(),
    };

    response = new Response(JSON.stringify(data), {
      headers: {
        'Content-Type': 'application/json',
        'Cache-Control': 'public, max-age=60',
      },
    });

    // 4. エッジキャッシュに書き込み
    ctx.waitUntil(cache.put(cacheKey, response.clone()));

    return response;
  },
};

エッジKVストレージ:グローバル低遅延データベース

Cloudflare Workers KV

// 書き込み
await env.KV.put('user:123:preferences', JSON.stringify({
  theme: 'dark',
  language: 'ja',
}));

// 読み取り(結果整合性、~60sグローバル同期)
const prefs = await env.KV.get('user:123:preferences', 'json');

// リスト
const list = await env.KV.list({ prefix: 'user:123:' });

Vercel Edge Config

import { get } from '@vercel/edge-config';

// 設定を読み取り(グローバル同期、~1s遅延)
const flags = await get('feature-flags');

if (flags?.newHomepage) {
  return newHomepage();
}
return oldHomepage();

従来アーキテクチャからの移行

移行パス

フェーズ1:静的リソースをCDNに(1-2日)
  → HTML/JS/CSS/画像 → CDNエッジキャッシュ
  → 動的リクエストはまだオリジンへ

フェーズ2:エッジミドルウェア(1-2週間)
  → リダイレクト、A/Bテスト、Geoルーティング → エッジ
  → ビジネスロジックはまだオリジン

フェーズ3:軽量APIのエッジ化(2-4週間)
  → 読み取り中心のAPI → エッジ + KV
  → 書き込み操作はまだオリジンへ

フェーズ4:重量ロジックのエッジ化(必要に応じて)
  → SSR → エッジSSR
  → ストリーミングレスポンス → エッジストリーミング

注意事項

制限 説明 対策
Node.js APIなし fspath等なし Web APIで代替
実行時間制限 Workers: 30ms(無料)/ 30s(有料) 長いタスクを分割
バンドルサイズ制限 Workers: 10MB Tree-shaking、WASM
グローバル状態なし リクエストごとに独立Isolate KV/D1で永続化
コールドスタートは小さいがゼロではない V8 Isolate ~5ms 主要ルートをウォームアップ

パフォーマンス実測

ToolsKuサイトはCloudflare CDN + 静的エクスポートアーキテクチャを使用:

指標              従来のSSR    エッジ静的
TTFB              200-500ms    10-30ms
LCP               1.5-3s       0.3-0.8s
グローバルP50遅延 150ms        15ms
グローバルP99遅延 800ms        50ms

まとめ

エッジコンピューティングはフロントエンドパフォーマンス最適化の究極の武器です—サーバーで50ms節約するのではなく、150msのネットワーク遅延を5msに削減することです。2026年、もし動的ページがまだエッジで実行されていないなら、ユーザーに100ms以上の待ち時間を無駄に浪費させています。Geoルーティング、A/BテストからAPI集約まで、エッジコンピューティングはフロントエンド開発者に「世界300以上の都市にコードをデプロイする」超能力を与えます。

ブラウザローカルツールを無料で試す →

#边缘计算#CDN#Edge Functions#性能优化#Cloudflare Workers