Web Workerとは
ウェブアプリケーションにおけるスクリプトの処理をメインとは別のスレッドに移し、バックグラウンドでの実行を可能にする仕組み。Webページ内でバックグラウンドスレッドを実行するためのJavaScriptの機能です。
特徴
マルチスレッド処理 : メインスレッドとは異なる独立したスレッドで実行されるため、メインスレッドのブロックを防止し、アプリケーションのレスポンス性を向上させることができます。
高速な処理 : より高速な処理ができます。例えば、複雑なアルゴリズムや大量のデータを処理する場合、Web Workerを使用することで処理速度を向上させることができます。
大量のデータの処理 : 大量のデータを同時に処理することができます。例えば、画像の処理やビデオの変換など、メインスレッドで処理すると処理速度が遅くなる場合でも、Web Workerを使用することで効率的に処理できます。
リアルタイムなデータ処理 :リアルタイムでデータを処理することができます。例えば、ユーザーがデータを入力したときにそのデータをすぐに処理することができます。
モジュール化 : スレッドごとに独立して実行されるため、モジュール化されたコードを実行することができます。なのでアプリケーションの構造が明確になり、保守性を向上させることができます。
一言でいうと「よりスムーズなユーザー体験を提供することができます」
ServiceWorkerとは
Workerの一種で、Webページとは別にバックグラウンドで実行するスクリプトです。ブラウザーとサーバーとの通信に介在しプロキシサーバーのように振る舞います。 これにより通信のリクエストやレスポンスに手を加えることができたり、オフライン時にキャッシュしておいた内容を返したりすることができます。
※プロキシサーバ:インターネットへのアクセスを代理で行うサーバー。通常はパソコンなどのブラウザを経由して直接Webサイトへアクセスし、サーバーがデータをブラウザに返すことで画面にWebサイトが表示されますが、プロキシサーバーを使用すると、ブラウザで直接Webサイトにアクセスせずに、プロキシサーバーにアクセス、プロキシサーバーが代わりに目的のサイトにアクセスしてデータを受け取り、ブラウザにデータを渡して表示できます。ローカルというわけではないです。
用途としては、キャッシュ・アセットの制御、プッシュ通知、オフライン対応、PWA対応などです。
対応ブラウザの確認
全体の96%は対応できるようです(2023/4/8)。また、Service Worker によるキャッシュ機能はウェブページそのものとは切り離されているため、非対応ブラウザで実行しても、単純に Service Worker 部が動作しないだけで、ページ自体には問題が発生しにくいという特徴があるようで、実装によってはあまり気にせず既存アプリケーションに組み込める可能性もあると思います。
なお、Service Workerはセキュリティのため、HTTPSかlocalhost(開発時)でしか利用できないようで、開発時にipアドレスやドメイン名をつけている場合は注意が必要です。
使用例
以下、Service Workerを使用してWebページのリソースのキャッシュを管理し、オフライン時にキャッシュを使用してリソースを提供する記述です。
// バージョンの定義
const CacheName = 'Cache:v1'
// Service Workerのinstallイベントでキャッシュのバージョンをログ出力する
self.addEventListener('install', (event) => {
console.log('ServiceWorker install:', event)
})
// ネットワークからリソースを取得できない場合はキャッシュから取得する関数
const networkFallingBackToCache = async (request) => {
const cache = await caches.open(CacheName)
try {
const response = await fetch(request)
await cache.put(request, response.clone()) // リソースをキャッシュに保存
return response // ネットワークから取得したリソースを返す
} catch (err) {
console.error(err)
return cache.match(request) // キャッシュからリソースを取得して返す
}
}
// Service Workerのfetchイベントで、リソースの取得処理を行う
self.addEventListener('fetch', (event) => {
// ネットワークから取得できなかった場合はキャッシュから取得する処理を行い、リソースを返すようにする
event.respondWith(networkFallingBackToCache(event.request))
})
イベント
今回はinstallイベント
を使用しています。これはService Worker がインストールされた際に一度だけ発生し、キャッシュの追加や、インストールが正常に完了したかの確認など、初期化処理を行います。これによって、Service Worker が起動した際にすぐに動作を開始できるようになります。
install以外の主なイベントは以下です。
fetch
: リソースが要求されたとき
activate
: Service Worker が有効化されたとき
message
: 別のスクリプトからメッセージが受信されたとき
メソッド
self.addEventListener()
は、Service Worker 内でイベントリスナーを登録するためのメソッドです。これにより、Service Worker が制御する範囲内で発生したイベントに対して、特定の処理を実行することができます。
他のメソッドは...
self.registration.unregister()
: Service Worker をアンインストールします。キャッシュされたリソースが削除され、Service Worker のコードがブラウザから削除されます。
self.registration.update()
: 、Service Worker を更新します。Service Worker を更新する際には、新しいコードを含むファイルを配信し、新しい Service Worker をインストールする必要があります。このメソッドを呼び出すことで、ブラウザは新しい Service Worker をダウンロードし、インストールとアクティブ化を行います。
self.registration.showNotification()
: ブラウザ上にプッシュ通知を表示します。このメソッドを呼び出すことで、ブラウザが通知を作成し、ユーザーに通知できます。
以上です。他にも、並列処理の概念など、使いながら理解を深めていく次第です。