こんにちはフロントエンドエンジニアのまさにょんです!
今回は、JavaScriptで並列処理をする・別スレッドを呼び出す Web-Workerの使い方・マルチスレッド処理について解説していきます。
目次
Web Workerとは?
Web Workerとは、JavaScriptでバックグラウンドでのマルチスレッド処理(並列処理)を実行するための機能です。
詳細な説明は、MDNから引用します。
ウェブワーカー (Web Worker) とは、
ウェブアプリケーションにおけるスクリプトの処理をメインとは別のスレッドに移し、
バックグラウンドでの実行を可能にする仕組みのことです。
時間のかかる処理を別のスレッドに移すことが出来るため、
UI を担当するメインスレッドの処理を中断・遅延させずに実行できるという利点があります。
ワーカーオブジェクトはコンストラクター(
Worker()
など)を用いて生成され、名前を持つ JavaScript ファイルを実行します。
このファイルにはワーカースレッドで実行されるコードが書かれています。
ワーカースレッドの中では、 JavaScript の標準の一連の関数
(
String
、Array
、Object
、JSON
、など)に加え、任意のコードのほとんどを実行することができます。いくつかの例外があります。例えば、ワーカー内から直接 DOM を操作することはできません。
また、
window
オブジェクトの既定のメソッドやプロパティには使用できないものがあります。ワーカーとメインスレッドとの間では、メッセージのシステムを通してデータがやり取りされます。
両者は
postMessage()
メソッドを使ってメッセージを送信したり、受け取ったメッセージには
onmessage
イベントハンドラーで返信したりします。(メッセージは
メッセージ
イベントのdata
属性に格納されます)なお、データは共有(share)されるのではなく複製(copy)されます。
引用元: MDN: ウェブワーカー API
上記に記載のある通り、Web Workerは、メインスレッドとは別の独立したスレッドとしてJavaScriptを実行します。
JavaScriptの機能をほぼ使用することができますが、DOM操作やwindowオブジェクトなど一部の機能は使えません。
また、メインスレッドとWeb Worker(サブスレッド)のやり取りは、
postMessage()
でデータの送信、onmessage
イベントハンドラーで返信の処理を定義します。
ワーカーの内部スコープに、あらゆる JavaScript オブジェクトの形式のメッセージも送ることができます。
引用元: MDN: Worker
Worker message イベントは、postMessage()
でデータの送信が実行されたときに発火します。
Worker message イベント
message
イベントはWorker
オブジェクトで、ワーカーの親がワーカーからメッセージを受け取ったとき(すなわち、ワーカーが
DedicatedWorkerGlobalScope.postMessage()
を用いてメッセージを送信したとき)に発生します。構文
このイベント名を
addEventListener()
などのメソッドで使用するか、イベントハンドラープロパティを設定するかしてください。
addEventListener('message', (event) => { });
引用元: MDN: Worker: message イベント
onmessage = (event) => { };
Web Workerの使い方・マルチスレッド処理のサンプル
Web Workerは、JavaScriptでバックグラウンドでのマルチスレッド処理(並列処理)を実行するための機能です。
SampleCodeを実行して、動作を確認してみましょう。
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="./main.js"></script>
</head>
<body>
<h1 style="text-align: center">Web-Worker-Test🔥</h1>
<div style="text-align: center">
<input type="text" id="submitMsg" value="送信メッセージ" disabled="true">
<input type="text" id="msgInput" value="">
<input type="button" id="submitBtn" value="送信">
</div>
</body>
</html>
worker.js: Web Workerのスレッドファイル(並列処理をするJavaScript)
Web Workerは、独立スレッドで実行するので、個別ファイルに記述します。
onmessage
イベントハンドラーでメインスレッドからの呼び出しに対するレスポンス処理を定義できます。
Web Worker で処理した結果をpostMessage()
でメインスレッドに返却します。
// [ Web Worker によるバックグラウンド処理・並列処理を記述する ]
// 1. onmessage イベントハンドラーでメインスレッドからの呼び出しに対するイベント処理を定義
this.onmessage = (event) => {
// Parameter (引数)の取得
let params = event.data;
// ここで「バックグラウンド処理・並列処理」させたい重い処理を実行する
const response = `${params}なのだ!`;
// 2. Web-Worker で処理した結果を返す(Postする)
this.postMessage(response);
};
main.js: メインスレッドのJavaScriptファイル
メインスレッドでは、worker.js のPathを渡して Web Worker のインスタンスを作成します。
また、Web Workerによるバックグラウンド処理の結果のレスポンスを取得して、処理するイベントを登録しておきます。
あとは必要なタイミングでpostMessage()
を使って、Web-Worker にデータを送信して Worker側の onmessage
イベントを動かします。
document.addEventListener('DOMContentLoaded',() => {
// 送信ボタン
const button = document.getElementById('submitBtn');
console.log({button});
const msgInput = document.getElementById('msgInput');
console.log({msgInput});
// Clickイベント
button.onclick = () => {
let inputMsg = msgInput.value;
console.log({inputMsg});
if (inputMsg === '') {
window.alert('送信するメッセージを入力してください');
return;
}
// 1. Web-Worker のインスタンスを作成する
const worker = new Worker('./worker.js');
console.log({worker});
// 2. バックグラウンド処理の結果のレスポンスを取得して、処理するイベントを登録する
worker.onmessage = (event) => {
console.log('result: ', event.data);
window.alert(event.data);
}
// 3. Web-Worker にリクエストを送信する(Postする)
worker.postMessage(inputMsg);
};
});
Web Workerには、アクセスできない機能がある
Web Workerには、アクセスできない機能があります。
Web Workerの使い方 からアクセスできない機能の一覧を引用します。
Web Worker からアクセスできない機能
- DOM
- window
- document
- parent
JavaScript書籍 Ver. 中級-上級者向け
JavaScript書籍 Ver. 初級者向け
プログラミング学習・エンジニア転職関連の情報
自宅で現役エンジニアから学べる『TechAcademy』 (エンジニア転職保証)
『GEEK JOBキャンプ』スピード転職コース(無料)
【IT道場】入校時0円! 就職目的プログラミングスクール
エンジニア転職なら100%「自社開発」求人に強い【クラウドリンク】
『techgym』 (Python特化・無料)
参考・引用
Twitterやってます!Follow Me!
神聖グンマー帝国の逆襲🔥
神聖グンマー帝国の科学は、世界一ぃぃぃぃぃぃ!!!!!