本稿では、JavaScriptのWeb Workerを手軽に試すために、Web Workerを動かすための最小限の手順とコードを示します。
使わないもの
最小限構成でいくので以下は使いません:
- コンパイラ: TypeScriptなどは使わず、素のJavaScriptで。
- バンドラー: webpackなどは使いません。
- フレームワークやライブラリ: ReactやNPMモジュールも一切なしでいきます。
コード量も最小限
- コードも過剰にならない範囲でシンプルにします。
- ファイル数もできるだけ少なく済ませます。
Web Workerとは
Web Workerは、雑に言うと、ブラウザ上でCPU負荷が大きい処理を動かすのに役立つ仕組みです。ワーカーの処理は、UI側の処理をブロックしないのが特徴です。ワーカーにはUIとは別のスレッドが割り当てられます。CPUを複数台積んでるパソコンなら、ワーカーはマルチコアを活用できる可能生があります。
詳しい説明はMDNなどを御覧ください。
Web Workerを動かす最小限の手順とコード
ワーカーを起動させてみよう
まず、index.htmlを作ります。
<!DOCTYPE html>
<meta charset="UTF-8" />
<script>
// ワーカーを起動するコード
const myWorker = new Worker("worker.js");
</script>
次に、worker.jsにワーカーの実装を書きます。
console.log("✅worker started!");
index.htmlからworker.jsを参照できるように、この2つのファイルは同じディレクトリに置きます。
.
├── index.html
└── worker.js
Google Chromeではfile://
プロトコルではWeb Workerを起動できないので、ローカルにHTTPサーバーを立ててHTTP越しにindex.htmlを開きます。index.htmlとworker.jsがGETできればHTTPサーバーは何でもいいのですが、http-serverが手軽なのでここではこれを使います。
# index.htmlがあるディレクトリでHTTPサーバーを起動する
npx http-server -c-1
http://127.0.0.1:8080
にアクセスします。Google ChromeのDev ToolsのConsoleを開いて、「worker started!」と表示されていれば、起動成功です。
ワーカーにメッセージを送ってみよう
親とワーカーの通信は、メッセージを介して行います。ワーカー側でメッセージを受け取るには、message
イベントを購読します。具体的には次のコードをworker.js
に追加します。
// メッセージイベントを購読する
self.addEventListener("message", (e) => {
// メッセージを受け取ったときに動かすコード
console.log("worker received a message", e);
});
ワーカーにメッセージを送るには、ワーカーオブジェクトのpostMessage
メソッドを使います。
<script>
// ワーカーを起動するコード
const myWorker = new Worker("worker.js");
// メッセージを送信する
myWorker.postMessage("hey");
</script>
コードを追記したら、ブラウザをリロードします。すると、コンソールに「worker received a message: hey」と表示されるはずです。
ワーカーからメッセージを受信してみよう
ワーカーからのメッセージを親が受信するには、ワーカーオブジェクトのmessage
イベントを購読します。
<script>
// ワーカーを起動するコード
const myWorker = new Worker("worker.js");
// ...中略...
// ワーカーからのメッセージを受信する
myWorker.addEventListener("message", (e) => {
console.log("parent received message:", e.data);
});
</script>
ワーカーからはself.postMessage
メソッドでメッセージを送信します。
console.log("✅worker started!");
// ...中略...
// 親にメッセージを送信する
self.postMessage("hello");
まとめ
- Web Workerは重い処理をバックグラウンドで動かすのに役立つ仕組み
- Web Workerの起動は
new Worker(ファイル名)
- 親とワーカーのコミュニケーションはメッセージの送受信
- 受信は
message
イベントを購読する - 送信は
postMessage
メソッドを呼ぶ
- 受信は