複雑なService Workerを作る際にはimportScriptsを使おう
Service WorkerはWebブラウザ側で実行されるJavaScript(メインスレッド)とは別で実行されます。バックグラウンド処理に使うこともできますし、メインスレッドで行うと画面が固まってしまうような重たい処理を実行させることもできます。
そんなService Workerを活用していく中で、処理が肥大化していくならば別ファイルとして切り出していきましょう。その際に使えるのがimportScriptsです。
importScriptsの使い方
例えばメインスレッド側のJavaScriptでは次のように処理を書きます。
if ('serviceWorker' in navigator) { | |
navigator.serviceWorker.register('/sw.js').then(function(registration) { | |
// Service Worker登録完了 | |
}, /*catch*/ function(error) { | |
// Service Worker登録失敗 | |
}); | |
} else { | |
// Service Workerをサポートしていない | |
} |
そしてService Worker(sw.js)を以下のように記述します。
importScripts('import.js'); | |
func(); |
self.importScripts
という書き方もありますが、どちらも同じ意味です。 import.js
は以下のように記述します。
const func = () => { | |
console.log('Output from import.js'); | |
} |
こうすることで、外部ファイルを読み込んでService Workerの中で利用できます。なお、複数ファイルの読み込みも可能です。
importScripts('import.js', 'other.js'); |
読み込みは同期処理
コードを見て分かる通り、importScripts
は同期処理で実行されます。読み込み完了時のコールバックもなく、返り値がPromiseな訳でもありません。さらに言えば、インポートされるファイルで最後に return
を書いたり、module
や export
は使えません。
読み込まれるファイルの特徴
インポートされるファイルは元ファイルと同じく self
が使えます。これは ServiceWorkerGlobalScope
であり、IndexedDB も利用可能です。また、インポートされるファイルを編集しても、元になるService Workerファイルが更新されていないとWebブラウザは更新してくれませんので注意してください。
importScriptsを使うことで、メインスレッドとワーカースレッドで同じライブラリを活用できるようになるでしょう。特に重たい計算処理の伴うようなものについては、ワーカースレッドで計算して結果だけメインスレッドで受け取って描画するといった使い分けもできそうです。
コメントは受け付けていません。