今回は個人的に気になっていた技術である、
JavaScriptのWeb Worker
について調べてみました。
Web Workerとは
Web Workerとは一体何でしょうか。
MDNには下記のように記載されていました。
ウェブワーカーは、ウェブコンテンツがスクリプトをバックグラウンドのスレッドで実行するためのシンプルな手段です。ワーカースレッドは、ユーザーインターフェイスを妨げることなくタスクを実行できます。さらに、fetch() や XMLHttpRequest など API を用いて、ネットワークリクエストを行うことができます。ワーカーが生成されると、それを作成した JavaScript コードが指定するイベントハンドラーにメッセージを投稿することで、そのコードにメッセージを送ることができます(逆も同様)。
なるほど。
バックグラウンドでタスクを実行できるのですね。
JavaScriptはシングルスレッドのプログラミング言語のため、
スクリプトやイベントハンドラが実行している間、
ブラウザはユーザーの入力に対して応答できません。
Web Worker
を使用することで、
ユーザーインターフェースを停止させずに済むのです。
では実際の実装例を見てみましょう。
実装例
どのように使用するのかみていきましょう。
数値カウント
下記の例では worker.js
にデータを送り、
それを用いた計算後の値を main.js
に送っています。
self.onmessage = function(event) {
const { countTo } = event.data;
let sum = 0;
for (let i = 1; i <= countTo; i++) {
sum += i;
}
// メインスレッドに結果を送信
self.postMessage(sum);
};
// Workerを作成
const worker = new Worker('worker.js');
// Workerにデータを送信
worker.postMessage({ countTo: 100000000 }); // 1から100,000,000までの合計を計算
// Workerから結果を受け取る
worker.onmessage = function(event) {
console.log('合計値:', event.data); // 合計値: 5000000050000000
};
// エラーハンドリング
worker.onerror = function(error) {
console.error('エラー:', error.message);
};
配列のフィルタリング
下記では偶数のみのリストを作成して出力します。
self.onmessage = function(event) {
const numbers = event.data;
// 偶数だけをフィルタリング
const evenNumbers = numbers.filter((num) => num % 2 === 0);
// メインスレッドに結果を送信
self.postMessage(evenNumbers);
};
const worker = new Worker('worker.js');
// 大量のデータを用意
const largeArray = Array.from({ length: 10000000 }, (_, i) => i);
// Workerにデータを送信
worker.postMessage(largeArray);
// 結果を受け取る
worker.onmessage = function(event) {
console.log('偶数リスト:', event.data); // リスト表示
};
// エラーハンドリング
worker.onerror = function(error) {
console.error('エラー:', error.message);
};
Web Workerの特徴
Web Workerには下記のような特徴があります。
独立性
ワーカースレッドで実行されるコードは、ドキュメントのコンテンツにアクセスできません。
また、メインスレッドや他のワーカースレッドと状態を共有することもできません。
非同期通信
メインスレッドや他のワーカースレッドとの通信は非同期のイベントが使用されます。
値の複製
postMessage()
で渡される値は複製のため、受信先で値を変更しても元の値は変わりません。
おわりに
Web Workerを使用することでマルチスレッド処理を実現し、
重たい処理でも高速に実行することができました。
いくつかの制限や使用方法に注意が必要ですが、
非常に役立つ技術だなと思いました。
今回は簡単な概要をさらいましたが、
またの機会により詳しく深堀りしたいなと思います。
それでは。
参考文献