B3S
menu close

Javascript

複数タブでポーリングする方法


はち

公開日:2021/10/27


皆様こんにちはゴスケです。
最近、社内システムで「新着情報をポーリングする処理」の実装機会がありました。
なんも考えずsetTimeout()で新着情報を取得するAPIをコールしていたのですが、開いているタブの数だけリクエストが飛んでいることに気が付きました。

これはよろしくない。
できればリクエストを1つにまとめて、取得した情報を各タブに通知する仕組みを実装したいところです。
今回はその仕組を「SharedWorker + BroadcastChannel」を使用して実装してみたので紹介します。
(フロントエンドはReactを使っています。)

参考にさせていただいた記事はこちらです。
https://qiita.com/okumurakengo/items/0273d80628e021537cbc

SharedWorkerを使って複数タブのリクエストを1つにまとめる

SharedWorkerの使い方は以下の通り。
コンストラクタの引数に実行したいスクリプトを指定します。
その後start() を実行することで、SharedWorkerが使用できます。

続いてSharedWorkerで実行するスクリプトの実装です。
ここでは「ポーリングで新着情報を取得するAPIをコール」という処理を実装します。
今回は簡易的にするために単純なカウントアップを繰り返すだけにしています。

SharedWorker内で実行されるconsole.log()は「chrome://inspect/#workers」で確認できます。

BroadcastChannelで各タブに通知する

次にSharedWorker内でカウントアップされた数値をフロントエンドに通知する方法です。
こちらはBroadcastChannelを使用します。

まずはアプリケーション側の変更。
コンストラクタにチャンネル名を指定し、このチャンネル宛に送信されたメッセージを購読できるようになります。
今回は「shared」という名前にしています。

続いて、SharedWorkerの変更。
カウントアップした内容を「shared」に送信することで、「shared」を購読しているフロントエンドに通知されます。

最後に

今回はSharedWorker + BroadcastChannnelで、複数タブでのポーリングを実現してみました。
WebWorkerは全然使ったことがなかったので、良い経験になりました!