Upload
kinuko-yasuda
View
12.388
Download
4
Embed Size (px)
Citation preview
ServiceWorker が拓くMobile Web の新しいかたち
HTML5とか勉強会 02/25/2015Kinuko Yasuda (@kinu)[email protected]
HTML5とか勉強会 02/25/2015Kinuko Yasuda (@kinu)[email protected]
ServiceWorker が拓くMobile Web の新しいかたち
自己紹介:Kinuko Yasuda@kinu / [email protected] エンジニア 5年目くらい
■ ストレージ、ネットワーク、Worker系など裏方っぽい API をよくいじっています■ File/Blob, FileSystem, Quota, XHR, Web Workers,
ServiceWorker などなど
■ 2013年秋頃からは主に ServiceWorker
今日話す内容
ServiceWorker が “拓く”Mobile Web の “新しいかたち”■ なぜ ServiceWorker は Exciting なの?
■ つまり ServiceWorker とは何なの?
■ どうやって使うの?
■ セキュリティはどうなってるの?
■ いつから試してみるべき?
Disclaimer: ここで話す内容は私の個人的な意見に基づくもので
あり、私の雇用者とは関係ありません
なぜ ServiceWorker がExciting なのか?
Web is Awesome!!
オープン仕様
リンクによる導線
常に最新のコンテンツ
インストール不要
Mashupの容易さ
プラットフォーム中立
…ただしネットワークに接続していれば。
■ Speed - ロード時間
■ Offline - オフライン時の UX
■ Re-engagement - Push通知などのユー
ザ再訪を促す方法がない
…そしてあらゆる場所に “Install App” のポップアップ
Mobile 時代の Web の ”弱み”
Speed - ロード時間
@igrigorik
Delay User reaction0 - 100 ms Instant100 - 300 ms Slight perceptible delay
300 - 1000 ms Task focus, perceptible delay
1 s+ Mental context switch10 s+ I'll come back later...
ユーザが待てるのは1秒まで、しかし…
Offline - オフライン時のUX
■ “When connectivity is gone,UX is gone.”
■ AppCache?■ 宣言的な記述
■ 細かい制御不可
■ ブラウザ実装次第
■ 凝ったことをしようと
するとはまる
Re-engagement - Push通知の欠如
■ ユーザが Tab を閉じたら終わり
■ 再訪を促す手段がない
■ Speed - ロード時間
■ Offline - オフライン時の UX■ Re-engagement - Push通知などのユー
ザ再訪を促す方法がない
→ どれも Web の動作モデル
から来るもの
Web の強み ≒ Mobile Web の ”弱み”
Webの動作モデル自体を拡張できるようにする?できればブラウザの実装スピードにとらわれない形で。
→ ServiceWorker
ServiceWorkerとは
何なのか?
ServiceWorkerとは?
“AppCacheを置き換える新しいオフラインAPI”
“ブラウザ内で動作するJavaScriptネットワークプロキシ”
“ネイティブ・アプリと Web の間のギャップを埋める”
改めて、ServiceWorkerとは
■ バックグラウンドで動作するJavaScript 実行環境■ DOMにはさわれない
■ ユーザインタラクションもできない
じゃあこのJavaScript環境で何ができるの?
→ ブラウザが内部でやっていたような ことを JS でいじれるようになる
改めて、ServiceWorkerとは
■ バックグラウンドで動作するJavaScript 実行環境■ DOMにはさわれない
■ ユーザインタラクションもできない
■ フォアグラウンドのWebページと対になって動作■ ページのネットワークリクエストを横取りできる■ ページを開いたりメッセージ通信したりできる■ Push通知を受け取れる■ Fetch, Cache などの低レイヤAPIが使える (*)
(*) Fetch, Cache は普通のページからも使えるようになることが予定されています
Webのイメージ, Before ServiceWorker
Cache
♪
Webのイメージ, Before ServiceWorker
Cache
“Network connectivity is a single point of failure when it comes to user-experience on the web.”
ー Jake Archibald, 2014
Webのイメージ, After ServiceWorker
Cache
ServiceWorker
Webページ(のセット)に対してブラウザ内に登録・インス
トールされ、バックグラウンドで動作
● インストールされた ServiceWorker はページからの HTTPリクエストを横取りできる
♪
Webのイメージ, After ServiceWorker
Cache
ServiceWorker
一度インストールされた ServiceWorker はオフラインでも動
作する
● オフライン時やネットワークが遅い・不安定な場合の挙動
をきめ細かくスクリプトで制御できる
♪
Webのイメージ, After ServiceWorker
Cache
CacheAPI
♪
HTTPリクエストをキー、HTTPレスポンスを値としてスト
アするオフラインストレージ
● HTTPリクエストをしゃべれる
● CORSレスポンスを扱える
● アトミックに複数エントリを更新できる
Webのイメージ, After ServiceWorker
Cache
FetchAPI
HTTPリクエストを発行してレスポンスを “Fetch” する
● CORSモード, Cache, Credentialsなどの細かい制御が可能
● XHRのより低レイヤな置き換え、あるいはブラウザが実際に
やっている “fetch” の挙動の再定義とも言える
Worker としての ServiceWorker
■ SharedWorker と似ている■ 複数 Web ページに紐付けられる
■ postMessage で Web ページと通信できる
■ SharedWorker と異なる点■ ‘register’ API によってブラウザに登録される
■ 登録はページを閉じても保持される
■ 対応する Web ページを ‘コントロール’ する
オフラインAPIとしての ServiceWorker
■ AppCache と違い、オフラインキャッシュに
特化されたAPIではない
■ AppCache のようなオフライン機能を
作ることもできる低レイヤAPI群■ 便利な高レイヤ API はその上に構築できればよい
■ ブラウザは必要なプリミティブを用意するので
あとはWeb開発者のみなさんがよろしくやってね
■ Extensible Web
ServiceWorker を使ってみる
ServiceWorker を登録・インストールするfunction register() {
// ‘sw.js’ スクリプトを ‘hello/’ 以下の
// URL に対して動作するよう登録する
navigator.serviceWorker.register(
'sw.js', {scope: 'hello/'})
.then(function(r) {
console.log('登録成功: ', r); })
.catch(function(err) {
console.error('エラー... ', err); });
}
self.oninstall = function(ev) {
// インストール時に呼ばれる
// イベント。必要ならここで
// キャッシュの初期化や更新を行う
...
}
sw.js
ServiceWorker のライフサイクル
install
イベントactivate
イベント
fetch
イベント
ServiceWorker のイベント
■ install■ ServiceWorker が登録されるときに呼ばれる■ 例:キャッシュデータの初期化など
■ activate■ 新しい ServiceWorker がページをコントロール
しはじめるときに呼ばれる■ 例:古いキャッシュデータを消すなど
■ fetch■ ページがHTTPリクエストを発行したときに
呼ばれる (ページ遷移もしくはロード)■ 例:キャッシュデータを代わりに返すなど
登録された ServiceWorker を確認する
chrome://serviceworker-internals
DevToolsを開く
登録を消す
SWのコンソールロ
グ
Fetchハンドラによるリクエスト横取り
self.onfetch = function(event) {
// a.html のデータをその場で作って返す
if (event.request.url.indexOf('a.html') != -1) {
event.respondWith(new Response('<h1>Hi!</h1>'));
}
}
Hi!
hello/a.html
Shift-Reload で強制的に読み込んだ場合は ServiceWorker をバイパスします
Cache API を使う
Cache
// 未実装のメソッドがあるのでポリフィルが必要
// https://github.com/coonsta/cache-polyfill
importScripts(‘cache-polyfill.js’);
self.oninstall = function(ev) {
ev.waitUntil(
caches.open(‘v1’).then(function(cache) {
return cache.add(‘/cat.png’);
})); };
self.onfetch = function(ev) {
if (ev.request.url.indexOf(‘png’) != -1)
ev.respondWith(caches.match(‘/cat.png’));
};
scope 内のページ内の画像をすべてネコの画像に置き換える
Cache の中身を確認する (M41から)
② DevToolsを開く
① serviceworker-internals へ
③ Resourcesタブ
④ Service Worker Cache
キャッシュはオリジン毎に管理されます。
Cache と Fetch API を組み合わせる
Cache
importScripts(‘cache-polyfill.js’);
self.oninstall = function(ev) {
ev.waitUntil(
caches.open(‘v2’).then(function(cache) {
return cache.addAll([‘/’, ‘/cat.png’, ...]);
})); };
self.onactivate = function(ev) {
ev.waitUntil(caches.delete(‘v1’));
};
self.onfetch = function(ev) {
ev.respondWith(
caches.match(ev.request).then(function(res) {
return res || fetch(ev.request);
}); };
‘/’以下をキャッシュしておき、キャッシュにないデータへのリクエストが来たらfetch
Fetch と Cache の組み合わせ例
■ キャッシュの中身をまず表示して後からネットワークから取ってきた内容で更新■ ストレスの少ないブラウジング■ 普通のアプリのような挙動■ Background Sync と組み合わせればオンラインのときにキャッ
シュを更新できるように
■ テンプレートをキャッシュしておいて内容だけネットワークから取得■ ロード時間の短縮
ネットワーク状況にかかわらずきめ細かいUXの設計ができるようになる
Fetch API が返す Response
■ basic filtered■ 同一オリジンでリダイレクトでもない■ Set-Cookie, Set-Cookie2 だけがフィルタされる
■ cors filtered■ リクエストが cors もしくは cors-with-preflight で同一
オリジンではない■ Cache-Control, Content-Type など一部を除きすべ
てのヘッダがフィルタされる
■ opaque filtered■ リクエストが no-cors で同一オリジンではない■ すべてのヘッダ, status, body がフィルタされる
ServiceWorker の更新
■ コントロールされているページをロードするとブラウザが自動でチェック■ Cache-control には従うので注意 (ただし24時間以上たってい
たら必ず見に行く)■ コントロールされてるページがある限り新しいものには置き換え
ない (Reload - Shift+Reload - Reload が有効)
self.oninstall = function(ev) {
ev.waitUntil(
caches.open(‘v2’).then(function(cache) {
return cache.addAll([‘...]);
}));
};
self.onactivate = function(ev) {
ev.waitUntil(caches.delete(‘v1’));
};
キャッシュの中身も忘れずに更新する
ServiceWorker の更新 - はまりどころ
■ コントロールされているページをほかに開いて
ると更新されない
■ スクリプトエラーがあると更新されない■ “Opens the DevTools window for ServiceWorker
on start for debugging” でデバッグできる
■ chrome://serviceworker-internals/ は友だち
■ どうしてもはまったらとりあえず登録を全部消
してやりなおす…
■ https://kinu.github.io/ServiceWorkerOfflineBasic
■ https://events.google.com/io2015/
■ https://horo-t.github.io/tiff2bmpsw/tiff2bmpsw.html
デモ的なもの
Push API (M42 から)
■ デモ: johnme-gcm.appspot.com/chat
ServiceWorkerセキュリティはどうなの?
ServiceWorker のセキュリティ (1)
■ Secure origin のみ■ http://example.com では動かない
■ https://example.com, http://localhost のみ
■ 同一オリジンルールに従う■ https://example.com の ServiceWorker は
https://example.com/ のみをコントロール
ServiceWorker のセキュリティ (2)
■ コントロールできるのはスクリプトの置か
れているパス以下のみ■ https://example.com/foo/sw.js は
https://example.com/bar/ をコントロールできない
■ ただし、Service-Worker-Allowed: ヘッダ
でサーバ側で変更できる (M42から)■ Service-Worker-Allowed: ‘/allowed-
path’
ServiceWorker のセキュリティ (3)
■ ServiceWorker スクリプトは javascript MIME type でサーブされる必要がある■ text/plain などでサーブされてるスクリプトは
ServiceWorker として登録できない
■ ServiceWorker のリクエストには Service-Worker: script ヘッダがつく■ サイト側で簡単に disable できる
■ 最初は whitelist されたものだけ許可するのオススメ
ServiceWorkerいつから試すべきか?
新しい API だし、いつから試すべき…?
今です
ServiceWorker を今すぐ試すべき理由
既存サイトに Opt-in で対応可能
■ ロード時間の短縮■ オフラインへの対応■ Push通知対応■ …
SW対応ブラウザ → UXの向上
SW非対応ブラウザ → そのまま
ServiceWorker を今すぐ試すべき理由
既存サイトに Opt-in で対応可能
■ ロード時間の短縮■ オフラインへの対応■ Push通知対応■ …
ネイティブ・アプリでいい?■ いいものもある、もちろん
■ インストールするメリットがあるサイトですか?■ 誰に、いつまで “Install App” 出し続けますか?
ServiceWorker を今すぐ試すべき理由
既存サイトに Opt-in で対応可能
■ ロード時間の短縮■ オフラインへの対応■ Push通知対応■ …
むしろ ServiceWorker 化しない理由がない!
ブラウザの対応状況
Chrome で今すぐ使えます!
http://bit.ly/use-sw-today
ブラウザの対応状況
Firefox でも試せます!
http://bit.ly/ff-sw-builds
ブラウザの対応状況
Internet Explorer にも実装してもらおう!
http://bit.ly/vote-ie-sw
What’s coming next?
今後の予定
■ M41: (もうじき)■ Cache API in DevTools, more methods
■ M42: (4月半ば)■ Push API, Service-Worker-Allowed:,
Fetch API in global scope
■ Firefox: 3月末に Nightly を目標
参考になるページなど
■ Chrome 40 で今すぐServiceWorker を試す
■ HTML5Rocks: ServiceWorkerの紹介
■ Google I/O 2014 - ServiceWorker でネイティブアプリとの差を縮めよう
■ Jake Archibald’s blog: The offline cookbook