では次に、Web Worker を使ってプロ仕様サンプルを並列処理化し、UI を止めずに巨大多次元配列を高速に処理する例 を作ります。
例:Web Worker で多次元配列を並列処理(進捗バー+集計付き)
1️⃣ メイン HTML(UI + Worker 起動)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Web Worker 多次元配列処理デモ</title>
<style>
#progress {
width: 100%;
background-color: #eee;
border-radius: 5px;
overflow: hidden;
margin: 10px 0;
}
#bar {
height: 20px;
background-color: #3F51B5;
width: 0%;
}
#status { font-family: monospace; }
</style>
</head>
<body>
<h1>Web Worker 多次元配列処理デモ</h1>
<div id="progress"><div id="bar"></div></div>
<p id="status">準備中...</p>
<script>
if (window.Worker) {
const worker = new Worker('worker.js'); // 別ファイルに処理
worker.postMessage({ rows: 1000, cols: 1000 }); // データサイズを送信
worker.onmessage = function(e) {
const data = e.data;
if (data.progress !== undefined) {
document.getElementById('bar').style.width = data.progress + '%';
document.getElementById('status').textContent =
`処理中... ${data.progress}% 合計=${data.sum}`;
}
if (data.done) {
document.getElementById('status').textContent =
`完了! 集計合計 = ${data.sum}, 残り行数 = ${data.remaining}`;
document.getElementById('bar').style.width = '100%';
}
};
} else {
alert('このブラウザは Web Worker に対応していません。');
}
</script>
</body>
</html>
HTML2️⃣ Worker ファイル(worker.js)
// worker.js
self.onmessage = function(e) {
const { rows, 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 queueA = new FastQueue();
let queueB = new FastQueue();
for (let i = 0; i < rows; i++) {
let row = Array.from({length: cols}, (_, j) => j);
(i % 2 === 0 ? queueA : queueB).enqueue(row);
}
const chunk = 10;
let processed = 0;
let sum = 0;
function processChunk() {
let queues = [queueA, queueB];
for (let q of queues) {
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++;
}
q.compact();
}
processed += chunk * queues.length;
const percent = Math.min(100, Math.floor((processed / rows) * 100));
self.postMessage({ progress: percent, sum });
if (processed < rows) {
setTimeout(processChunk, 0);
} else {
self.postMessage({
done: true,
sum,
remaining: queueA.size() + queueB.size()
});
}
}
processChunk();
};
JavaScriptポイント解説
- UI と処理を完全に分離
- Worker 内で処理 → メインスレッドがフリーズしない
- UI は進捗バーやステータス更新に専念できる
- 巨大多次元配列も安全
- 条件付き削除、変換、集計を Worker 内でまとめて実行
- メインスレッドは負荷なし
- 進捗報告
postMessageで定期的に進捗を返す- チャンク処理 +
setTimeoutでフリーズ回避
- 複数キュー処理
- queueA / queueB に分けることで並列構造に近い管理
- 大規模データでも安定
💡 応用例
- 巨大スプレッドシートのブラウザ上での安全処理
- ゲームやシミュレーションの並列更新
- リアルタイム統計・加工の Web アプリ


