Tips & Tricks

Web Worker Implementation dengan Claude Code

Pelajari tentang web worker implementation menggunakan Claude Code. Dilengkapi tips praktis dan contoh kode.

Web Workerがdiperlukanな場面

JavaScript シングルスレッド 動作 untuk 、重い計算pemrosesan UI フリーズさせ.Web Worker 使えば、バックグラウンドスレッド pemrosesan 実行し、メインスレッド 応答性 維持 bisa dilakukan.Claude Code 使えば、type safetyなWeb Worker通信 mekanisme 素早くpembangunan bisa dilakukan.

type safetyなWeb Worker通信

> TypeScript dengan type safetyなWeb Worker 通信レイヤー buatkan.
> pesan 型definisi dan Promiseベース 呼び出し support.
// worker-types.ts
export interface WorkerRequest {
  id: string;
  type: string;
  payload: any;
}

export interface WorkerResponse {
  id: string;
  result?: any;
  error?: string;
}

// typed-worker.ts
type MessageHandler = (payload: any) => any | Promise<any>;

class TypedWorkerHost {
  private worker: Worker;
  private pending = new Map<string, { resolve: Function; reject: Function }>();
  private counter = 0;

  constructor(workerUrl: string | URL) {
    this.worker = new Worker(workerUrl, { type: 'module' });
    this.worker.onmessage = (e: MessageEvent<WorkerResponse>) => {
      const { id, result, error } = e.data;
      const handler = this.pending.get(id);
      if (!handler) return;
      this.pending.delete(id);
      error ? handler.reject(new Error(error)) : handler.resolve(result);
    };
  }

  call<T>(type: string, payload: any): Promise<T> {
    return new Promise((resolve, reject) => {
      const id = `msg-${++this.counter}`;
      this.pending.set(id, { resolve, reject });
      this.worker.postMessage({ id, type, payload } satisfies WorkerRequest);
    });
  }

  terminate() {
    this.worker.terminate();
    this.pending.forEach(({ reject }) => reject(new Error('Worker terminated')));
    this.pending.clear();
  }
}

implementasi ワーカー側

// heavy-computation.worker.ts
const handlers: Record<string, (payload: any) => any> = {
  'sort-data': (data: number[]) => {
    return data.sort((a, b) => a - b);
  },

  'filter-search': ({ items, query }: { items: any[]; query: string }) => {
    return items.filter((item) =>
      Object.values(item).some((v) =>
        String(v).toLowerCase().includes(query.toLowerCase())
      )
    );
  },

  'compute-statistics': (data: number[]) => {
    const n = data.length;
    const mean = data.reduce((a, b) => a + b, 0) / n;
    const sorted = [...data].sort((a, b) => a - b);
    const median = n % 2 === 0
      ? (sorted[n / 2 - 1] + sorted[n / 2]) / 2
      : sorted[Math.floor(n / 2)];
    const variance = data.reduce((sum, x) => sum + (x - mean) ** 2, 0) / n;

    return { mean, median, stdDev: Math.sqrt(variance), min: sorted[0], max: sorted[n - 1] };
  },
};

self.onmessage = async (e: MessageEvent<WorkerRequest>) => {
  const { id, type, payload } = e.data;

  try {
    const handler = handlers[type];
    if (!handler) throw new Error(`Unknown handler: ${type}`);
    const result = await handler(payload);
    self.postMessage({ id, result });
  } catch (error: any) {
    self.postMessage({ id, error: error.message });
  }
};

ワーカープール

> 複数 Worker manajemenするプール buatkan.task 効率よく分散して。
class WorkerPool {
  private workers: TypedWorkerHost[] = [];
  private queue: { type: string; payload: any; resolve: Function; reject: Function }[] = [];
  private busy: Set<number> = new Set();

  constructor(workerUrl: string, poolSize: number = navigator.hardwareConcurrency || 4) {
    for (let i = 0; i < poolSize; i++) {
      this.workers.push(new TypedWorkerHost(new URL(workerUrl, import.meta.url)));
    }
  }

  async execute<T>(type: string, payload: any): Promise<T> {
    const freeIndex = this.workers.findIndex((_, i) => !this.busy.has(i));

    if (freeIndex === -1) {
      return new Promise((resolve, reject) => {
        this.queue.push({ type, payload, resolve, reject });
      });
    }

    return this.runOnWorker(freeIndex, type, payload);
  }

  private async runOnWorker<T>(index: number, type: string, payload: any): Promise<T> {
    this.busy.add(index);
    try {
      return await this.workers[index].call<T>(type, payload);
    } finally {
      this.busy.delete(index);
      this.processQueue();
    }
  }

  private processQueue() {
    if (this.queue.length === 0) return;
    const freeIndex = this.workers.findIndex((_, i) => !this.busy.has(i));
    if (freeIndex === -1) return;

    const task = this.queue.shift()!;
    this.runOnWorker(freeIndex, task.type, task.payload)
      .then(task.resolve)
      .catch(task.reject);
  }

  terminate() {
    this.workers.forEach((w) => w.terminate());
  }
}

Pemanfaatan dengan React Hook

function useWorker<T>(type: string, payload: any, deps: any[]) {
  const [result, setResult] = useState<T | null>(null);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    setLoading(true);
    pool.execute<T>(type, payload)
      .then(setResult)
      .finally(() => setLoading(false));
  }, deps);

  return { result, loading };
}

Summary

Untuk Claude Codeを使えば、type safetyなWeb Worker通信からワーカープールまで、並列pemrosesanfondasiをefisienにpembangunanできます。performa全般はperformaoptimasiを、Service Workerとの違い, lihat Service Worker活用.

Web Worker API 仕様 MDN Web Docs - Web Workers silakan lihat.

#Claude Code #Web Worker #並列pemrosesan #performance #TypeScript