JavaScript | 大きな配列を扱うときのパフォーマンス面

JavaScript JavaScript
スポンサーリンク

では次に、自動スケーリング Worker で処理したデータの進捗や統計結果をリアルタイムグラフで可視化する完全デモ を作ります。
ブラウザ上で UI はフリーズせず、グラフで処理状況と集計を確認できます。


例:リアルタイムグラフ付き自動スケーリング 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: #2196F3;
    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 初期化
const ctx = document.getElementById('progressChart').getContext('2d');
const chart = new Chart(ctx, {
  type: 'line',
  data: {
    labels: [],
    datasets: [{
      label: '集計合計の推移',
      data: [],
      borderColor: 'rgb(33, 150, 243)',
      backgroundColor: 'rgba(33, 150, 243, 0.2)',
      fill: true
    }]
  },
  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 });
}

// Worker 作成関数
function startWorker(task) {
  const worker = new Worker('worker-multi.js');
  activeWorkers++;
  let step = 0;

  worker.onmessage = function(e) {
    const data = e.data;
    if (data.progress !== undefined) {
      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}`;

      // グラフ更新
      step++;
      chart.data.labels.push(step);
      chart.data.datasets[0].data.push(sumTotal + data.sum);
      chart.update('none'); // アニメなしで高速更新
    }
    if (data.done) {
      sumTotal += data.sum;
      activeWorkers--;
      if (taskQueue.length > 0) {
        startWorker(taskQueue.shift());
      } 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());
}
</script>
</body>
</html>
HTML

2️⃣ Worker ファイル(worker-multi.js)

前回と同じ Worker を使えます:

  • チャンク処理+条件付き削除+変換+集計
  • postMessage で進捗と完了を通知
  • 自動スケーリングのタスク割り当てに対応

ポイント解説

  1. リアルタイムグラフで進捗可視化
    • Chart.js で集計合計の推移を表示
    • UI はフリーズせずに滑らか更新
  2. 自動スケーリング Worker
    • 空き Worker があれば次のタスクを割り当てる
    • CPU コアを最大限活用
  3. チャンク処理+Worker 分散
    • 巨大多次元配列でも安定
    • 条件付き削除+変換+集計を効率的に実行
  4. ブラウザ負荷軽減
    • animation: false + chart.update('none') でグラフ更新を高速化
    • UI は常に応答可能

💡 応用例

  • 巨大 CSV/スプレッドシート解析のリアルタイム可視化
  • Web ブラウザでの大規模統計やデータ加工の進捗管理
  • シミュレーションやゲームの処理状況をグラフで確認

このデモを応用すれば、数千万件レベルの多次元データもブラウザ上で高速かつリアルタイムに処理・可視化 できます。

タイトルとURLをコピーしました