JavaScriptのWeb Workers APIを「社長」と「従業員」の例で説明する〜メインファイルとWorkerファイルの関係について
目次
先日、「WordPress + AMP(Accelerated Mobile Pages) + PWA(プログレッシブ ウェブアプリ)でWordPressサイトの高速化について考えてみた(新しいタブで開く)」という記事を書きました。
このうちPWA(プログレッシブ ウェブアプリ)を理解しようと思うと、Service Workerについての理解が必要なようです。
PWAを知りたければWeb Workersの理解が必要
ただそのService Workerを理解するためには、さらに1つ上の概念であるWeb Workers APIの概念を理解しなければなリません。イメージ的にはこんな感じでしょう。
「PWAを知りたい」 → 「Service Workerを理解しなさい」 → 「Web Workers APIを理解しなさい」
物事を知りたければ、その根本までたどって行かなければならないということのお手本のようですね。
並列処理のWeb Workersを例えで説明
そこでWeb Workerのことを自分で調べました。Web Workerをあえて一言で表すと並列処理のことですね。HTML5 Rocksというサイトに「ウェブワーカーの基本(新しいタブで開く)」というページがあります。そのページにもとづき、たとえ話でWeb Workerについて簡単に説明します。
シングルスレッドモデルのJavaScript
クライアントサイドのJavaScriptはシングルスレッドモデルを採用していますが、このモデルであると1つの命令(リクエスト)に対して、1つの処理(レスポンス)しかできません。
スマホ全盛期にシングルスレッドモデルは不可
インターネットに接続する人PCユーザーしかいないという、昔のようなのどかな時代であればシングルスレッドモデルでも、「命令→処理」が滞りなく済んだかもしれません。
ですが世はまさにスマホ全盛期。あっちこっちから膨大な数のリクエストが飛んできている状態で、「1番目の処理をしてるからちょっと待ってね」なんて50番目の人に向かっていったらすさまじい数の苦情が飛んでくるでしょう。
そこでなんとか10番目の人でも50番目の人でも「とりあえず対応する何らか」が必要です。その「何らか」が、Web Workerです。”Worker”という言葉は、雇用主にしたがって働くというイメージにぴったり合いますね。
“Worker”とメッセージ
“Worker”は雇用主にしたがって働かなければなりません。社長に対して指示を受け取って作業を行います。また従業員の方でも作業内容を社長に報告する必要があります。言い換えると”Worker”は従業員で、社長の指示にもとづいて一緒に作業をしているという感じでしょう。
ちなみに”Worker”が従業員が社長と一緒に作業をする(並列処理をする)という点では、Web WorkerもService Workerも同じです。
コードで理解するWeb Worker
と、ここまでWeb Workerについて簡単な説明をしました。ただし言葉だけで説明してもいまいち説得力がありません。具体的にJavaScriptのコードを用いて説明しましょう。サンプルコードは上述した「ウェブワーカーの基本」から引用します。
Workerオブジェクトの作成
社長はまず従業員と作業することを宣言しなければなりません。このことをJavaScriptのコードで表すとメインのindex.htmlに以下の記述することになります。
var worker = new Worker("worker.js");
Web Workers APIのWorkerオブジェクトを新しく定義して、引数をworker.jsとします。worker.jsは従業員にとっての職務記述書と言えるでしょう(GitHub(新しいタブで開く))。
postMessage()メソッドで作業開始の連絡
worker.postMessage('Hello World');
次に社長は決めた作業内容(worker.js)を始めるよう従業員に伝えなければなりません。その伝言の役割を果たすのが、index.htmlに記述されているpostMessage()メソッドです。postMessage()メソッドの引数を”Hello World”の文字列としています(GitHub(新しいタブで開く))。
Workerファイルがメッセージを受け取る
self.addEventListener('message', function(e) { self.postMessage(e.data); }, false);
従業員はあらかじめ社長から受け取った伝言を報告するようにworker.jsで定義されています。報告する内容はworker.jsで定義されているpostMessageメソッドの引数である”e.data”です(GitHub(新しいタブで開く))。
メインファイルで報告内容を表示
worker.addEventListener('message', function(e) { console.log('Worker said: ', e.data); }, false);
社長は従業員から受け取った報告である”e.data”をindex.htmlのコンソールに表示します。社長があらかじめ従業員に指示した内容は、”Hello World”を復唱することです(GitHub(新しいタブで開く))。
以上のプログラミング動作を社長と従業員の仕事関係で簡表すとこんな感じになります。ちなみにworker.jsで使っているselfキーワードは省略することも可能です(GitHub(新しいタブで開く))。
今回のプログラミングを実行すると、ブラウザの表示とコンソール画面はこんな感じになります。自分でも動かしてみたいと思った方は、GitHubのサンプルコード(新しいタブで開く)を参考にしてください。