1. 導入:なぜWeb Workerが必要なのか
Webページで複雑な計算や大量のデータ処理を行うとき、画面がフリーズして操作を受け付けなくなることはありませんか?これはJavaScriptが「シングルスレッド」という仕組みで動いており、ひとつの処理が終わるまで他の処理(画面描画など)が待たされるためです。ここで登場するのが「Web Worker」です。Workerを使うと、メインの処理とは別に「裏側で動くスレッド」を作成でき、画面をサクサク保ったまま重い処理を実行できるようになります。
2. 基礎知識:postMessageとは何か
Web Workerは、メインのJavaScriptファイルとは完全に独立した環境で動きます。そのため、直接変数や関数を共有することができません。そこで情報の受け渡しに使われるのが「postMessage」というメソッドです。
postMessageは、メインスレッドとWorkerスレッドの間でメッセージ(データ)を送るための郵便ポストのような役割を果たします。送ったデータは、受け取り側で「onmessage」というイベントを通じて取得できます。
3. 実装/解決策:やり取りの基本手順
実装には「メインファイル(main.js)」と「Workerファイル(worker.js)」の2つが必要です。
1. メインから Worker を生成する(new Worker)。
2. postMessageでデータを送る。
3. Worker側でonmessageを使ってデータを受け取り、処理を行う。
4. 処理結果をpostMessageでメインに返す。
4. サンプルプログラム
以下のコードをコピーして試してみてください。
[main.js]
// Web Workerを生成
const worker = new Worker(‘worker.js’);
// Workerから送られてきたデータを受け取る
worker.onmessage = (event) => {
console.log(‘Workerからの返信:’, event.data);
};
// Workerにデータを送る
worker.postMessage(100);
[worker.js]
// メインからのデータを受け取る
self.onmessage = (event) => {
const number = event.data;
// 重い処理を想定した計算
const result = number 2;
// メインスレッドに結果を返す
self.postMessage(‘計算結果は: ‘ + result);
};
5. 応用・注意点:現場で役立つポイント
注意点1:DOMは操作できない
Workerの中では「window」や「document」といったDOM操作に関連する機能は使えません。あくまで純粋な計算やデータ加工用です。
注意点2:データのコピーが発生する
postMessageで送るデータは「構造化複製(Structured Clone)」という仕組みでコピーされます。巨大なデータを送るとメモリを消費するため、数百万個の配列などを扱う場合は「転送可能オブジェクト(Transferable Objects)」という手法を使って、データをコピーではなく「移動」させる最適化を検討しましょう。
現場のテクニック
Workerは使い終わったら「worker.terminate()」を呼び出して終了させることで、ブラウザのリソースを効率的に解放できます。常に開きっぱなしにせず、必要なときだけ生成する習慣をつけましょう。