では次のステップとして、Worker ごとの個別統計やエラー検知もリアルタイムグラフ化するプロ仕様拡張版 を作ります。
これにより、各 Worker の進捗、処理合計、エラー発生状況などを個別に可視化できます。
例:Worker 個別統計+エラー検知+リアルタイムグラフ
1️⃣ HTML(UI + Chart.js)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Worker 個別統計+エラー検知デモ</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
#progress { width: 100%; background-color: #eee; border-radius: 5px; overflow: hidden; margin: 10px 0; }
#bar { height: 20px; background-color: #FF5722; width: 0%; }
#status { font-family: monospace; }
#chart-container { width: 100%; max-width: 800px; }
</style>
</head>
<body>
<h1>Worker 個別統計+エラー検知デモ</h1>
<div id="progress"><div id="bar"></div></div>
<p id="status">準備中...</p>
<div id="chart-container">
<canvas id="progressChart"></canvas>
</div>
<script>
const maxWorkers = navigator.hardwareConcurrency || 4;
let workers = [];
let taskQueue = [];
let activeWorkers = 0;
let sumTotal = 0;
const rows = 1000, cols = 1000;
// Chart.js 初期化(Worker 個別データを色分け)
const ctx = document.getElementById('progressChart').getContext('2d');
const datasets = [];
for (let i = 0; i < maxWorkers; i++) {
datasets.push({
label: `Worker ${i+1}`,
data: [],
borderColor: `hsl(${i*360/maxWorkers},70%,50%)`,
backgroundColor: `hsla(${i*360/maxWorkers},70%,50%,0.2)`,
fill: true
});
}
const chart = new Chart(ctx, {
type: 'line',
data: { labels: [], datasets },
options: { animation: false, scales: { x: { title: { display: true, text: 'ステップ' } }, y: { title: { display: true, text: '合計' } } } }
});
// タスク分割
for (let i = 0; i < rows; i += 50) {
taskQueue.push({ startRow: i, endRow: Math.min(i + 50, rows), cols });
}
function startWorker(task, workerIndex) {
const worker = new Worker('worker-multi-error.js');
activeWorkers++;
let step = 0;
worker.onmessage = function(e) {
const data = e.data;
if (data.progress !== undefined) {
// グラフ更新
step++;
chart.data.labels.push(step);
chart.data.datasets[workerIndex].data.push(data.sum);
chart.update('none');
const percent = Math.min(100, Math.floor((sumTotal + data.sum) / (rows * cols * 1.0) * 100));
document.getElementById('bar').style.width = percent + '%';
document.getElementById('status').textContent =
`処理中... ${percent}% 合計=${sumTotal + data.sum}${data.error ? ' ⚠エラー発生!' : ''}`;
}
if (data.done) {
sumTotal += data.sum;
activeWorkers--;
if (taskQueue.length > 0) {
startWorker(taskQueue.shift(), workerIndex); // 次タスク割当
} else if (activeWorkers === 0) {
document.getElementById('status').textContent =
`完了! 合計 = ${sumTotal}`;
document.getElementById('bar').style.width = '100%';
}
}
};
worker.postMessage(task);
workers.push(worker);
}
// 初期 Worker を最大数まで起動
for (let i = 0; i < Math.min(maxWorkers, taskQueue.length); i++) {
startWorker(taskQueue.shift(), i);
}
</script>
</body>
</html>
HTML2️⃣ Worker ファイル(worker-multi-error.js)
// worker-multi-error.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(){return this.head>=this.data.length?undefined: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 = [];
let error = false;
for (let val of row) {
// 任意のエラー条件(例: 999 は異常値と仮定)
if (val === 999) { error = true; continue; }
if (val % 2 === 0) { 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, error });
if (processed < (endRow - startRow)) {
setTimeout(processChunk, 0);
} else {
self.postMessage({ done: true, sum, remaining: q.size() });
}
}
processChunk();
};
JavaScriptポイント解説
- Worker 個別グラフ
- Chart.js で各 Worker の合計推移を色分け表示
- タスクごとの処理状況をリアルタイムで確認
- エラー検知
- Worker 内で任意の異常値を検知
- メインスレッドに
errorフラグ付きで通知 - UI に ⚠マークで表示
- 自動スケーリング + リアルタイム統計
- タスク完了後に次タスクを自動割当
- Worker 数や処理量に応じて柔軟に負荷分散
- ブラウザ負荷軽減
- チャンク処理 + 非同期
setTimeout - グラフ更新は高速化設定(
animation:false+update('none'))
- チャンク処理 + 非同期
💡 応用例
- 巨大スプレッドシートの個別 Worker ごとの進捗監視
- Web アプリでの大規模データ解析+リアルタイムエラー検知
- 大規模シミュレーションやゲーム処理の状況監視
この構成を応用すると、ブラウザ上で CPU 複数コアをフル活用しつつ、個別 Worker の統計とエラーまでリアルタイム可視化できる本格プロ仕様のデータ処理プラットフォーム が実現可能です。
さらなる拡張案
- Worker 個別統計の高度可視化
- 処理時間、タスク完了率、エラー率を複合グラフで表示
- グラフを折れ線+棒グラフ+色分けで Worker ごとに可視化
- ダイナミック Worker スケーリング
- 負荷に応じて Worker 数を増減
- 低負荷時は Worker を停止、高負荷時に自動追加
- リアルタイムフィルタ&集計
- Worker から送られる集計結果をブラウザでフィルタ
- 条件付き集計(例:特定値以上の合計だけ集計)を即時表示
- UI 操作によるタスク制御
- タスクの一時停止、再開、キャンセル
- 特定 Worker の処理優先度変更
- エラー解析・通知
- エラー発生 Worker をハイライト
- 詳細ログをリアルタイム表示、メールや通知に連携可能
まとめ
- 巨大多次元データをブラウザ上で安全に処理
- 自動スケーリング Worker で CPU コアを最大活用
- Worker 個別統計・エラー検知をリアルタイム可視化
- UI は常に応答可能で、進捗・統計・エラーを即座に把握


