WebワーカーコードをHTMLに埋め込むhtml5rocksソリューションはかなり恐ろしいものです。
そして、エスケープされたJavaScript-as-a-stringのブロブは、特にワークフローを複雑にするため、良くありません(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つのテーブルの共通部分です。
ただし、オプションの「name」パラメーターが一致する場合でも、URLは完全に一致する必要があるため、これはSharedWorkerでは機能しません。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、またはよりシームレスに、実際のJavaScriptファイルを/my_workers/worker1.jsに配置します
このアプローチの利点は次のとおりです。
- SharedWorkersもサポートできます。
- タブは、固定アドレスで単一のキャッシュされたコピーを共有できます。blobアプローチでは、タブごとにランダムなobjectURLが急増します。