Web Worker avec Claude Code
Découvrez web Worker avec Claude Code. Conseils pratiques et exemples de code inclus.
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をご覧ください。
Passez votre flux Claude Code au niveau supérieur
50 modèles de prompts éprouvés, prêts à être copiés-collés dans Claude Code.
PDF gratuit : aide-mémoire Claude Code en 5 minutes
Commandes clés, raccourcis et exemples de prompts sur une seule page imprimable.
À propos de l'auteur
Masa
Ingénieur passionné par Claude Code. Il gère claudecode-lab.com, un média tech en 10 langues avec plus de 2 000 pages.
Articles similaires
Créer des commandes slash personnalisées dans Claude Code
Apprenez à créer des commandes slash personnalisées dans Claude Code. Couvre l'emplacement des fichiers, les arguments et l'automatisation des tâches.
10 astuces pour tripler votre productivité avec Claude Code
Découvrez 10 astuces pratiques pour tirer le meilleur parti de Claude Code. Des stratégies de prompts aux raccourcis de workflow, ces techniques amélioreront votre efficacité dès aujourd'hui.
Optimisation Canvas/WebGL avec Claude Code
Découvrez l'optimisation Canvas/WebGL avec Claude Code. Conseils pratiques et exemples de code inclus.