Web Workers con Claude Code
Aprenda sobre Web Workers usando Claude Code. Incluye consejos practicos y ejemplos de codigo.
Web Workerが必要な場面
JavaScriptはシングルスレッドで動作するため、重い計算処理はUIをフリーズさせます。Web Workerを使えば、バックグラウンドスレッドで処理を実行し、メインスレッドの応答性を維持できます。Claude Codeを使えば、型安全なWeb Worker通信の仕組みを素早く構築できます。
型安全なWeb Worker通信
> TypeScriptで型安全なWeb Workerの通信レイヤーを作って。
> メッセージの型定義とPromiseベースの呼び出しに対応して。
// 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();
}
}
ワーカー側の実装
// 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を管理するプールを作って。タスクを効率よく分散して。
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());
}
}
Reactフックでの活用
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
Claude Codeを使えば、型安全なWeb Worker通信からワーカープールまで、並列処理基盤を効率的に構築できます。パフォーマンス全般はパフォーマンス最適化を、Service Workerとの違いはService Worker活用を参照してください。
Web Worker APIの仕様はMDN Web Docs - Web Workersをご覧ください。
Related Posts
10 consejos para triplicar tu productividad con Claude Code
Descubre 10 consejos prácticos para sacar más provecho de Claude Code. Desde estrategias de prompts hasta atajos de flujo de trabajo, estas técnicas mejorarán tu eficiencia desde hoy.
Optimizacion de Canvas/WebGL con Claude Code
Aprende sobre la optimizacion de Canvas/WebGL usando Claude Code. Incluye consejos practicos y ejemplos de codigo.
Implementacion de Markdown con Claude Code
Aprenda sobre la implementacion de Markdown usando Claude Code. Incluye consejos practicos y ejemplos de codigo.