では、最終ステップとして 複数 Web Worker を使った完全並列処理 に拡張し、巨大多次元配列を複数 CPU コアで分散処理する例を作ります。UI は進捗バー付きでフリーズなしです。
例:複数 Worker で巨大多次元配列を並列処理
1️⃣ メイン HTML(UI + Worker 管理)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>複数 Worker 並列処理デモ</title>
<style>
#progress {
width: 100%;
background-color: #eee;
border-radius: 5px;
overflow: hidden;
margin: 10px 0;
}
#bar {
height: 20px;
background-color: #E91E63;
width: 0%;
}
#status { font-family: monospace; }
</style>
</head>
<body>
<h1>複数 Worker 並列処理デモ</h1>
<div id="progress"><div id="bar"></div></div>
<p id="status">準備中...</p>
<script>
const numWorkers = 4; // 使用する Worker 数
const rows = 1000, cols = 1000;
let workers = [];
let remainingWorkers = numWorkers;
let sumTotal = 0;
function updateProgress() {
let percent = Math.min(100, Math.floor((sumTotal / (rows * cols * 1.0)) * 100));
document.getElementById('bar').style.width = percent + '%';
document.getElementById('status').textContent = `処理中... ${percent}% 合計=${sumTotal}`;
}
for (let i = 0; i < numWorkers; i++) {
const worker = new Worker('worker-multi.js');
workers.push(worker);
worker.onmessage = function(e) {
const data = e.data;
if (data.progress !== undefined) {
updateProgress();
}
if (data.done) {
sumTotal += data.sum;
remainingWorkers--;
if (remainingWorkers === 0) {
document.getElementById('status').textContent =
`完了! 合計 = ${sumTotal}`;
document.getElementById('bar').style.width = '100%';
}
}
};
// データ範囲を Worker に渡す
worker.postMessage({
startRow: Math.floor((rows / numWorkers) * i),
endRow: Math.floor((rows / numWorkers) * (i + 1)),
cols
});
}
</script>
</body>
</html>
HTML2️⃣ Worker ファイル(worker-multi.js)
self.onmessage = function(e) {
const { startRow, endRow, cols } = e.data;
class FastQueue {
constructor() { this.data = []; this.head = 0; }
enqueue(v) { this.data.push(v); }
dequeue() { if (this.head >= this.data.length) return undefined; return this.data[this.head++]; }
size() { return this.data.length - this.head; }
compact() { if (this.head > 10000) { this.data = this.data.slice(this.head); this.head = 0; } }
}
let q = new FastQueue();
for (let i = startRow; i < endRow; i++) {
let row = Array.from({length: cols}, (_, j) => j);
q.enqueue(row);
}
const chunk = 10;
let processed = 0;
let sum = 0;
function processChunk() {
let chunkCount = 0;
while (chunkCount < chunk && q.size() > 0) {
let row = q.dequeue();
let newRow = [];
for (let val of row) {
if (val % 2 === 0) {
val = val * 2;
sum += val;
newRow.push(val);
}
}
if (newRow.length > 0) q.enqueue(newRow);
chunkCount++;
}
processed += chunk;
self.postMessage({ progress: Math.min(100, Math.floor((processed / (endRow - startRow)) * 100)), sum });
if (processed < (endRow - startRow)) {
setTimeout(processChunk, 0);
} else {
self.postMessage({ done: true, sum, remaining: q.size() });
}
}
processChunk();
};
JavaScriptポイント解説
- Worker を複数使い CPU を分散
- 1つの Worker に処理を分割 → CPU コアを有効活用
- 巨大多次元配列でもフリーズなし
- 各 Worker 内でチャンク処理
- 一度に全データを処理せず、UI や通信に影響を与えない
- 進捗集計
- メインスレッドで各 Worker の進捗を統合
- 合計をリアルタイム表示
- メモリ効率
- Worker 内は行単位で操作
- shift/unshift せず
FastQueueを活用
- 条件付き削除+変換+集計を同時処理
- filter/map/sum をまとめて処理
- 中間配列を最小化して高速化
💡 応用例
- 巨大データをブラウザ上でリアルタイムに安全に処理
- 並列処理で大規模統計やシミュレーションを実行
- データ解析やゲームエンジンなど、CPU 集約タスクに最適
この仕組みを応用すると、数千万件レベルの多次元データもブラウザで効率的に処理可能 になります。


