邊緣計算×前端:Cloudflare Workers/Vercel Edge 讓你的網站快到離譜

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

為什麼前端需要邊緣計算?

傳統架構中,使用者請求需要穿越半個網際網路到達源站伺服器:

使用者(東京)→ CDN 節點(東京,僅快取靜態)→ 源站(美西,動態計算)
延遲:~10ms          ~150ms 跨太平洋                ~50ms 計算
總計:~210ms

邊緣計算把計算邏輯推到離使用者最近的節點

使用者(東京)→ Edge 節點(東京,直接計算)
延遲:~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

實戰場景一: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).*)'],
};

實戰場景二: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
伺服器端分流 ✅ 無閃爍 增加延遲
邊緣分流 ✅ 無閃爍 幾乎無影響

實戰場景三:個人化內容

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

    // 根據時區顯示本地時間
    const localTime = new Date().toLocaleTimeString('zh-TW', {
      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,
    });
  },
};

實戰場景四: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: 'zh-TW',
}));

// 讀取(最終一致性,~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 路由 → Edge
  → 業務邏輯仍在源站

階段 3:輕量 API 邊緣化(2-4 週)
  → 讀多寫少的 API → Edge + KV
  → 寫操作仍走源站

階段 4:重度邏輯邊緣化(按需)
  → SSR → Edge SSR
  → 串流式回應 → Edge Streaming

注意事項

限制 說明 應對
無 Node.js API 沒有 fspath 使用 Web API 替代
執行時間限制 Workers: 30ms (免費) / 30s (付費) 拆分長任務
套件大小限制 Workers: 10MB Tree-shaking、WASM
無全域狀態 每次請求獨立 Isolate 使用 KV/D1 持久化
冷啟動雖快但非零 V8 Isolate ~5ms 預熱關鍵路由

效能實測

工具庫網站使用 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