📗
JavaScriptのWorker
■ はじめに
Social Databank Advent Calendar 2024 の 24 日目です。
こんにちは。エンジニアの西崎です。
今回は JavaScript の Worker について調べたので、記事にまとめていきたいと思います。
■ まずは
JavaScript はシングルスレッド
- 記述された順番に処理を行う(前の処理が終わってから次の処理を行う)処理方式
- 途中に単一で重い処理が入ってくると、その処理中他の処理は実行されない
- 非同期処理で一部の処理を後回しにするなど工夫できるケースもあるが、単一で重い処理の場合、非同期処理は役に立たない
同期処理と非同期処理
- 同期処理
- コードを順番に処理していき、ひとつの処理が終わるまで次の処理は行わない
- 同期処理では実行している処理はひとつだけ
- JavaScript はこれ
- 非同期処理
- 非同期処理はコードを順番に処理していくが、ひとつの非同期処理が終わるのを待たずに次の処理を行なう
- 同時に実行している処理が複数ある
並行処理と並列処理
-
並行処理
- ある 1 つの時点では 1 つの処理しかしていないが、複数の処理間を切り替えることによって、同時にやっているように見える
- 非同期処理はこれ
-
並列処理
- ある 1 つの時点で実際に、物理的に、複数の処理をしていること。
- 複数の動作を同時に実行できる
非同期処理とは並列処理のことではない
- 非同期処理は並列処理ではなく、実行を順不同で行う並行処理にあたる
- 非同期処理を使って一部処理を後回しにするなど、処理を分散させることで負荷の軽減はできるが、単体で重い処理の場合は、後回しにしたところでブラウザがフリーズしてしまうなどの問題が発生してしまう可能性がある
■ じゃあどうするのか
Web Worker を使う
Web Worker とは、ウェブアプリケーションにおけるスクリプトの処理をメインとは別のスレッドに移し、バックグラウンドでの実行を可能にする仕組みのことです。時間のかかる処理を別のスレッドに移すことが出来るため、 UI を担当するメインスレッドの処理を中断・遅延させずに実行できるという利点があります。
Web Workers API - Web API | MDN
■ 実際に使ってみる
Worker の作成
const worker = new Worker("worker.js");
メッセージを送信する場合
worker.postMessage({ data: "メインスレッドからデータを送信" });
メッセージを受信する場合
worker.onmessage = (e) => {
const { data } = e;
if (!data) return;
console.log(data);
}
// もしくはこう
self.addEventListener("message", (e) => {
const { data } = e;
if (!data) return;
console.log(data);
});
Worker を終了したい場合
worker.terminate();
// あるいはWorker側でcloseメソッドを呼び出す
self.close();
注意点
- Worker の中では DOM オブジェクトや window オブジェクトは利用できない
- 受け取った値に応じて DOM の操作などを行う際は一度メインの処理に値を返して行なう
- その他利用できる関数や API など
■ まとめ
- 非同期処理 = 並列処理 ではない
- 並列処理を行いたい場合は Web Worker を使ってみよう
Discussion