この例ではheader.txtとfooter.txtをキャッシュに保存しています。caches.open()でキャッシュを開き、取得したcacheに対して、cache.addAll()を呼んでヘッダとフッタをサーバーから取ってきて保存しています。'text/html']]})));});次に、Fetchイベントハンドラで、先ほど保存したヘッダとフッタをキャッシュから取り出して、サーバーから取得したコンテンツと文字列連結します。APIで元のURLに”.txt”をつなげたURLにネットワークリクエストを投げています。それらすべてのレスポンスから、text()でコンテンツ本文を取得し、その後、joinで連結しています。これで目的通り、ヘッダとフッタを連結してページに返すことができるのですが、問題があります。先ほど書いたとおり、サーバーからのコンテンツ全体を取得完了するまでページに返せないのです。そこで、解決方法がStreamです。Streamを使えば、サーバーから取得したコンテンツを徐々にページに返していくことができます。'text/html']]}));});具体的にコードを見ていきましょう。Installイベントハンドラは先ほどと同じです。イベントハンドラは上のコードのようになります。ReadableStreamという新しいクラスが登場します。中身は下で説明しますが、ここでReadableStreamをつくって、それをResponseオブジェクトを作る際に渡し、respondWith()でレスポンスをページに返しています。controller.close());}});ReadableStreamの中身は、このようになります。start()というメソッドの中でまず、header.txtとfooter.txtのキャッシュからの読み込みと、サーバへのFetchリクエストのPromiseを作っています。下の方で、まず、ひとつ目のPromise、つまりHeader読み込みのPromiseからレスポンスを取得し、そのレスポンスボディをpushStream()という関数に渡しています。pushStream()ではbodyからreaderを取得して、順番に読んでいって、controller.enqueue()で詰め込んでいきます。それが終わったら2つ目のPromise、つまりFetchのPromiseからレスポンスを取得して、あとは同様にbodyの中身を徐々にenqueueしていきます。その後、3つ目のPromise、つまりfooter.txtのPromiseも同様です。最後に、controller.close()を呼んでStreamを閉じています。このようにすると、サーバーからのレスポンスを最後まで待たずに、徐々にページにデータを返していくことができます。Chromeは51まで、audioエレメントやvideoエレメントではAndroidのメディアスタックを利用していました。52からデスクトップ版Chromeと共通化されました。Audioに送信するといったことができるようになり、クロスデバイスの開発が容易になりました。詳細はこちらのURLを参照してください。Syncはどういうものかと言いますと、その名の通り、バックグラウンドでデータを送受信できる機能です。「オフライン時にメッセージを書いて、オンラインになったときに自動で送信」といったことができるようになります。AndroidだとChromeアプリを閉じていても動作します。いい動画がYouTubeにあったのでこちらをご覧ください。Workerを使ってオフラインでもWikipediaの記事を読むことができるというWebアプリのデモです。Syncを使ってオンラインになった時に自動で記事をダウンロードし、ダウンロードが完了したら先ほど紹介したNotificationのAPIで通知を表示しています。Fetchの説明をする前に通常のFetchイベントを復習します。Workerが登録されているとします。WorkerのFetchイベントハンドラで横取りすることができます。b.comのサイトのページからa.com上にある画像などのサブリソースへのリクエストはFetchイベントハンドラで横取りすることができません。Workerで横取りすることができるようになります。Fetchイベントまとめますとこうなります。「ネットワークリクエストを横取りする」という点は共通です。普通のFetchイベントは自分のサイトのページからのネットワークリクエストを横取りします。自分のサイトのHTMLページと、そこからの画像などのサブリソースリクエストも横取りできます。それに対してForeignFetchイベントでは、他のサイトから自分のサイトへのサブリソースのリクエストを横取りすることができるようになります。FontサーバやCDN等で活用できるのではと考えられます。以下へのリクエストを横取りしたい場合は、Installイベントハンドラで上のコードのようにregisterForeignFetch()というAPIを叩きます。scopesに横取りしたいリクエストの範囲、originsにリクエスト元のオリジンを指定します。すべてのオリジンからのリクエストを横取りしたい場合は、originsにアスタリスクを指定します。以下へのネットワークリクエストの度にForeignFetchイベントハンドラが実行されるようになります。res})必要があります。res}));});注意点として、このようにしてページに返したレスポンスはページではOpaqueになります。<img>タグで画面に表示はできるのですが、JavaScriptから中身を読むことができません。これを読めるようにするにはCORSの設定が必要になります。['...']})));});具体的にはこのように、respondWith()に渡す辞書でページのoriginを指定します。headersを指定すると、指定したHTTPヘッダもページ側で読めるようになります。54以降でchrome://flagsのenable-experimental-web-platform-featuresを有効にしてください。Workerを登録する場合、JavaScriptでnavigator.serviceWorker.register()を呼ぶ必要がありました。Elementで登録できるようになります。Workerをインストールできるということです。Workerをインストールできます。Workerを登録できるようになるのです。54以降でchrome://flagsのenable-experimental-web-platform-featuresを有効にしてください。TrialとはChromeの実験的な新しいAPIを、申請のあった特定のオリジン(ドメイン)で一定期間だけ使ってもらってフィードバックをもらう仕組みです。Installation含む)が対象になっています。(通称AppCache)という、Webサイトのオフライン対応のためにかつて提案された機能があります。Cacheの非サポート化を明言してまして、Chromeも非セキュアなコンテクストではAppCacheをサポートしなくするとしています。Workerを使おうという流れにあります。Workerを使ってシミュレーションするライブラリです。興味がありましたら、このURLを参照してください。Workerの状態を確認したり、デバッグしたりすることができます。この画面で注目していただきたいのが、このメッセージです。Workerの停止がキャンセルされました」と書かれてます。Workerは一定期間イベントが実行されないと停止し、次回イベントで再起動するようになっています。DevToolsを開いている間は停止しません。通常の状態だと、しばらくほっておくと勝手に停止し、FetchEventなどのイベントハンドラを呼ぶ必要が出ると再起動します。Workerのコードを書く際は気をつけてください。Worker周辺の最近(ここ1年くらい)の動向について説明いたしました。下に関連リンクを貼り付けていますので、もっと詳細を確認したい方はご参照ください。Bluetoothhttps://developers.google.com/web/updates/2015/07/interact-with-ble-devices-on-the-web?hl=enWebUSBhttps://developers.google.com/web/updates/2016/03/access-usb-devices-on-the-web当日の講演資料と動画は下記で公開されていますので、こちらも参照してください。