WebワーカーコードをHTMLに埋め込むhtml5rocksソリューションは、かなり恐ろしいものです。
また、エスケープされたJavaScript-as-a-stringのblobは、ワークフローを複雑にするため、特に良くありません(Closureコンパイラーは文字列を操作できません)。
個人的にはtoStringメソッドが本当に好きですが、@ dan-man正規表現です!
私の好ましいアプローチ:
// Build a worker from an anonymous function body
var blobURL = URL.createObjectURL( new Blob([ '(',
function(){
//Long-running work here
}.toString(),
')()' ], { type: 'application/javascript' } ) ),
worker = new Worker( blobURL );
// Won't be needing this anymore
URL.revokeObjectURL( blobURL );
サポートは、次の3つのテーブルの共通部分です。
ただし、これはSharedWorkerでは機能しません。オプションの 'name'パラメーターが一致しても、URLは完全に一致する必要があるためです。SharedWorkerの場合、別個のJavaScriptファイルが必要です。
2015年の更新-ServiceWorkerの特異点が到着しました
この問題を解決するさらに強力な方法があります。ここでも、ワーカーコードを(静的文字列ではなく)関数として保存し、.toString()を使用して変換してから、選択した静的URLの下のCacheStorageにコードを挿入します。
// Post code from window to ServiceWorker...
navigator.serviceWorker.controller.postMessage(
[ '/my_workers/worker1.js', '(' + workerFunction1.toString() + ')()' ]
);
// Insert via ServiceWorker.onmessage. Or directly once window.caches is exposed
caches.open( 'myCache' ).then( function( cache )
{
cache.put( '/my_workers/worker1.js',
new Response( workerScript, { headers: {'content-type':'application/javascript'}})
);
});
2つのフォールバックが考えられます。上記のObjectURL、またはよりシームレスに、実際の / my_workers / worker1.jsに JavaScriptファイルを配置します
このアプローチの利点は次のとおりです。
- SharedWorkersもサポートできます。
- タブは、固定アドレスで単一のキャッシュされたコピーを共有できます。blobアプローチは、すべてのタブに対してランダムなオブジェクトURLを増殖させます。