mcpField
C
cloudflare-workers-performance

cloudflare-workers-performance

github.com/secondskyクラウド・DevOps240319 回インストール5 週間前に更新
リポジトリ

cloudflare-workers-performance について

Cloudflare Workers の最適化に取り組む開発者向けのリファレンススキルです。CPU、メモリ、レイテンシ、キャッシュ、バンドルサイズの手法に加え、関連資料、テンプレート、プロファイリングスクリプトを扱います。

主な機能

  1. 01CPUとホットパスの最適化
  2. 02ストリーミングとメモリ管理
  3. 03Cache APIとバッチ処理
  4. 04バンドルサイズとコールドスタートの指針
  5. 05テンプレートとプロファイリングスクリプト

活用シーン

  1. 01WorkerのCPU使用量とレイテンシの削減
  2. 02大きなペイロードをバッファリングせず処理
  3. 03メモリやコールドスタートの問題を調査
  4. 04キャッシュやパフォーマンス監視を追加

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/secondsky/claude-skills --skill cloudflare-workers-performance

インストール後、Claude Code で/cloudflare-workers-performanceを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
bundle-optimization.md
caching-strategies.md
cold-starts.md
cpu-optimization.md
memory-optimization.md
scripts/
benchmark.sh
profile-worker.sh
templates/
caching-layer.ts
optimized-worker.ts
performance-middleware.ts

詳細

Cloudflare Workers のパフォーマンス最適化

Worker のパフォーマンスを最大化し、レイテンシを最小限に抑えるための手法です。

すぐにできる改善

// 1. Avoid unnecessary cloning
// ❌ Bad: Clones entire request
const body = await request.clone().json();

// ✅ Good: Parse directly when not re-using body
const body = await request.json();

// 2. Use streaming instead of buffering
// ❌ Bad: Buffers entire response
const text = await response.text();
return new Response(transform(text));

// ✅ Good: Stream transformation
return new Response(response.body.pipeThrough(new TransformStream({
  transform(chunk, controller) {
    controller.enqueue(process(chunk));
  }
})));

// 3. Cache expensive operations
const cache = caches.default;
const cached = await cache.match(request);
if (cached) return cached;

重要なルール

  1. CPU 制限内に収める - 10ms(無料プラン)、30ms(有料プラン)、50ms(無制限プラン)
  2. コールドスタートを最小限に抑える - バンドルサイズを 1MB 未満にし、動的インポートを避けます
  3. Cache API を使用する - エッジでレスポンスをキャッシュします
  4. 大きなペイロードはストリーミングする - レスポンス全体をバッファリングしないでください
  5. 操作をまとめる - 複数の KV/D1 呼び出しをまとめます

パフォーマンスに関する主なエラー 10 件

エラー症状対処法
CPU 制限の超過Worker が終了するホットパスを最適化し、ストリーミングを使用します
コールドスタートのレイテンシ最初のリクエストが遅いバンドルサイズを小さくし、トップレベルの await を避けます
メモリ負荷GC の遅延、タイムアウトデータをストリーミングし、大きな配列を避けます
KV のレイテンシ読み取りが遅いCache API を使用し、読み取りをまとめます
D1 のクエリが遅いレイテンシが高いインデックスを追加し、SQL を最適化します
バンドルサイズが大きいコールドスタートが遅いツリーシェイキングを行い、コードを分割します
ブロッキング操作リクエストのタイムアウトPromise.all とストリーミングを使用します
不要なクローン作成メモリの急増必要な場合にのみクローンを作成します
キャッシュがない計算の繰り返しキャッシュ層を実装します
同期操作CPU の急増非同期の代替手段を使用します

CPU の最適化

ホットパスのプロファイリング
async function profiledHandler(request: Request): Promise<Response> {
  const timing: Record<string, number> = {};

  const time = async <T>(name: string, fn: () => Promise<T>): Promise<T> => {
    const start = Date.now();
    const result = await fn();
    timing[name] = Date.now() - start;
    return result;
  };

  const data = await time('fetch', () => fetchData());
  const processed = await time('process', () => processData(data));
  const response = await time('serialize', () => serialize(processed));

  console.log('Timing:', timing);
  return new Response(response);
}
JSON 操作の最適化
// For large JSON, use streaming parser
import { JSONParser } from '@streamparser/json';

async function parseStreamingJSON(stream: ReadableStream): Promise<unknown[]> {
  const parser = new JSONParser();
  const results: unknown[] = [];

  parser.onValue = (value) => results.push(value);

  for await (const chunk of stream) {
    parser.write(chunk);
  }

  return results;
}

メモリの最適化

大きな配列を避ける
// ❌ Bad: Loads all into memory
const items = await db.prepare('SELECT * FROM items').all();
const processed = items.results.map(transform);

// ✅ Good: Process in batches
async function* batchProcess(db: D1Database, batchSize = 100) {
  let offset = 0;
  while (true) {
    const { results } = await db
      .prepare('SELECT * FROM items LIMIT ? OFFSET ?')
      .bind(batchSize, offset)
      .all();

    if (results.length === 0) break;

    for (const item of results) {
      yield transform(item);
    }
    offset += batchSize;
  }
}

キャッシュ戦略

マルチレイヤーキャッシュ
interface CacheLayer {
  get(key: string): Promise<unknown | null>;
  set(key: string, value: unknown, ttl?: number): Promise<void>;
}

// Layer 1: In-memory (request-scoped)
const memoryCache = new Map<string, unknown>();

// Layer 2: Cache API (edge-local)
const edgeCache: CacheLayer = {
  async get(key) {
    const response = await caches.default.match(new Request(`https://cache/${key}`));
    return response ? response.json() : null;
  },
  async set(key, value, ttl = 60) {
    await caches.default.put(
      new Request(`https://cache/${key}`),
      new Response(JSON.stringify(value), {
        headers: { 'Cache-Control': `max-age=${ttl}` }
      })
    );
  }
};

// Layer 3: KV (global)
// Use env.KV.get/put

バンドルの最適化

// 1. Tree-shake imports
// ❌ Bad
import * as lodash from 'lodash';

// ✅ Good
import { debounce } from 'lodash-es';

// 2. Lazy load heavy dependencies
let heavyLib: typeof import('heavy-lib') | undefined;

async function getHeavyLib() {
  if (!heavyLib) {
    heavyLib = await import('heavy-lib');
  }
  return heavyLib;
}

リファレンスを読み込むタイミング

タスクに応じて、必要なリファレンスを読み込みます。

  • CPU 使用率を最適化しますか? → references/cpu-optimization.md を読み込みます
  • メモリに関する問題ですか? → references/memory-optimization.md を読み込みます
  • キャッシュを実装しますか? → references/caching-strategies.md を読み込みます
  • バンドルサイズを小さくしますか? → references/bundle-optimization.md を読み込みます
  • コールドスタートの問題ですか? → references/cold-starts.md を読み込みます

テンプレート

テンプレート用途使用するタイミング
templates/performance-middleware.tsパフォーマンスの監視タイミング測定/プロファイリングの追加
templates/caching-layer.tsマルチレイヤーキャッシュキャッシュの実装
templates/optimized-worker.tsパフォーマンスパターン最適化された Worker の開始

スクリプト

スクリプト用途コマンド
scripts/benchmark.sh負荷テスト./benchmark.sh <url>
scripts/profile-worker.shCPU プロファイリング./profile-worker.sh

リソース

コメント