<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://organizeseries.com/"
	>

<channel>
	<title>ServiceWorker &#8211; HTML5Experts.jp</title>
	<atom:link href="/tag/serviceworker/feed/" rel="self" type="application/rss+xml" />
	<link>https://html5experts.jp</link>
	<description>日本に、もっとエキスパートを。</description>
	<lastBuildDate>Sat, 07 Jul 2018 03:14:05 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.7.19</generator>
	<item>
		<title>【エキスパートガチトーク】Web技術の未来を「Extensible Web」から探る！（後編）─技術の進化は必要か？</title>
		<link>/shumpei-shiraishi/16641/</link>
		<pubDate>Tue, 08 Sep 2015 01:00:19 +0000</pubDate>
		<dc:creator><![CDATA[白石 俊平]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Extensible Web]]></category>
		<category><![CDATA[Promise]]></category>
		<category><![CDATA[ServiceWorker]]></category>
		<category><![CDATA[Web Components]]></category>

		<guid isPermaLink="false">/?p=16641</guid>
		<description><![CDATA[本対談記事は、Extensible Webが誕生してから2年で何が変わったのか、そしてこれからWebはどうなっていくのかを、有識者の方々にそれぞれの立場から語っていただこうという企画です。 後編である今回は、Extens...]]></description>
				<content:encoded><![CDATA[<p><style>
.post-detail-contents p {
  text-indent: 0;
  clear: left;
}
b.speaker.komatsu {
  background: url('/wp-content/uploads/2015/08/komatsu.png') no-repeat;
  background-size: 48px;
}
b.speaker.shiraishi {
  background: url('/wp-content/uploads/2015/08/shiraishi.png') no-repeat;
  background-size: 48px;
}
b.speaker.saito {
  background: url('/wp-content/uploads/2015/08/saito.png') no-repeat;
  background-size: 48px;
}
b.speaker.daniel {
  background: url('/wp-content/uploads/2015/08/daniel.png') no-repeat;
  background-size: 48px;
}
b.speaker.asai {
  background: url('/wp-content/uploads/2015/08/asai.png') no-repeat;
  background-size: 48px;
}
b.speaker {
  display: inline-block;
  width: 48px;
  height: 18px;
  float: left;
  padding-right: 8px;
  padding-top: 48px;
  text-align: center;
  font-size: 12px;
  margin-bottom: 4px;
  font-weight: normal;
  clear: left;
}
p {
  overflow: hidden;
}
</style>
本対談記事は、<strong>Extensible Web</strong>が誕生してから2年で何が変わったのか、そしてこれからWebはどうなっていくのかを、有識者の方々にそれぞれの立場から語っていただこうという企画です。</p>

<p>後編である今回は、Extensible Webの現在、そしてWeb技術の未来にフォーカスしたお話になります。Extensible Webの概要や、Extensible Web以前からあるWebの問題点について知りたい方は、<a href="https://html5experts.jp/shumpei-shiraishi/16597/" data-wpel-link="internal">前編</a>をご覧ください。</p>

<p><img src="/wp-content/uploads/2015/08/DSC_0187.png" alt="" width="640" height="407" class="aligncenter size-full wp-image-16716" srcset="/wp-content/uploads/2015/08/DSC_0187.png 640w, /wp-content/uploads/2015/08/DSC_0187-300x191.png 300w, /wp-content/uploads/2015/08/DSC_0187-207x132.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>HTML5は（ついに）モジュール化される</h2>

<p><b class="speaker shiraishi">白石</b> では、Extensible Webの考え方が提唱されてから2年が過ぎたわけですが、どのような変化が起きつつありますか？まずは皆さん、思いついたものから教えていただけると嬉しいです。</p>

<p><b class="speaker daniel">ダニエル</b> 最近の話で言うと、<strong>HTML5の仕様がモジュール化されます</strong>。例えば<a href="http://w3c.github.io/charter-html/timed-media-wg.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Timed Media Working Group</a>というワーキンググループが提案されていますが、もともとはHTML5の一部でした。このように、専門的なグループに分かれて仕様策定が進められるようになろうとしています。</p>

<p><b class="speaker shiraishi">白石</b> Extensible Webは、標準化の話とも密接に関わっているかと思うので、詳しく教えて下さい。HTML5.1がバラバラになっていくということでしょうか？</p>

<p><b class="speaker daniel">ダニエル</b> そうです。まだ詳細は決まっていませんが、<strong>今後仕様書も分割されていきます</strong>。ちょうど、CSSがバージョン3になって、多数の仕様書に分割されて、それぞれメンテナンスされるようになったのと似た感じになるでしょう。</p>

<p>また、ワーキンググループが分かれていくというだけではなく、もっと開発者が参加しやすくなります。その一つが、<a href="https://www.w3.org/community/wicg/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Incubator Community Group</a>の作成です。これができたのもつい最近（2015/7/2）ですね。ここは仕様を提案する場というよりは、質問してアドバイスを受けたり、デモを投稿したりと、一般の開発者のサポートが中心になります。</p>

<p><b class="speaker saito">斉藤</b> これは素晴らしいですね。最近すごく思うのは、仕様書がGitHubに置かれるようになって、<strong>別にGitHubが大好きというわけでもないんですが、開発者に見られるサイトNo.1ということで</strong>、変更の履歴すらも簡単に見られるようになり、どういう経緯で仕様が変更されていったかが追えるようになったのは素晴らしいと思います。</p>

<p><b class="speaker daniel">ダニエル</b> 10月のTPACまでに細かい作業を終えて、TPAC以降にフィードバックをもらいながら改善していくという感じだと思います。</p>

<h2>APIの低レベルさはどこまで許容される？</h2>

<p><b class="speaker asai">浅井</b> 最近はExtensible Webの流れを受けて、低レベルなAPIを提供して開発者に使ってもらおう、ということを意識するようになりました。例えば最近、センサー類のAPIを作ろうとしているのですが、大きく２つの方向性があるという議論になったんですよ。</p>

<p>一つは光センサーとか、既存のセンサーを抽象化するようなもの。またそれと合わせて、組み込み向けの通信制御のAPIを提供してはどうかというものでした。こちらはまあ、普通ですね。</p>

<p>でももう一つはぶっ飛んでて、<strong>Low Level File System APIっていうのを作ってしまってはどうか</strong>、と。
UNIXって、<code>/dev</code> 以下のファイルを通じてデバイスにアクセスできるじゃないですか。だったら、ファイルにアクセスできる手段を一つ開発者に与えてあげるだけで、どんなデバイスでも操作できるようになるじゃないか、と。本当に低レベルなものを作りさえすれば、開発者が必要なものを作れるよという考え方です。</p>

<p>でもこれは完全にぶっ飛んでる。だってプラットフォームに思い切り依存するじゃないですか。やり過ぎ感はすごくあるけど(笑)、それをマジメに議論できるようになったというのが、Extensible Webから来る発想なんじゃないかな、という気がします。僕としては、ちょっと低レベルすぎるんじゃないかと思いますが。</p>

<p><b class="speaker shiraishi">白石</b> そのうち、システムコールとか叩けるAPIが出てきそうですね。</p>

<p><b class="speaker asai">浅井</b> あまりAPIが低レベル過ぎても、今度は（JavaScriptライブラリによる）パフォーマンスのロスが大きすぎるし、OS依存のAPIを露出するのはよくないという考え方もあるので、どこまで低レベルにいくべきかというのは、今Extensible Webの中で本当に議論していかなくてはならないんじゃないか、という気がします。</p>

<h2>「Extensible」なAPIたち</h2>

<p><b class="speaker shiraishi">白石</b> なるほど。ではここでちょっと話を変えて、実際にExtensible Webに関連するAPIといえば何があるんでしょう？まず<strong>Fetch</strong>（※）とか。あと、<strong>ServiceWorker</strong>（※）もでしょうか。</p>

<p><b class="speaker saito">斉藤</b> <strong>Promise</strong>（※）とかもそうだと言っていいんじゃないでしょうか。Promiseの原型になったAPI（Deferとか）は、Extensible Webの提唱以前からありますが。</p>

<p><b class="speaker komatsu">小松</b> 他には、<strong>Object.observe</strong>（※）とかもありますね。</p>

<p><b class="speaker asai">浅井</b> <strong>Web Components</strong>（※）もそうでしょうね。</p>

<p><b class="speaker daniel">ダニエル</b> Web Componentsは便利ですよね。Polymer 1.0が出た時に使ってみましたが、とてもよかった。でも、Polymer自体がものすごく巨大なので、便利さの代償も大きいな、と(笑)。</p>

<p><b class="speaker asai">浅井</b> Web Components、小規模なプロジェクトならいいですが、大規模で長期的なプロジェクトとかでは、まだあまり使われてないんじゃないでしょうか。
そういう点では、Mozillaはむしろ積極的に使っています。しかも、Firefox OS本体で。<strong>本当に大事なAPIは、誰かがガチで使わないと熟成されないので、我々は必ず本番プロジェクトにガンガン入れるんです</strong>。</p>

<p>Firefox OS 2.5とかになると、Web ComponentsだけじゃなくてServiceWorkerとかも思い切り使って、アプリケーションのアーキテクチャを大幅に変更しようとしてます。どこよりもServiceWorkerを思い切り使って、悪いところを見つけ出そう、くらいの勢いですね。
ただ、ServiceWorkerをフルに使用して、複雑なキャッシュ処理とかを行うコードを見ていると、これはもう一般のWeb開発者が気軽に触れるレベルじゃないな、と思います。WebGLを生で扱うコードとかもそうですけど。</p>

<p><img src="/wp-content/uploads/2015/08/DSC_0175.png" alt="" width="640" height="426" class="aligncenter size-full wp-image-16719" srcset="/wp-content/uploads/2015/08/DSC_0175.png 640w, /wp-content/uploads/2015/08/DSC_0175-300x200.png 300w, /wp-content/uploads/2015/08/DSC_0175-207x138.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker komatsu">小松</b> WebRTCなんかについても、「一般のWeb開発者にとっては、使うのが難しい」という話はよく聞きます。でも<strong>WebRTCは、低レベルすぎるという意見もあれば、あれでもまだAPIのレベルが高過ぎるという意見もあって</strong>。</p>

<p>もともとはビデオチャットをユースケースとしてAPIを作っていたんだけど、実際にやってみると双方向のビデオチャットだけじゃなくて、例えば監視カメラみたいに「一方向だけ」というユースケースも重要だったりとか、多人数会議とかやるときは映像のネゴシエーションとかもっと柔軟にやりたい、という話が出てくると、実は今のWebRTCでも高レベルすぎると。その議論が、今のORTCに繋がったりしているわけです。しかし、APIのレベルを低くすればするほど、柔軟性は向上するんだけど取り扱いは難しくなって、一般の開発者が触るには難しいものになっていくだろうな…とは感じています。</p>

<p><b class="speaker shiraishi">白石</b> なるほど…WebRTCみたいな、高度なネットワーク処理を伴うAPIについては、TCP/UDPのソケットを直接触れるような低レベルAPIがあればよさそうですよね。Socket APIとかは既にあるんでしたっけ？</p>

<p><b class="speaker asai">浅井</b> ありますよ。Firefox OSではよく使われています。</p>

<p><b class="speaker shiraishi">白石</b> ああそうか、Firefox OSやChrome OSだと、かなり低レベルなJavaScript APIが既に実装されてますよね。Bluetoothとか、シリアル通信とかも可能だったような。</p>

<p><b class="speaker daniel">ダニエル</b> BluetoothのAPIは使ってみたんですけど、やっぱりChromeブラウザじゃなくてChrome OSでしか使えないんですよね。ブラウザで（通常のWebアプリで）使いたいとは感じましたが、それは叶っていません。「危険だ」と。</p>

<p><b class="speaker komatsu">小松</b> <strong>APIのレイヤーを下げていくことと、セキュリティやプライバシーはトレードオフがあります</strong>よね。</p>

<p><small>
※ Fetch…ブラウザがHTTPを使用してリソースを取得する操作をAPIとして利用できるようにしたもの。XMLHttpRequestに近いが、よりAPIが洗練されている</p>

<p>※ ServiceWorker…バックグラウンドで動作し、アプリケーションのHTTPリクエスト・レスポンスをフック可能なAPI。詳しくは<a href="https://html5experts.jp/iwase/7006/" data-wpel-link="internal">こちらの記事</a>を参照のこと。</p>

<p>※ Promise…JavaScriptの非同期処理を扱いやすくするAPI。いわゆる「コールバック地獄」から開放される。</p>

<p>※ Object.observe…オブジェクトのプロパティ変更を監視できるAPI。AngularJSなどでユースケースが発見され、標準化提案がなされている。</p>

<p>※ Web Components…カスタム要素を利用できるようにできるAPI
</small></p>

<h2>低レベルAPIとセキュリティ・プライバシー</h2>

<p><b class="speaker daniel">ダニエル</b> 今お話に上がったように、「低レベルなAPIは危ない」という問題もある。皆さんここはどう考えますか？</p>

<p><b class="speaker shiraishi">白石</b> 僕が今回の対談を準備するにあたって、いろいろ情報を集めた中では、「<strong>そういうセキュリティやプライバシーの部分こそ、標準化のリソースを費やすべき点だ</strong>」という意見がありました。ひとりのエンジニアが、自分の力だけでセキュリティやプライバシーを完璧に実装することは不可能なので、標準化というプロセスを踏んで様々な知見を集約することで、そういったAPIの安全性を担保するという。</p>

<p><b class="speaker asai">浅井</b> ただ今の時代、<strong>APIだけでセキュリティを担保するのは難しくて、結局はアプリケーションのエコシステム全体でサポートしていかなくちゃいけない</strong>んですよね。例えばWebを全てHTTPS化するとか、アプリケーションマーケットでセキュリティレビューが行われるから安全になるとか、ほかの仕組みと組み合わせることで安全性を担保するという形になってきている。</p>

<p>まあ、一方で、そういう他の仕組みで担保してもらえるからエンジニア自身はあまりセキュリティのことを考えなくなっている…というのもあると感じています。もし低レベルのAPIが使えるようになるなら、実際躊躇なく開発者は使うわけですよ。Firefox OSでもふんだんに使われています。セキュリティレビュー前提でね。でも、そのセキュリティレビューが、どのエコシステムでも行われるわけではない。もしそういうAPIが、（セキュリティレビューのない）一般のWebコンテンツでも使えるようになったらまずいんです。</p>

<p><strong>エコシステム全体で安全性を保っているのに、エコシステム抜きでAPIだけ持ってきて使えるようにしてしまうと、安全でなくなってしまう。そこをどうやって担保していけばいいのか</strong>な、というのはすごく難しく感じています。</p>

<p><b class="speaker shiraishi">白石</b> HTTPSが前提だったり、Firefox OSみたいな環境の上でサンドボックス化されたアプリケーションであることが前提だったりとか、APIを取り囲む様々なコンテキストだったり環境を含めてこそセキュリティが担保されるのであって、APIだけ切り出して安全性を担保するというのは難しいということですね。</p>

<p><b class="speaker saito">斉藤</b> なるほど… 正直、「ServiceWorkerがHTTPSのみになりました」と聞いた時「なんだとコノヤロウ」と思ったくらいなんですが(笑)。よくよく考えてみると「そうだよね」と納得は出来るんですが、一方で「誰がそのSSL証明書代払うねん」という感じでもあります(笑)。</p>

<p><b class="speaker asai">浅井</b> <a href="http://www.mozilla.jp/blog/entry/10442/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">MozillaはHTTPSの無料化を推進しようとしています</a>けどね。</p>

<p><b class="speaker shiraishi">白石</b> そうですよね、頑張ってくださいよMozillaさん！世界中がMozillaに期待してます(笑)！</p>

<p>でも、ServiceWorkerはHTTPSオンリーです、というのは少し乱暴な感じも受けるのですが。<strong>今後、Extensible Webの思想に則ったAPIがどんどん現れるとして、「とりあえず危ないかもしれないからHTTPS限定にしておこう」という感じになっちゃわないんでしょうか</strong>？</p>

<p><b class="speaker saito">斉藤</b> まあ、流れとしてはWebは全部HTTPSにしていこうという感じですしねえ…</p>

<p><b class="speaker komatsu">小松</b> そうそう。iOS9のWebViewは、<a href="http://dev.classmethod.jp/smartphone/iphone/ios-9-intro-ats/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">デフォルトではHTTPS接続しかできなくなるしね</a>。</p>

<p><b class="speaker daniel">ダニエル</b> 標準化のほうでも、実際そういう流れはあります。「<a href="https://w3c.github.io/webappsec/specs/powerfulfeatures/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Secure Contexts</a>」というドキュメントがあって、<a href="https://w3c.github.io/webappsec/specs/powerfulfeatures/#threat-risks" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">「こういう場合はHTTPS接続が必要」というシチュエーションを列挙しています</a>。
これによると、センシティブなデータやセンサーデータにアクセスするAPIは全て対象となっていますので、（今まで非HTTPS環境でも利用できていた）<strong>Geolocation APIなども、将来的にはHTTPS限定になるかもしれません</strong>。</p>

<h2>世界は、開発者からのフィードバックを求めている</h2>

<p><b class="speaker shiraishi">白石</b> ここまでは、Extensible Webを中心として、Webの過去や現在についてお話いただきました。では、<strong>未来のWeb技術はどうなるんでしょう</strong>？</p>

<p><b class="speaker daniel">ダニエル</b> 簡単に言うと、<strong>低レベルなAPIが増えて、高レベルなライブラリが増える</strong>、ってことじゃないかと思います。</p>

<p><b class="speaker saito">斉藤</b> 一般の開発者や企業もライブラリを作るようになり、もっと言えば、それで利益を上げる企業が出てきてもいいと思います。今はWebのプラットフォームやライブラリを作っているのって、結局ブラウザベンダ周辺の方々ばかりです。もしそこで利益を上げられる仕組みが出てきたとしたら、もっと一般の企業や開発者がWebのプラットフォームづくりに貢献できるようになるんじゃないかと。今は、あまり貢献できる余地がない。</p>

<p><b class="speaker asai">浅井</b> <strong>（Webプラットフォームへの）貢献という点では、ブラウザベンダの立場から言うと、一番求めているのって開発者からのフィードバックなんですよね</strong>。Webブラウザのエンジニアは、フィードバックが欲しくてしかたがないんですよ。自分たちが仕様を書いても、他の人が作って使ってくれないと標準化できないんですから。そこを、どんな方法でもいいから解決したくって、だからこそこんな考え方（Extensible Web）になったという流れもあると思います。</p>

<p><b class="speaker shiraishi">白石</b> そうですよねえ…前編でいくつか挙がっていた「使われていないAPI」なんて、ほんとに使われてなさそうなので、フィードバックも何もあったもんじゃないですよね。</p>

<p><b class="speaker asai">浅井</b> そうなんです。少なくとも僕らは、W3Cにインパクトを与えるためにもどんどん開発者は意見をあげていってほしいと思っていますし、ダニエルさんが紹介していたWeb Platform Incubator Groupにも参加してほしいと思っています。Mozillaに限って言えば、<strong>Bugzillaに日本語でもいいからガンガンコメント欲しい</strong>ですね。「英語で書かなくちゃならない」と思って書かない方も多いんですが、翻訳サイトを使って読んでみて、わからなければ日本のエンジニアに質問が来るので。</p>

<p><b class="speaker saito">斉藤</b> なるほど、そういう貢献であれば、気軽にできそうだし人にも促せそうです。</p>

<p><b class="speaker asai">浅井</b> <strong>わかりにくい英語でフィードバックもらうくらいなら、専門用語満載で日本語で書いてくれたほうがありがたい</strong>んです。フィードバックをもらえないことで発生するコストに比べたら、日本語のフィードバックをもらってそれに日本のスタッフが応えるなんて安いもんです。今はそれこそ、縦書きの仕様とかあるじゃないですか。ああいうところって、日本でしか通用しない用語がたくさんある。それを無理に英語にする必要はなくて、そのまま日本語で書いてほしい。</p>

<p><b class="speaker saito">斉藤</b> そうですよね…「禁則処理」とか英語でどう言えばいいのか、よく考えたら知らない(笑)。</p>

<p><b class="speaker asai">浅井</b> そういうフィードバックを世界中の開発者がくれる、という未来を僕らは目指しているんです。それに、Extensible Webが進むことで、例えばライブラリやミドルウェアをビジネスにするような企業も出てきたとしたら、そういう企業ってブラウザベンダとの協業にも本気なので、更にフィードバックが熱くなって嬉しいし。</p>

<p>例えば3Dにしても、UnityとかUnrealとか大きな企業がガンガンフィードバックをくれるので、WebGLやasm.jsも —— 今は WebAssemblyの方向に向かっていますが —— どんどんよくなっていったわけですし。</p>

<p><b class="speaker komatsu">小松</b> 確かに、ビジネスで使われると急激にフィードバックが貰えるようになりますよね。</p>

<p><b class="speaker saito">斉藤</b> 「趣味」のレベルと「ビジネス」のレベルだと、フィードバックするモチベーションもぜんぜん違うかもしれませんね。</p>

<p><b class="speaker komatsu">小松</b> そうそう。趣味でやってる時って、例えバグに遭遇したとしても「このバグは仕様である」って済ませちゃう(笑)。</p>

<p><b class="speaker saito">斉藤</b> 「ま、いっか」で済ませちゃいますよね(笑)。Web技術の進化がビジネスに直結するのであれば、フィードバックのモチベーションは確実に高まると思います。</p>

<h2>今あえて問う: Web技術の進化は求められているのか？</h2>

<p><b class="speaker shiraishi">白石</b> ここで一つ、ちょっと刺激的に聞こえるかもしれない問題提起をさせてください。
<strong>Web技術の進化って、今そんなに求められているのでしょうか？</strong>
現状で言うと、Web技術って主にデスクトップブラウザで使われていて、モバイルはネイティブでいいよね、と世間に認知されている感覚が僕としてはあって。
しかも、デスクトップは進化が停滞していて、イノベーションはモバイルアプリで起こっている。WebのAPIをどんどん拡充していっているけど、それで喜んでいる人ってどれくらいいるのかな？と。</p>

<p><b class="speaker daniel">ダニエル</b> 確かに…最近そういう議論がありましたね。<a href="https://twitter.com/ppk" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ppk</a>（※）を中心として、<a href="http://www.quirksmode.org/blog/archives/2015/07/stop_pushing_th.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">「Webは一年くらい開発を止めておこう」という発言がありました</a>。</p>

<p><b class="speaker saito">斉藤</b> 僕もppkの発言は読みました。普通、僕らの開発でも、2年も経てばたくさん技術的負債が溜まっていってしまうものなのに、<strong>Webは壊れたままでどんどん新しい機能を追加していこうとしている</strong>。「一旦止まってしまうと死んでしまう」「止まることは後退することだ」というある種の強迫観念のようなものがあるのかもしれません。</p>

<p><b class="speaker asai">浅井</b> 実際には（Webの進化は）長い間止まってましたけどね(笑)。</p>

<p><b class="speaker shiraishi">白石</b> (HTML)4と5の間ね。</p>

<p><b class="speaker saito">斉藤</b> あの（進化が止まっていた）悲しさを繰り返しちゃダメだと、みんな思っているんじゃないでしょうか。僕は、Webはなくなってほしくないと思っているので、Web技術の進化は続いてほしいと考えています。ただ白石さんが仰るとおり、モバイルはネイティブでいいじゃん、という流れもあるのは確かです。</p>

<p><b class="speaker shiraishi">白石</b> 僕自身も、モバイルアプリであってもCordovaを使って開発していたりするので、Web技術は進化し続けてほしいと考えてはいます。CordovaやFirefox OSと言ったプラットフォームが今よりもっと力を持てば、先ほど僕が言った問題提起は不要だと思うんですけどね。</p>

<p><b class="speaker asai">浅井</b> 今はiOSやAndroidのシェアが非常に大きいですからね。そこら辺の状況が変わってくれば、Web技術の立ち位置ももう少し変わってくるんでしょうけどね。</p>

<p>また、先ほどあれだけ開発者に「声が欲しいんです」と訴えましたが、一方で仕様を作っているメンバーが念頭に置いているのは、<strong>5年10年先まで互換性を保ち、しかもあらゆるプラットフォームで動作する</strong>ことです。最初からこれを念頭に置いたプラットフォームは、人類にとって唯一のものだと思う。だから、5年10年先を見据えて絶え間なく技術を進化させていくというのは、誰かがやらなくてはならないと思っています。</p>

<p><b class="speaker shiraishi">白石</b> そう考えると、<strong>昔の「ユースケースありき」で仕様を決めていくというのは少し無理があったのかな、と思えます</strong>ね。5年10年経ったら、ユースケースなんて同じなわけがないですし。そう考えても、Extensible Webというのは正しい方向なんじゃないかと思えてきました。</p>

<p><b class="speaker daniel">ダニエル</b> そうですね。HTML5の世界は、長らくユースケースベースでした。例えばHTML5に何かを提案しようとすると、Ian Hickson（※）の答えは決まって「あなたのユースケースを教えて下さい」（「What&#8217;s your use case?」）でしたし。Extensible Webは、そうしたパラダイムからの脱却という面は少なからずあると思います。
<small>
※ ppk…Peter-Paul Koch氏のこと。著名なWebエンジニアで、<a href="http://www.quirksmode.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">QuirksMode</a>というサイトを運営している。</p>

<p>※ Ian Hickson…HTML5を始め、近年の様々なAPI仕様を策定するにあたって中心的な役割を果たしていた人物。相性はHixie。
</small></p>

<p><img src="/wp-content/uploads/2015/08/DSC_0090.png" alt="" width="640" height="403" class="aligncenter size-full wp-image-16720" srcset="/wp-content/uploads/2015/08/DSC_0090.png 640w, /wp-content/uploads/2015/08/DSC_0090-300x189.png 300w, /wp-content/uploads/2015/08/DSC_0090-207x130.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>新たなライブラリ、仕様書の変化 &#8211; Extensible Webがもたらしつつある変化とは</h2>

<p><b class="speaker daniel">ダニエル</b> CSSの方でも、ユースケースありきの考え方から脱却しつつあります。例えば<strong>「<a href="https://github.com/w3c/css-houdini-drafts" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">CSS Houdini</a>」は、ユースケースを考えずにCSSの基盤を公開して、その上に新たな機能を載せていく</strong>というアイデアです。</p>

<p>例えば、「新しいセレクタが欲しい」という場合、CSSの低レベルAPIで独自のCSSセレクタを作ったり…ということが想定されています。</p>

<p><b class="speaker komatsu">小松</b> 正確ではありませんが、「Web ComponentsのCSS版」といえばわかりやすいんじゃないかな。</p>

<p><b class="speaker saito">斉藤</b> 「独自のCSSセレクタを作る」というのを実現する<a href="http://www.hitchjs.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">hitch.js</a>というライブラリはすでにありますね。</p>

<p><b class="speaker shiraishi">白石</b> （READMEの例を一見して）自分の好きなセレクタを書ける！これはすごい。いやー、未来的な話になってきましたね。</p>

<p><b class="speaker saito">斉藤</b> CSSにまつわる話で言うと、<a href="https://github.com/marcj/css-element-queries" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">CSS Element Query</a>っていうのもありますね。</p>

<p><b class="speaker shiraishi">白石</b> （こちらもREADMEの例を一見して）ああ、これは使いやすそうですね。メディアクエリで「巨大なif」みたいな感じになるのが防げますね(笑)。</p>

<p><b class="speaker komatsu">小松</b> ほんとだ、これは便利そう。</p>

<p><b class="speaker daniel">ダニエル</b>
ちょっといいですか？<strong>今ここで起きていることこそが、Extensible Webが目指す形だと思いました</strong>。</p>

<p>これまでは、まず英語でできた仕様書しかなくて、その後コードやデモが整備されるまでは中々APIを理解できない。英語がよく読めない人たちにとってはなおさらです。</p>

<p><strong>でも今ここで起きていたのは、アイデアがコードで示されていて、皆さんは説明よりも先にコードを読んでいました。そして、「これはいい」とか「これは良くない」とかそういう話で盛り上がっていた</strong>。</p>

<p><b class="speaker komatsu">小松</b> 確かに。それに、仕様書にコードスニペットが記載されるという動きも、どんどん広がってますよね。そっちのほうがずっと分かりやすいから。</p>

<p><b class="speaker shiraishi">白石</b> そうですよねー、<strong>WebIDL</strong>（※）で示されたインターフェース定義から、どう動くのか想像するのとかって、割としんどかったですからね。そもそもWebIDLの読み方を勉強しなくちゃならない。</p>

<p><b class="speaker saito">斉藤</b> 「仕様書の読み方」みたいな講座があってもいいかもしれませんよね(笑)。</p>

<p><small>
※ WebIDL…W3Cのドキュメントで使用される、Web技術用のインターフェース定義言語（IDL:Interface Definition Language）
</small></p>

<h2>Extensible Webから探る、Webの未来</h2>

<p><b class="speaker shiraishi">白石</b> では、最後のトピックとして、Webブラウザの未来を探ってみたいと思うのですが、いかがでしょう？例えば以前、「Webは死ぬか」という対談を行った時に、Googleの及川さんが、「ブラウザコードもコンポーネント化が進んで、必要に応じてコンポーネントがダウンロードされる」という可能性を示唆してくれたのですが。</p>

<p><b class="speaker komatsu">小松</b> 例えばLinuxディストリビューションを想定してみるのもいいかもしれませんね。Linuxのカーネルに当たるのが現在のブラウザエンジン（のコア部分）で、その他の部分、例えばJavaScriptライブラリや利用頻度がそこまで高くないAPIとかは、パッケージみたいな扱いになるとか。</p>

<p><b class="speaker daniel">ダニエル</b> 未来のブラウザという話で言うと、<strong>もっと専門的なブラウザが出てくる可能性もある</strong>のかな、と考えています。例えば<a href="http://www.espial.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Espial</a>という会社がありまして、別にここは新しい会社ではありませんが、TV専用のブラウザを作っていて、結構使われています。
こういうブラウザが、TVに関係する機能だけ実装すればいいのと同じように、家電専用のブラウザとか、色んな用途に特化したブラウザが出てくる可能性は大きいと思います。</p>

<p><b class="speaker asai">浅井</b> ブラウザが様々なデバイスで使われるようになっていくと、そのうちブラウザというのはユーザから見えなくなって、意識されなくなっていく。四角くなくなるとか、UIのないブラウザとかが普通に使われるようになっていく。</p>

<p><b class="speaker saito">斉藤</b> ブラウザがどこにでもある、って世界ですね。</p>

<p><b class="speaker shiraishi">白石</b> ただ例えば、ウェアラブルデバイスにブラウザが乗るのは当面ないような気もしますね。パフォーマンスの問題もありますし。</p>

<p><b class="speaker saito">斉藤</b> それは確かにそうかもしれません。が、何をもってブラウザと呼ぶのか、という話もありますね。例えば最近読んだのは、車通勤している最中に、Mediumの記事を読み上げてほしいという話があって。そのためのAPIを作ってはという話だったのですが、サーバ側でMediumのHTMLを解釈して、音声データだけをダウンロードしてクライアントで再生するようにすれば、HTMLを解釈する「ブラウザ」はクライアント側になくてもいいわけです。このように、Webページを「聞く」という行為、それすらも「ブラウジング」と言えると思います。</p>

<p><b class="speaker shiraishi">白石</b> なるほど、<strong>「ブラウザがどこにでもある」という世界を考えると、逆にブラウザが手元になくてもいい</strong>わけですね。HTMLが単なる音声データのためのデータソースになっている。</p>

<p><b class="speaker asai">浅井</b> そういうサービスを作るにあたっても、Web技術を使うようにすると、特許の問題とかが起きにくいんです。</p>

<p><b class="speaker saito">斉藤</b> ああ、それはありますね。</p>

<p><b class="speaker asai">浅井</b> …新しいものを作るときに、エコシステムが広がるのをブロックしてしまう原因を、Webは比較的解決していたり、最初から意識していたりすることが多いので、Web技術が広がってくれると、</p>

<p><b class="speaker shiraishi">白石</b> 広がってくれると？</p>

<p><b class="speaker asai">浅井</b> <strong>より人類は幸せになれます</strong>。</p>

<p><b class="speaker shiraishi">白石</b> 話でかい(笑)。〆の言葉としていい感じのフレーズが出たところで、本対談を終わりにしたいと思います。皆様、本日はどうもありがとうございました！</p>
]]></content:encoded>
			</item>
		<item>
		<title>HTML5とかモバイルとかJSフレームワークとか、ぶっちゃけどうなの座談会</title>
		<link>/amurachi/10569/</link>
		<pubDate>Thu, 04 Sep 2014 00:00:51 +0000</pubDate>
		<dc:creator><![CDATA[村地彰]]></dc:creator>
				<category><![CDATA[システム開発]]></category>
		<category><![CDATA[ServiceWorker]]></category>
		<category><![CDATA[Web Components]]></category>
		<category><![CDATA[html5j]]></category>
		<category><![CDATA[イベント]]></category>
		<category><![CDATA[エンタープライズ]]></category>

		<guid isPermaLink="false">/?p=10569</guid>
		<description><![CDATA[連載： エンタープライズ開発特集 (4)最近のシステム開発の現場では、HTML5やモバイル、JSフレームワークなどの新しい道具が次々と登場してきます。「そうした新しい道具ってエンタープライズではどうなの？」「現場として受...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/enterprise/" class="series-197" title="エンタープライズ開発特集" data-wpel-link="internal">エンタープライズ開発特集</a> (4)</div><p>最近のシステム開発の現場では、HTML5やモバイル、JSフレームワークなどの新しい道具が次々と登場してきます。「そうした新しい道具ってエンタープライズではどうなの？」「現場として受け入れられているの？」といったぶっちゃけトークを行う座談会が、8月11日に美人で有名なおだんみつさんのいる<a href="http://www.ni-ichicafe.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">21cafe</a>で開催されました。1時間半にわたる長時間のトークから特に盛り上がった話を紹介します。</p>

<p><img src="/wp-content/uploads/2014/09/talk1.jpg" alt="" width="600" height="400" class="alignnone size-full wp-image-10570" srcset="/wp-content/uploads/2014/09/talk1.jpg 600w, /wp-content/uploads/2014/09/talk1-300x200.jpg 300w, /wp-content/uploads/2014/09/talk1-207x138.jpg 207w" sizes="(max-width: 600px) 100vw, 600px" /><br><span style="font-size: 80%;">　▲パネラーたち（左から株式会社クレスコ・小川充さん、グロースエクスパートナーズ株式会社・酒巻瑞穂さん、NTTコムウェア株式会社・川田寛さん）</span></p>

<h2>日本のエンタープライズが抱える悩ましい問題とは</h2>

<p><br>
<b>川田</b>：世の中は技術革新で勉強会に行くとワクワクするんですが、でも皆さん本当に使ってますか？<br>
私はあるところで「勉強会で紹介される技術ってお花畑だよね」「俺たちそこまでアグレッシブじゃないよね」って聞いてショックを受けたんです(笑)。とは言え、イケてるものは世の中にいっぱい出てきていて、OSS由来のベンダー製品も、モバイルもたくさん出てきています。でも日本のエンタープライズだと、結構悩ましい問題を抱えているように思うのですよ。</p>

<p><img src="/wp-content/uploads/2014/09/talk5.jpg" alt="" width="600" height="338" class="alignnone size-full wp-image-10580" srcset="/wp-content/uploads/2014/09/talk5.jpg 600w, /wp-content/uploads/2014/09/talk5-300x169.jpg 300w, /wp-content/uploads/2014/09/talk5-207x116.jpg 207w" sizes="(max-width: 600px) 100vw, 600px" /><br><span style="font-size: 80%;">　▲日本のエンタープライズは世界のスタンダードと離れすぎている</span>
<br><br>
（スライドを示して）そもそもですけど、エンタープライズって、エンジニアを取り巻くエコシステムが欧米と日本とで全然違いますよね。SIerなんかがまさにそれで、ユーザ企業さんのシステム費を下げようとして頑張るんですが、システム費が下がると受注費が下がるし、エンジニアが評価されないしで、利害がうまく一致せず難しい状況。<br><br>
そんな中で、ITで働き方をよくしようとか、エンジニアの技術で競争力アップに貢献していこうとか、そういう投資を提案していけるかんじにはなかなかなれず、海外とかと比べると日本はよくない方向に向かってる。エンタープライズは今とてもツラい状況に陥っているのではないでしょうか。そこで今日は前向きに企業のITをよくしていく方法を、フロントエンドという観点から、語り合えたらいいなと考えています。今日のアジェンダですがこの3つです。</p>

<ul>
<li>古いシステムのツラいところ、例えばIE6/VB6とか</li>
<li>これから結構使えそうなWeb技術</li>
<li>どうやって新しい技術を入れるか、上司を説得するか</li>
</ul>

<p><br>
これらの課題を考えていく会にしたいと思います。早速パネラーに自己紹介してもらいましょう。<br><br>
<b>小川</b>：エンタープライズ部の小川です。システム提案とか社内で利用するフレームワークの選定、エンジニアのトレーニングとかをやってます。<br><br>
<b>酒巻</b>：同じくエンタープライズ部の酒巻です。前職ではHTML5関係の技術を仕事に取り入れてました。転職して直接HTML5関連は減ってるんですが、前職の経験からエッジの効いたエンタープライズっぽいところには関っている、という結構幸せな仕事をしてます(笑)。前職では小川さんと同じ社内標準の選定や、教育を含めてオープンソースの技術をどう使っていくのかという取り組みをやってました。</p>

<h2>レガシーシステムとの付き合い方</h2>

<p><br>
<b>川田</b>：では、まず「古いシステムのツラいところ」から。
<br><br>
<b>酒巻</b>：自分の場合は、IE6やVB6でも苦しめられることがありますね。IE6ってXPと同時に死に絶えるかと思ったら、「サポート切れてるけど長期的に見て2年後にリプレース」みたいなところがあって。その資産とエッジの技術が今ぶつかってる。特に技術者が少ない部分、ActionScriptとかPrototypeJSとかに特有の癖などをよく知っている技術者が少ないんです。そういうニッチなことを知ってる人に負荷が集中してるのが、今よく見る状況ですね。VBも一緒だと思います。VBができるエンジニアって社内で貴重です。
<br><br>
<b>川田</b>：VB6知ってる人とか「神」扱いですよね。
<br><br>
<b>酒巻</b>：そういう人はたいていエッジなものも知ってるから、一人に対してよけいに負荷が集中してしまう。知らない人は定時で帰れるのに。
<br><br>
<b>小川</b>：私は今は幸いにIE6じゃなくIE8なんですけど、VBからIE6とJava EEに置き換わってという、まずはオープン系に置き換わって、その次のリプレースってのが多いですね。私は今日は話すほうよりも、皆さんからヒントをいただきたいので、いろいろ聞きたいんです。
<br><br>
<strong>──ここで川田さんが、会場にIEの案件をやっている人の挙手を募ったところ、意外と少ない結果に。さらにAndroid2.3標準ブラウザについても聞いてみると…</strong>
<br><br>
<b>川田</b>：Android2.3標準ブラウザだと、IE6とあまり変わらないくらいの存在ですね。IE8を使ってるということは、エンタープライズだとJavaなどが多いと思いますが、JSFあたりは拡張にいろいろと制約が出てきませんか？
<br><br>
<b>小川</b>：私の周りでは、そもそもJSFを使ってるケースがあまり例がありません。実際はまだJSPで作られているものが多くて、それを今のHTMLベースのアプリケーションに置き換える時に、BackboneなのかAngular.jsなのか、という議論です。
<br><br>
<b>川田</b>：JavaScriptフレームワークの活用に進んだのですね。小川さんは、ちなみにどっち派ですか？
<br><br>
<b>小川</b>：今はAngular推しなんですけど、どちらかというとSenchaのように、UIのコンポーネントを持っているもののほうがエンタープライズとしてはよいのではないかと思っています。
<br><br>
<b>川田</b>：エンタープライズの重要なポイントとしてサポートというのもあるけど、ちょっと安い案件はサポートなしでいこうかな、みたいなラインを狙ってるようですが、そのあたりどう思いますか？
<br><br>
<b>小川</b>：持続可能性を考えると、オープンソースだけタダだからって単体で使うのは、ちょっと違うなと思ってます。サポートがあるというのとは別に、いろんなものを組み合わせるとどこで不整合が起きるか分からないですし、ライセンスの問題もありますし、結構難しいんですね。そう考えるといろんなオープンソースを組み合わせて、一個のプロダクトにしているものの方がよいと思います。
<br><br>
<b>川田</b>：なるほど。話は変わりますけど、「古いIE向けのシステムはIE8や9でDocumentModeを使って動かせる」という神話があるんですが、実際に中身にはJavaアプレットがあったり、もう一つはFlash/Flexだったりするわけですね。そういうのを入れ替えたり、維持したりというのはありますか。
<br><br>
<b>酒巻</b>：2年くらい前の話なんですけど、その時に自分はネイティブを選んじゃったんです。2年くらい前だとFlashでやれることがHTMLではまだつらかった時期で、しかもIE7までサポートという条件があって。技術的にはできるんですよ、技術的には。ただ投資効果が…リプレース案件だったのでお金が出ないんですよ。それで一番安く上げる方法は…ってなるとFlashになっちゃう。自分はこれはHTMLでやったら面白そうだなとは思ってたんですが…。
<br><br>
<strong>──会場からJavaで画像を操作するところをFlashを使おうとしたが、許可が下りなかった話が投げかけられた。ソースや設計書もなかったが、動いたのだという。</strong>
<br><br>
<b>川田</b>：JavaアプレットとかFlashを置き換える案件、いい方法はありますか？
<br><br>
<b>小川</b>：作り変えた方がいいと思います。作られた当時のビジネス要件と今のビジネス要件では、状況が違いますから。お客さんにとっては、システム更改はグローバル化に代表される様々な変化と戦うための、新しいシステムを手に入れるチャンス。我々エンジニアとしてはそこに新しい技術を入れていく方法を考えていくべきかと。
<br><br>
<b>酒巻</b>：部分置き換えって長期的に見てコストがよろしくないケースのほうが多くて、会社レベルで業務計画の一環として古い資産を置き換えていくべきってのは、常に意識してます。
<br><br>
<b>川田</b>：この世界には、「三割改修は全入れ替えと変わらない」の法則がありますからね。</p>

<h2>エンタープライズでも注目の最新Web技術</h2>

<p><br>
<b>川田</b>：これから先、ビジネスになりそうな技術を探っていこうかなと思うんですが、「この辺の技術要素はアツいぜ」ってのはありますか。
<br><br>
<b>酒巻</b>：鉄板ですが、Web ComponentsとServiceWorkerがすごく「来る」と思ってます。Web ComponentsのビジネスモデルとServiceWorkerのオフラインアプリケーションというのが、今の微妙に足りないHTML5プラットフォームにぴったり当てはまりそうな気がしてるんです。
<br><br>
<b>小川</b>：私の会社はWebだけでなく組込みやクラウドもやっていますが、その中で考えていくと、WebSocketですね。いろいろなデバイスがありますし、今後は薬の中にもセンサーが入るような時代になっていく。そうするとそれらのデータをどうやってWebやクラウドに上げて分析をしていくかが重要になっていて、今「何か」と「何か」をつなぐインフラとしてWebが一番適しているんですよ。そこで今注目している通信技術としてはWebSocketですね。
<br><br>
<b>川田</b>：私はやっぱり業界全体の流れに全力に乗っかろうということで、モバイルに期待していたりします。私はこれからは「モバイルファースト」じゃなく「モビリティファースト」になる説を推しています。実は<a href="http://furoshiki.hatenadiary.jp/entry/2014/08/11/122614" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ブログ記事</a>でも上げてるんですが。
<br><br>
<b>小川</b>：見ました。同感ですね。
<br><br>
<b>川田</b>：従来はデスクトップコンピューターに縛られたシステムだけです。それが今変わってきて、安価で汎用的なデバイスの中から、取捨選択しながらシステムを作っていく時代になると思うんです。デスクトップだけで完結したシステムを作るんではなく、いろいろなデバイスの中から適切なものを選んで、システムで業務フローを実現するような時代になっていくのではないかと。
<br><br>
<b>酒巻</b>：タブレットは結構もてはやされていましたが、仕事で要件とかワークフローを作っていくと専用機の方が優秀になることが多いんです。ワコムのペンタブレットとか、専用のUSBを挿すだけで動くような端末とかで。それがさっき小川さんが言ったWebSocketで通信する、API互換、Web標準でそういったマシンが繋がることがシステム開発の土台となってくれたら、すごい嬉しいなと思います。
<br><br>
<img src="/wp-content/uploads/2014/09/talk2.jpg" alt="" width="600" height="400" class="alignnone size-full wp-image-10575" srcset="/wp-content/uploads/2014/09/talk2.jpg 600w, /wp-content/uploads/2014/09/talk2-300x200.jpg 300w, /wp-content/uploads/2014/09/talk2-207x138.jpg 207w" sizes="(max-width: 600px) 100vw, 600px" /><br><span style="font-size: 80%;">　▲当日の会場は、テーブルには川田さんのおごりのビールが最初から並べられました</span></p>

<h2>エンタープライズにUXって必要？</h2>

<p><br>
<b>川田</b>：モバイル絡みの話になりますが、エンタープライズにUX（への配慮）って必要だと思いますか？
<br><br>
<strong>──会場からの挙手はUXいらないと思う人、いると思う人が半々という結果に</strong>
<br><br>
<strong>（参加者）</strong>：ミスを少なくするというような観点で、誤解が少ないラベリングや紛らわしくないアイコンといったものは絶対必要。そういう理由で僕はUXは必要だと思います。
<br><br>
<strong>（参加者）</strong>：スマートフォンのOSを乗り換えるということがあるけど、たいていの人はすぐに使いこなせる。それはなぜかというと、UXがものすごく考えられていて分かりやすいから。でもエンタープライズの技術では新しいのになると「使わない」「使えない」って言われるのは、UXを考えてないからなんじゃないか。なので新しい技術で日々革新してことになったら、UXの部分だけは一本筋を通してあげないとダメではないかと…。
<br><br>
<b>小川</b>：UI/UXはお金にならないと言われる機会が多いです。例えば非常に使いにくいUIを変えたとき、現場の反応を見ると最初は大変評判が悪い。でも半年くらい経つと「使いやすい」と言われるようになる。その半年間の業務効率低下のコストと、そこで得たUI/UXが本当に等価だったのか自分は結構悩んでいて、WebとかであればUI/UXのベストプラクティスってあるんでしょうけど、企業システムの閉じた世界だと一般論では語れない何かがあるんではないかなと思ってます。
<br><br>
<b>川田</b>：私はUXは暫定的には儲からないんですけど、これから先は必要になると思ってます。エンタープライズとWebで公開されているサービスの大きな違いって評価軸で、Web系のサービスはたくさん利用してもらうことに価値がある。でも業務システムは嫌でも毎日使う。
<br><br>
ところが業務ってシステム化されているはずなのに案外現場に見にいってみると「使いにくい」あるいは「現場に合ってない」と思われるところをアナログに戻してるんです。そういう意味で今まであったものを置き換えるとなった時に、UXは重要なポイントになる。エンタープライズでは、モバイルとUXはセットだと考えているんです。
<br><br>
<b>酒巻</b>：UXじゃなくて、UIの話題の方がまだエンタープライズでは多いんですね。まだUIが出そろっていない「こういう時にこうする」っていうベストな選択肢が、まだ分かってない部分が多いんじゃないかなあと。
<br><br>
<b>川田</b>：エンタープライズは「ベストプラクティス」が好きですよね。
<br><br>
<b>酒巻</b>：むしろその言葉に安心して、みんな次の一歩へ進みたいっていうのがあるんじゃないかな。
<br><br>
<b>小川</b>：「モビリティ」の考え方は非常にありだと思っていて、例えば日本だとどんどん人口が減ってきていて、出産後の女性の活用、オフィスに縛られない働き方の中ではデバイスだったりノートPCが必要だけど、それは今までの業務システムの業務フローにないんです。そこで新しく再設計した上で、全部最適化されたら素晴らしい未来があると思ってますが、なかなかピンときてくれないんですね。ただ今後そういう企業や事例などが増えて、日本でもそういう働き方が普通になってくると思うので、そういうのを実現するための新しいテクノロジーはありだと思うんです。
<br><br>
<b>酒巻</b>：それは自分も夢に見ることがあるんですけど、そうなるために企業が何をするかっていうと「一部改修」「部分改修」で何とかしようって考えが多くて、それでコストが大きくなって結局取りやめようってケースが多かったんです。
<br><br>
<b>小川</b>：そこで相手側のステークホルダーを考え、「経営者の方に話すときは企業としての将来計画、ビジョンといったものをきちっと立てる」ことが必要だと思ってます。</p>

<h2>オープンソースのフレームワークはどう？</h2>

<p><br>
<b>川田</b>：別の新しい技術の話も取り上げてみましょう。「オープンソースのフレームワークってぶっちゃけどうよ？」に何か意見はありますか？
<br><br>
<b>酒巻</b>：現在のエンタープライズで一番注目株といえば、Cordovaですね。お客様からのご要望で、ネイティブのファイルAPI、ローカルファイルにアクセスしたいっていう話が結構あるんです。「ActiveXなどで使えたのが同じWebなのに何で使えないの」って話が出てくるんですよ。そのための逃げ道として、Cordovaなどが出てきているんじゃないかと。ただ将来的に、Cordovaだけでやっていくのは怖いなって自分は思ってます。
<br><br>
<b>小川</b>：あれはまだ「闇」ですね(笑)。私もHTMLだけ作ればネイティブできますよっていうCordovaの甘い誘惑に誘われていったら、なぜかAndroidのネイティブ部分を触ることもあるという(笑)。技術の選択肢としてはありだと思いますけど、選定する側としてはメリット/デメリットをちゃんと把握した上できちんと利用するべきで、そのために一番大事なのは「味見」ですよね。
<br><br>
<b>川田</b>：弊社にはオープンソースの匠みたいな人がゴロゴロといるんですが、彼らが言うには「ここ最近の技術革新は早すぎる」。ここ10年くらいはゆっくり動いていたのに、滅茶苦茶早くなってしまった。そんな中で戦うために必要なのは、やはり「味見」だと思います。
<br><br>
<b>酒巻</b>：ブログや記事で紹介されている「光」の面だけ見て理解した気になり、とりあえず仕事に取り入れてみよう、というスタートはデスマのサイクルに陥る一因。その間に自分で味見やプロトタイプを作り、評価をするって課程が今後必要になってきますね、オープンソースをしっかり使う上では。
<br><br>
<b>川田</b>：「味見部」は何かやります？そこに html5j味見部部長の<a href="https://html5experts.jp/canidoweb/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">金井健一</a>さんもいらっしゃるので…
<br><br>
<b>金井</b>：基本的に新しい技術が出たら味見をしています。なので「人柱」です。新技術がたくさん出てきても当たりなんて1割あるかどうか、本当にひと握りです。
<br><br>
<img src="/wp-content/uploads/2014/09/talk6.jpg" alt="" width="600" height="400" class="alignnone size-full wp-image-10614" srcset="/wp-content/uploads/2014/09/talk6.jpg 600w, /wp-content/uploads/2014/09/talk6-300x200.jpg 300w, /wp-content/uploads/2014/09/talk6-207x138.jpg 207w" sizes="(max-width: 600px) 100vw, 600px" /><br><span style="font-size: 80%;">　▲html5j Web先端技術味見部部長　AngularJS Japan User Group 管理人の金井健一さん</span>
<br><br>
<b>川田</b>：エンタープライズのエンジニアがみんなユーザー企業にいるなら、システム費を下げればそれは直接自分たちの成績になるけど、日本では中間にSIerがいますからね。そこで新しい技術でできることとしてまず考えられるのは、「入れ替えの技術」。まず、「VB6とかFlashを使ってきたことを入れ替える技術は何だ」ってところからスタートして、その後モバイルでどうするのかを考えていくべきかと。</p>

<h2>エンタープライズを「モダン」にするための技術</h2>

<p><br>
<b>川田</b>：最後にどうやって新しい技術を入れていくか、ぶっちゃけ「どうやって上司を説得するか」という話になります。酒巻さんはフレームワークを導入した時、どういう説得をしました？
<br><br>
<b>酒巻</b>：Angularを実際のそれなりの規模のあるシステムに取り入れました。何が大変だったかというと、エンジニアの下からの反発と、それで本当に見積り出せるのかという上からの反発ですね。
<br><br>
<b>川田</b>：見積りなんですか、上からは。
<br><br>
<b>酒巻</b>：これは何万円でできて、ウチに何万円の利益が出るかを最初にかなり正確に出したがるんです。フレームワークは前例がない。それに比べて、JSPで作ったらものすごく具体的に数値ができるんです。そこをいかに「最初に（見積もりを）作りあげるか」でしたね。
<br><br>
<b>川田</b>：Angularを入れるメリットは説明したんですか？
<br><br>
<b>酒巻</b>：はい。説明資料もかなり作りました。自分もBackboneとかEmberとかの当時エッジなJSフレームワークを味見して、最初にいけると思った唯一のフルスタックがAngularだったんですよ。
<br><br>
<b>川田</b>：一つで完結できるってことですか。
<br><br>
<b>酒巻</b>：テストとCIまでが、Angularのページに「こうすればいい」と載っています。Angularの基礎の部分を一回理解すると、それをそのまま設計に転用できるというのがすごく大きい。特にバックエンドのノウハウをそのまま使ったクラスコード、モジュール設計をできたのは上司を説得する上での説得材料になりました。
<br><br>
それをもとに実際に部下たちにAngular.jsを触らせて、実際できたら「できるじゃん」というノリですよね。言いかたが悪いですけどサラリーマンプログラマの人たちは安定した技術、昨日やっていたことを今日もやりたいと思う人が多いんで、それをどう切り替えさせるのか、「ほら簡単だよ」「やったらできるでしょ」さらに「こんなに楽になるよ」というのを教えてあげる、体験させてあげるっていうのが重要かなと思います。
<br><br>
<b>小川</b>：同感です。その点、Angular.jsはいいフレームワーク。後はUIフレームワークですね。SenchaやKendoUIなども検討してみてもいいと思います。
<br><br>
あとマイクロソフトのWinJS、これが正式にリリースされたら結構インパクト大きいと思います。企業システムのHTML5化をする上で一番ネックなのが、バックエンドの既存システムをどうやってWebAPIにするかという点です。バックエンドの話で言うと、マイクロソフトの.NETの技術はかなり素晴らしいですね。そことペアになる、マイクロソフトのサポートがあるUIフレームワークが出てきたら、乗っかってもいいかなと思っています。
<br><br>
<b>川田</b>：最近のエンタープライズでは、OSSよりベンダー製品の方が明らかに尖ってきていますよね。新製品の選定をOSSで縛ると、できないことが多すぎて困ってしまうのですが。
<br><br>
<b>酒巻</b>：自分は、Angularは入れましたけど、実際にガンガンやっていくんであれば、SenchaとかEasyUIの方が安心はできますよね。
<br><br>
<img src="/wp-content/uploads/2014/09/talk7.jpg" alt="talk7" width="600" height="400" class="alignnone size-full wp-image-10616" srcset="/wp-content/uploads/2014/09/talk7.jpg 600w, /wp-content/uploads/2014/09/talk7-300x200.jpg 300w, /wp-content/uploads/2014/09/talk7-207x138.jpg 207w" sizes="(max-width: 600px) 100vw, 600px" />
<br><br>
<b>川田</b>：ほかにこの辺りが来るんじゃないってのはありますか？
<br><br>
<strong>金井</strong>： Angular.jsユーザー会会長だからAngularを推しているわけじゃないんですけど、Build 2014というマイクロソフトの技術者カンファレンスでも「.NET系とAngularの相性がすごくいい」とめちゃくちゃ盛り上がってました。マイクロソフト系列のKnockoutの話が全然出てこなかったんですよ。
<br><br>
<b>小川</b>：ちなみにJavaOne TokyoでもAngularが取り上げられていたそうです。エンタープライズJavaとの組み合わせでも、Angularは注目されているのかもしれない。
<br><br>
<b>金井</b>：たぶん、JavaScriptを書きたくないんですよね。Angularを使えば、JavaScriptの記述量をかなり減らせるから。
<br><br>
<b>川田</b>：私も「みんなJavaScriptなんか書きたくないんじゃないか」と思ってるんですよ。jQueryは「jQuery」っていう言語で、JavaScriptとは言いがたいじゃないですか。ひょっとするとここにいる皆さんも、本当はJavaScriptが嫌いなんじゃないんですか！？
<br><br>
<strong>(会場から) え～(笑)</strong>
<br><br>
<b>川田</b>：で、新しい技術をどう入れていくかの一歩前に戻るんですけど、フロントエンドってJavaScriptを書かない方向に行くんじゃないですか？
<br><br>
<b>金井</b>：JavaScriptにWeb Componentsが実装されると、苦手な人はわざわざJavaScript書かなくていいよっていうふうに、未来はなってます。
<br><br>
<b>小川</b>：コンポーネントが安定的に提供されて、JavaScriptに慣れないエンジニアでも大規模なものが作れるようになればいいなあと思いますね。
<br><br>
<b>川田</b>：思ったよりモバイルとフレームワークの話に行きましたよね。モバイルとフレームワークは非常に関心が高いのだと思います。モバイルに関しては「適用方法はいくらでもあるけど、提案する方法が見つからない」なのですが、フレームワークの場合は「良さは分かっているけど、お客さんにその良さを伝えられないというのが苦しい」のだと全体的に感じました。
<br><br>
ということで、90分にわたりいろいろ議論していただいてありがとうございました。最後にもう一度乾杯で締めましょう。乾杯！</p>
]]></content:encoded>
		
		<series:name><![CDATA[エンタープライズ開発特集]]></series:name>
	</item>
		<item>
		<title>Google I/O 2014 ── ServiceWorker でネイティブアプリとの差を縮めよう</title>
		<link>/myakura/8365/</link>
		<pubDate>Thu, 31 Jul 2014 04:00:00 +0000</pubDate>
		<dc:creator><![CDATA[矢倉 眞隆]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Google I/O 2014]]></category>
		<category><![CDATA[ServiceWorker]]></category>

		<guid isPermaLink="false">/?p=8365</guid>
		<description><![CDATA[連載： Google I/O 2014 特集 (8)今回お届けするのは、Jake Archibald氏とAlex Russell氏によるServiceWorkerのセッション「Appy Times with Servic...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/google-io-2014-2/" class="series-191" title="Google I/O 2014 特集" data-wpel-link="internal">Google I/O 2014 特集</a> (8)</div><p>今回お届けするのは、Jake Archibald氏とAlex Russell氏による<a href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ServiceWorker</a>のセッション「<a href="https://www.youtube.com/watch?v=_yy0CDLnhMA" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Appy Times with ServiceWorker &#8211; Bridging the gap between the web and apps</a>」です。</p>


<!-- iframe plugin v.4.3 wordpress.org/plugins/iframe/ -->
<iframe width="560" height="315" src="//www.youtube.com/embed/_yy0CDLnhMA" frameborder="0" 0="allowfullscreen" scrolling="yes" class="iframe-class"></iframe>


<p>Alex氏はService Workers仕様のEditorで、古くはDojoやChrome Frameに携わっています。TC39やW3CのTAGのメンバーとしても活動し、<a href="http://extensiblewebmanifesto.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Extensible Web構想</a>を推し進める一人です。
Jake氏は<a href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#acknowledgements" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Service Workers仕様の「ゴーストオーサー」</a>だそうです。とても面白い人で、今回も彼のユーモアが炸裂、笑いに包まれた楽しいセッションとなりました。</p>

<h2>不確かなリクエストの旅を助けるServiceWorker</h2>

<p>セッションでは「ブラウザーランド」を舞台に、ブラウザがキャッシュやインターネットからデータを取ってくるまでのやりとりを、Jake氏とAlex氏が演じて説明するという寸劇から、ServiceWorkerの紹介が行われました。</p>

<div id="attachment_8826" style="width: 860px" class="wp-caption aligncenter"><img src="/wp-content/uploads/2014/07/io_ja_al_1.jpg" width="850" height="460" class="size-full wp-image-8826" srcset="/wp-content/uploads/2014/07/io_ja_al_1.jpg 640w, /wp-content/uploads/2014/07/io_ja_al_1-300x162.jpg 300w, /wp-content/uploads/2014/07/io_ja_al_1-207x111.jpg 207w" sizes="(max-width: 850px) 100vw, 850px" /><p class="wp-caption-text">「（AppCacheの森ではなく）HTTPキャッシュに向かい、忘れっぽい魔術師に尋ねるのだ」<br>「魔術師が知らなかったら？ほら、忘れっぽいわけですし」<br>「ならば不確かさの海を渡り、子猫が戯れるインターネットに赴くのだ」<br>「しかし、これまでにも多くのリクエストが戻ってきていません……」</p></div>

<p>ブラウザがリソースを取得するまでには様々な不確定要因があり、遅い・繋がらないといったことはユーザーエクスペリエンスに影響します。しかし、現在のWeb標準ではそれをコントロールする術が足りておらず、Webの持つ拡張性という良さを持ってないとのこと。これを解決するものとしてApplication Cacheが提案されましたが、宣言的な記法を導入したため、見た目のシンプルさとは裏腹に、制御不能な挙動や仕様の説明不足が問題となりました（こうした既存の技術で説明不可能な挙動は、“magic”と呼ばれてたりもします）。</p>

<p>しかし、Application Cacheが提供する「キャッシュ」「ルーティング」「バージョン」のという概念は、Webプラットフォームにはぜひ欲しい機能です。そこでこの3機能を持ち、その上で拡張性やデバッグのしやすさを取り込んだ仕様として、ServiceWorkerが提案されました。策定にはMozillaやSamsungをはじめ、多くの開発者も加わっており、実装もChromeとMozillaが競うように進めています。</p>

<h2>ServiceWorkerを動かす</h2>

<h3>登録・インストールで準備</h3>

<p>ServiceWorkerはWebアプリによって登録（register）され、ServiceWorkerがインストール（install）されて待機状態となります。インストール時には<code>install</code>イベントが発火するので、このタイミングでアプリに必要なファイルをダウンロードできます。</p>

<p></p><pre class="crayon-plain-tag">// ServiceWorkerのスクリプト
this.addEventlistener('install', function (event) {
  // event.waitUntil()は中の処理が終わるまで終了を遅らせる
  event.waitUntil(
    // static-v1という名前のついたキャッシュを用意
    caches.create('static-v1').then(function (cache) {
      // キャッシュしたいリソースをCacheオブジェクトに追加
      // 追加すると自動で取得して、全部取得できたらresolveする
      return cache.add(
        '/',
        '/theme.css',
        '/polymer/polyer.js',
        // ...
      );
    })
  )
});</pre><p></p>

<h4>大活躍なES6 Promises</h4>

<p>ServiceWorkerは複数のドキュメントから登録され、それらをコントロールします。ドキュメント主導ではなくイベント駆動であり、必要がなくなれば終了します。このため中の処理に動的なものは含められず、非同期処理が前提です。</p>

<p>こうした非同期処理にはコールバックやイベントなどさまざまなやり方がありますが、ServiceWorkerではECMAScript 6で定義されるPromisesというものを使います。Promisesを使うと、非同期の何かが成功した場合（resolveした）、失敗した場合（rejectされた）それぞれに対応する処理を一定のパターンで書けるため、コードの見やすさや処理漏れを防ぐことに繋がると期待できます。</p>

<p></p><pre class="crayon-plain-tag">// ES6 Promisesの例
// someAsyncOperation は非同期処理をPromiseオブジェクトとして返す関数
someAsyncOperation()
.then(success) // resolve（成功）時のアクションはthen()の第一引数の関数で処理
.catch(failure) // reject（失敗）時はcatch()内の関数で処理</pre><p></p>

<p>Promisesについて解説すると、それだけで別な記事ができてしまうので、今回はJake氏による<a href="http://www.html5rocks.com/ja/tutorials/es6/promises/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Promisesに関するHTML5 Rocksの記事</a>や<a href="http://azu.github.io/promises-book/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">JavaScript Promiseの本</a>をお読みください。</p>

<h3>fetchでリクエスト・レスポンスに介入</h3>

<p>待機状態のServiceWorkerは、リソースの取得（<code>fetch</code>）やServiceWorkerのアクティベート（<code>activate</code>）などのイベントが発火すると動き出します。オフラインアプリにおいては、fetch時にキャッシュの確認や更新・反映や、フォールバックの提供が考えられるでしょう。</p>

<p></p><pre class="crayon-plain-tag">this.addEventListener('fetch', function (event) {
  // respondWith()でレスポンスを好きなようにできる
  // 引数にはResponseオブジェクトにresolveされるPromiseオブジェクトをとれる
  event.respondWith(
    // キャッシュがあればまずそれを表示
    caches.match(event.request)
    .catch(function () {
      // キャッシュにないものはふつうに取得する
      return event.default();
    })
    .catch(function () {
      // ネットワークに問題があるなどで取得不可能な場合はフォールバック
      return caches.match('/fallback.html');
    })
  );
}</pre><p></p>

<h3>参考：Cache APIって？</h3>

<p>Cache APIは手軽に使えるキャッシュです。キャッシュと言ってもHTTPキャッシュとは完全に分離されており、さらには明示的な指示がない限り削除されない、ドメインを越えて共有されないといった大きな違いがあります。<code>Cache</code>オブジェクトは<code>caches</code>オブジェクトに複数格納できます。また、<code>oninstall</code>時の<code>static-v1</code>のように名前をつけて、参照しやすくもできます。</p>

<p>Cache APIのキャッシュは、適当なタイミングで消してやらなければいけません。ServiceWorkerは、自身の更新時に<code>activate</code>イベントを発火します。このタイミングでは<code>fetch</code>イベントが発生する前なので、キャッシュの削除はもちろん、データベースのスキーマ更新などに最適とのことです。</p>

<h2>キャッシュを賢く使ってよいオフライン体験を</h2>

<p>セッションでは、I/OのKeynoteで発表された<a href="http://www.polymer-project.org/docs/elements/material.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">PolymerのPaper Elements</a>によるクイズアプリ「<a href="http://www.polymer-project.org/apps/topeka/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Topeka</a>」に、ServiceWorkerでオフライン対応を施したアプリをデモしながら解説しました。</p>

<p><img src="/wp-content/uploads/2014/07/topeka.png" alt="" width="675" height="417" class="aligncenter size-full wp-image-9116" srcset="/wp-content/uploads/2014/07/topeka.png 640w, /wp-content/uploads/2014/07/topeka-300x185.png 300w, /wp-content/uploads/2014/07/topeka-207x127.png 207w" sizes="(max-width: 675px) 100vw, 675px" /></p>

<p>Topekaでは、クイズの得点を競い合うためのLeaderboard（スコア表）があります。クイズ本体はキャッシュさせたままでもオフライン動作に問題ありませんが、Leaderboardは順位が変動するのでインストール時にキャッシュさせることはできません。</p>

<p>というわけで、Leaderboardへのアクセスを他のアクセスと分けて処理します。URLのチェックには、<a href="http://url.spec.whatwg.org/#api" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">URL API</a>を使うと少し楽です。</p>

<p></p><pre class="crayon-plain-tag">// こちらServiceWorkerのファイル
var workerURL = new URL(this.url); // URL APIきました

this.addEventListener('fetch', function (event) {
  var url = new URL(event.request.url);
  if (workerURL.origin === url.origin &amp;amp;&amp;amp; url.path === '/leaderboard.json') {
    // leaderboardFetchにLeaderboardの処理を分岐
    event.respondWith(leaderboardFetch(event.request));
  } else {
    // その他はふつうにキャッシュがあれば使って、なければ取得するフローで
    event.respondWith(
      caches.match(event.request).catch(function () {
        return event.default();
      })
    );
  }
});

// 後ろのコードにつづく&hellip;</pre><p></p>

<p>ここでJake氏は、Leaderboardについても常にリクエストするのではなく、キャッシュがあればまずそれを表示し、並行して最新のLeaderboardをリクエストし、取得後に反映するという、ネイティブアプリのオフライン対応でも使われる方法を提案しました。こうすると、新しいLeaderboardをリクエストしている間は画面が真っ白になるといったことがありません。</p>

<div id="attachment_8892" style="width: 710px" class="wp-caption aligncenter"><img src="/wp-content/uploads/2014/07/Screen-Shot-2014-07-15-at-3.15.31.jpg" width="700" height="460" class="size-full wp-image-8892" srcset="/wp-content/uploads/2014/07/Screen-Shot-2014-07-15-at-3.15.31.jpg 640w, /wp-content/uploads/2014/07/Screen-Shot-2014-07-15-at-3.15.31-300x197.jpg 300w, /wp-content/uploads/2014/07/Screen-Shot-2014-07-15-at-3.15.31-207x135.jpg 207w" sizes="(max-width: 700px) 100vw, 700px" /><p class="wp-caption-text">Leaderboardのキャッシュがあればそれを用い、その後で新しいLeaderboardを取得し置き換える処理を示すフローチャート</p></div>

<p>これを実装するとなると、キャッシュされているLeaderboardが最新のものかを確かめ、古い場合はキャッシュを更新しなければいけません。一体どうするのでしょうか。これはまずアプリから「キャッシュを使ってほしい」とServiceWorkerに伝えないといけません。</p>

<p></p><pre class="crayon-plain-tag">// こちらかわってアプリのJavaScriptコード
var showingLiveData = false;

// ふつうにネットワークから取得するPromiseオブジェクト
var liveDataPromise = fetchJSON('/leaderboard.json')
.then(updatePage).then(function () {
  showingLiveData = true;
});

// キャッシュを使うようにServiceWorkerに伝えるPromiseオブジェクト
// serviceWorker.controllerはページをコントロールするSWを返す
if (navigator.serviceWorker.controller) {
  // （fetchJSON()ってメソッドは仕様にないけど、fetch()に似た何かでしょう）
  var cachedDataPromise = fetchJSON('/leaderboard.json', {
    // てきとーなヘッダでタグづけ。これ重要
    headers: { 'X-Cache-Only-Please': 'yep' }
  })
  .then(function (data) {
    if (!showingLiveData) {
      updatePage(data);
    }
  });
}

// セッションのスライドにはなかったので以下勝手に追加
// たぶんこんなコードが入るはず
liveDataPromise.catch(function () {
  return cachedDataPromise
})</pre><p></p>

<p>キャッシュを使わせるよう適当なヘッダをつけてリクエストします。ServiceWorkerはこのヘッダの有無を確かめ、キャッシュがない場合は新しいデータを取得し、キャッシュに追加します。これを処理するのが、ServiceWorkerのスクリプト側にある<code>leaderboardFetch</code>関数です。</p>

<p></p><pre class="crayon-plain-tag">// こちらふたたびServiceWorker
function leaderboardFetch(request) {
  // タグづけされたリクエストの場合は、マッチするキャッシュをそのまま返す
  if (request.headers.has('X-Cache-Only-Please')) {
    return caches.match(request);
  } else {
    // そうじゃない場合はまずstatic-v1なキャッシュを取得し
    return caches.get('static-v1')
    .then(function (cache) {
      // 最新のleaderboardをとってきてキャッシュを更新
      return cache.add(request);
    })
    .then(function (responses) {
      // それだけじゃ何にもならないのでブラウザにも渡す
      return responses[0];
    });
  }
}</pre><p></p>

<h2>ServiceWorkerでいろいろしてみる</h2>

<p>主にオフラインWebアプリの解決策として紹介されるServiceWorkerですが、要はクライアントサイドでプロキシを動かすようなものなので、その気になればかなりいろいろできます。</p>

<p>たとえば、新しい画像フォーマットを使うとして、対応してないブラウザではクライアントサイドでPNGに変換して返すなんてことができます。</p>

<p></p><pre class="crayon-plain-tag">this.addEventListener('fetch', function (event) {
  // request.contextにはいろいろあります
  // http://fetch.spec.whatwg.org/#concept-request-context
  if (event.request.context === 'image') {
    event.respondWith(
      // リソースを取得し、そのレスポンスのContent-Typeをみる
      event.default().then(function (response) {
        if (response.headers.get('content-type') === 'image/amazing') {
          // 謎メソッドでPNGに変換
          return transcodeToPng(response.body);
        }
        return response;
      })
    )
  }
})</pre><p></p>

<p>こちらはもっと一般的（？）なユースケースでしょうか。あるクライアントサイドでテンプレートエンジンを動的に適用しその結果を返すといった、フレームワーク依存が強かったところも少し解決されます。</p>

<p></p><pre class="crayon-plain-tag">// importScriptsはWeb Workersのやつですね
importScripts('/template-engine.js');

this.addEventListener('fetch', function (event) {
  var url = event.request.url;
  if (event.request.context === 'navigation' &amp;amp;&amp;amp; /\/article\//.test(url)) {
    event.respondWith(
      fetch(url + '.json').then(function (response) {
        // asJSON()はStreams APIに移動しそうだけど、いまはFetch仕様にて定義
        // http://fetch.spec.whatwg.org/#fetchbodystream
        return response.body.asJSON();
      }).then(function (json) {
        // JSONとれたらテンプレートを呼び出して
        return caches.match('/template.tmpl').then(function (response) {
          return response.body.asText();
        }).then(function (template) {
          // テンプレートを適用したものをHTMLにして返す
          return new Response(renderTemplate(template, json) {
            headers: {
              'Content-Type': 'text/html'
            }
          });
        })
      })
    );
  }
});</pre><p></p>

<p>ネコ好きのJake氏は、木曜日になったらすべての画像を猫画像に差し替えてしまうコードを紹介して、拍手をもらっていました。</p>

<p></p><pre class="crayon-plain-tag">this.addEventListener('fetch', function (event) {
  if (event.request.context === 'image' &amp;amp;&amp;amp; new Date().getDay === 4) {
    event.respondWith(
      caches.match('/kitten.jpg');
    )
  }
});</pre><p></p>

<p>ServiceWorkerはキャッシュ、ルーティング、バージョニングの仕組みが分離さてているので、いろいろ応用がききますね。</p>

<p>また、ServiceWorkerはWeb Workersの拡張なので、<code>postMessage()</code>でメッセージの送受信が可能です。これを使って、「あとで読む」機能の仕組みを作れます。</p>

<p></p><pre class="crayon-plain-tag">// こちらアプリ
navigator.serviceWorker.controller.postMessage({
  action: 'read-later',
  articleId: 12345
});

// こちらServiceWorker
this.addEventListener('message', function (event) {
  if (event.data.action === 'read-later') {
    // articleIdを持つ記事のリソースを取得してキャッシュに追加する
  }
});</pre><p></p>

<h2>普通のJavaScriptとしてデバッグ可能</h2>

<p>ServiceWorkerのパワフルさはお分かりいただけたかと思えますが、ほかにもいろいろ利点があるとのこと。まずAppCacheとは違い、JavaScriptコードなので、DevToolsでデバッグできるという点が大きいでしょう。Chromeでは、<code>chrome://inspect/#service-workers</code>や <code>chrome://serviceworker-internals/</code>といった、デバッグに便利なページも用意されています。また、現在Chrome Canaryで導入されているDevToolsの新しいエミュレーションモードでは回線状況のシミュレーションができるので、それを組み合わせると遅いネットワークを想定したテストもできるのでおすすめとのことです。このDevToolsの新しいエミュレーション機能については、Tomomi Imuraさんによる<a href="https://html5experts.jp/girlie_mac/8384/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Paul Bakaus氏のセッションレポート</a>で紹介されていますのでお読みください。</p>

<p>少し不便な点といえば、MitM attackを防止するためにHTTPSで提供されたページでしか動作しないことでしょうか。ただ、手元での開発への影響を抑える目的でlocalhostはその例外として機能するとのこと。</p>

<h2>ネイティブとの差を埋めるためには</h2>

<p>セッションのタイトルには、「Bridging the gap between the web and apps（『Webとアプリの差を埋める』）」とあります。キャッシュやルーティングによって必要なリソースをインストールさせてオフラインでも動作させるのも必要ですが、ネイティブアプリにあってWebにはまだ足りていないものがまだまだあるとのこと。その一例としてJake氏はプッシュやバックグラウンド同期を挙げ、それに対応するWeb標準（Background Sync, Push API, Web Notifications）を紹介しました。</p>

<p>Background Sync以外は策定中で、Notifications仕様については実装もあります。しかし、ServiceWorker対応はこれから。というわけでTopekaでどのようにServiceWorkerと同期・プッシュ・通知が実装されているかを紹介しました。Leaderboardのスコアを同期し、トップを奪われたら通知が来るという機能の実装です。</p>

<p>まずは同期です。ServiceWorkerがインストールされているかを確認し、スコアの同期をとります。</p>

<p></p><pre class="crayon-plain-tag">// app.js
sendScore().catch(function () {
  // serviceWorker.readyは常にresolveするPromiseを返す
  navigator.serviceWorker.ready.then(function () {
    // 同期はnavigator.syncに登録するらしいです
    navigator.sync.register('send-score')
    .then(success, failure);
  });
});</pre><p></p>

<p>この同期は1回きりで終了しますが、特定の間隔で同期するタスクも登録。例として、1時間ごとに質問の更新をするタスクが紹介されました。</p>

<p></p><pre class="crayon-plain-tag">// app.js
navigator.serviceWorker.ready.then(function () {
  navigator.sync.register('update-questions', {
    minInterval: 1000 * 60 * 60
  }).then(success, failure);
});</pre><p></p>

<p>minIntervalはあくまでヒントとして伝えられるだけのようで、ブラウザがもっと賢くスケジューリングするのも構わないと説明していました。</p>

<p>さて、ユーザーが同期を許可すると、ServiceWorkerに<code>sync</code>イベントが伝えられます。複数の同期をスケジュールしていたので、イベントの <code>id</code>プロパティで処理を振り分けます。</p>

<p></p><pre class="crayon-plain-tag">// sw.js
this.addEventListener('sync', function (event) {
  if (event.id === 'update-questions') {
    event.waitUntil(syncQuestions());
  }
  else if (event.id === 'send-score') {
    event.waitUntil(sendScore());
  }
});</pre><p></p>

<p>渡されたPromiseオブジェクトがrejectされた場合は、同期が再スケジュールされるとのことなので、また登録する必要はないとのこと。</p>

<p>スコアを送信する <code>sendScore()</code> 関数は、データベースからスコアを取得し、それをPOSTします。</p>

<p></p><pre class="crayon-plain-tag">// sw.js
function sendScore() {
  return getScoreFromDatabase().then(function (score) {
    // Fetch APIはもちろんPOSTもできます
    return fetch('/post-score', {
      method: 'POST',
      body: new FormData({score: score})
    })
    .then(function (response) {
      if (response.status !== 200) {
        throw Error('Failed to post score');
      }
    });
  });
}</pre><p></p>

<p>プッシュメッセージについては、Google Cloud Messagingを使った実装でのやり方が紹介されました。</p>

<p></p><pre class="crayon-plain-tag">// app.js
var regID = '...'; // サーバーに送った登録ID

navigator.serviceWorker.ready.then(function () {
  navigator.push.register().then(function (regDetails) {
    if (regDetails.id !== regID) {
      return postToServer(regDetails);
    }
  }).then(success, failure);
});</pre><p></p>

<p>GCMでは、プッシュの登録が完了すると、以前の登録したプッシュの詳細が返ってくるそうで、今回処理しようとしているものと同じでないかを確認してから、サーバーにメッセージを送っています。</p>

<p>ServiceWorkerでは、<code>push</code>イベントが通知されます。これを拾ってNotification APIで通知を出します。</p>

<p></p><pre class="crayon-plain-tag">// sw.js
this.addEventListener('push', function (event) {
  if (event.message.data === 'lost-lead') {
    new Notification('Lead lost!', {
      body: 'You\'re no longer top!',
      tag: 'leaderboard',
      serviceWorker: true
    });
  }
});</pre><p></p>

<p>デモでは2つのNexus 5を用意し高得点を競い、トップを奪われた方に通知が届きました。また、Android Wearでもその通知が表示されました。</p>

<p><img src="/wp-content/uploads/2014/07/Screenshot-2014-07-25-at-07.45.49-1024x619.png" width="1024" height="619" class="aligncenter size-large wp-image-9121" srcset="/wp-content/uploads/2014/07/Screenshot-2014-07-25-at-07.45.49-1024x619.png 1024w, /wp-content/uploads/2014/07/Screenshot-2014-07-25-at-07.45.49-300x181.png 300w, /wp-content/uploads/2014/07/Screenshot-2014-07-25-at-07.45.49-207x125.png 207w, /wp-content/uploads/2014/07/Screenshot-2014-07-25-at-07.45.49.png 640w" sizes="(max-width: 1024px) 100vw, 1024px" /></p>

<p>大規模なカンファレンスにつきものなネットワークの悪さもあって、通知が来るまでに時間がかかりました。みんなそわそわしましたが、「オフラインWebアプリでも問題ないセッションが、デモのせいで失敗するとか…！」「ふー、このセッション自体も非同期とは」といったオフライン・非同期ジョークなどが飛び出し、会場を和ませました。</p>

<h2>まだまだあるよServiceWorker</h2>

<p>セッションで紹介されたServiceWorkerの機能は以上です。盛りだくさんでした。</p>

<p>このセッションでは、ServiceWorkerの更新については語られませんでした。これについてはJake氏が<a href="http://jakearchibald.com/2014/service-worker-first-draft/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Service Worker &#8211; first draft published</a>という記事で紹介しています。</p>

<p>ServiceWorkerの実装は少しずつ進んでいますが、仕様の議論も並行しているため、今回紹介したコードが動かなくなる可能性は十分にあります。何かアップデートがあればまたServiceWorkerに関する記事が公開されるかもしれませんので、楽しみにしていてください。</p>
]]></content:encoded>
		
		<series:name><![CDATA[Google I/O 2014 特集]]></series:name>
	</item>
		<item>
		<title>ServiceWorker解説 &#8211; オフラインWebアプリケーション開発技術の最前線</title>
		<link>/iwase/7006/</link>
		<pubDate>Fri, 23 May 2014 03:00:45 +0000</pubDate>
		<dc:creator><![CDATA[岩瀬 義昌]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[ServiceWorker]]></category>
		<category><![CDATA[W3C仕様]]></category>

		<guid isPermaLink="false">/?p=7006</guid>
		<description><![CDATA[今月上旬5月8日に、W3CよりServiceWorkerの草案初版が提示されました。ServiceWorkerは、オフラインWebアプリケーションの開発者が問題と考える点を解決する、非常に魅力的な仕様です。日本語の情報が...]]></description>
				<content:encoded><![CDATA[<p>今月上旬5月8日に、W3Cより<a href="http://www.w3.org/TR/2014/WD-service-workers-20140508/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ServiceWorkerの草案初版</a>が提示されました。ServiceWorkerは、オフラインWebアプリケーションの開発者が問題と考える点を解決する、非常に魅力的な仕様です。日本語の情報がほとんどないこのタイミングで、HTML5 Expert.jp編集部が解説いたします！</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/05/ScreenShot2014-05-22-2.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/ScreenShot2014-05-22-2.png" alt="ScreenShot2014-05-22-2" width="847" height="522" class="alignnone size-full wp-image-7015" srcset="/wp-content/uploads/2014/05/ScreenShot2014-05-22-2.png 640w, /wp-content/uploads/2014/05/ScreenShot2014-05-22-2-300x184.png 300w, /wp-content/uploads/2014/05/ScreenShot2014-05-22-2-207x127.png 207w" sizes="(max-width: 847px) 100vw, 847px" /></a></p>

<h2>ServiceWorkerとは</h2>

<p>ServiceWorkerは、リソースの永続的なキャッシュを可能にする、およびWebアプリケーションのリソース要求の処理を可能にする新しい機能です。Webページを開く前であっても（ネットワークの接続/切断の有無にかかわらず）、独自の処理を挟み込めるのがポイントです。クライアント側に、一種のプロキシサーバがあるようにイメージされると分かりやすいと思います。</p>

<p>ServiceWorker自体は、WebWorker同様にJavaScriptで記述し、特にWebWorkerの一種であるSharedWorkerに似ています。最大の違いとしては、SharedWorkerはWebページによってコントロールされるのに対し、ServiceWorkerはWebページをコントロールします。任意のWebアプリケーション(ServiceWorker)がひとたびインストールされると、次回以降のアクセスでは、ブラウザ側の処理がはじまる前に、ServiceWorkerの処理が起動します。</p>

<h3>注意点(ブラウザのサポート状況について)</h3>

<p>執筆時点では、ServiceWorkerをサポートするブラウザはありません。Chrome Canaryでは、以下のようにchrome://flagsにて一部の機能を有効化できますが、あくまで一部の機能であり、後述するキャッシュからリソースを取得する機能等、多くの機能は動作しません。</p>

<div id="attachment_7007" style="width: 689px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2014/05/ScreenShot2014-05-22.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/ScreenShot2014-05-22.png" alt="Chrome://flagsのスクリーンショット" width="679" height="310" class="size-full wp-image-7007" srcset="/wp-content/uploads/2014/05/ScreenShot2014-05-22.png 640w, /wp-content/uploads/2014/05/ScreenShot2014-05-22-300x136.png 300w, /wp-content/uploads/2014/05/ScreenShot2014-05-22-207x94.png 207w" sizes="(max-width: 679px) 100vw, 679px" /></a><p class="wp-caption-text">Chrome://flagsのスクリーンショット</p></div>

<h2>登場の背景</h2>

<p>オフラインWebアプリケーションの開発において、よく知られるキャッシュ機能にApplicationCacheがあります。ApplicationCacheは、ネットワークが切断されている状態であっても、事前にキャッシュしたコンテンツを、Webアプリケーションに提供しますが、<a href="https://html5experts.jp/kyo_ago/2466/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">こちらの記事</a>でも言及されているとおり、様々な問題を抱えています。</p>

<p>例えば、ApplictionCacheは一部のキャッシュのみを更新することができません。ApplicationCacheでは、キャッシュしたいリソースを以下のようなmanifestファイルにすべて記載しておく必要があり、</p>

<p></p><pre class="crayon-plain-tag">CACHE MANIFEST
index.html
stylesheet.css
yourapp.js
myimage.png   <!-- このファイルだけ更新したい！ --></pre><p></p>

<p>ブラウザがWebページにアクセスした際に、これらのリソースはすべてダウンロードされます。仮に上記のコメント箇所のように、リソースの一部のキャッシュのみを更新したいと考えていても、不可能となります。</p>

<p>上記の例は、ApplicationCacheの抱える問題点の一例に過ぎず、その他にも問題点が多くあります。ServiceWorkerは、これらの問題点に対する解決方法となります。</p>

<p>以下で、W3Cの草案で示されるコードサンプル(本記事では一部簡略化)を参考に、利用イメージを解説します。W3Cの例では、非同期処理にpromiseを利用しています。本記事ではpromiseの解説はいたしませんので、必要に応じて<a href="https://developer.mozilla.org/ja/docs/Core_JavaScript_1.5_Reference/Global_Objects/Promise" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">MDN</a>等を参照ください。なお、前述した通りで、執筆時点でServiceWorkerが動作するブラウザはありませんので、以下のコードは実際には動作しない点にご注意ください。</p>

<h2>ServiceWorkerの利用イメージ</h2>

<p>例えば、https://www.example.com/index.htmlにて、ServiceWorkerを利用するケースを考えます。(ServiceWorkerはセキュリティの都合上、HTTPSが必須となる点に注意ください) 先に処理フローを図示し、その後にコード例で解説いたします。</p>

<p style="text-indent: 0em">※ 2014/05/23 追記：ServiceWorkerの処理フローを示す図を追加いたしました。（本図は、Expertsの川田さんから提供いただきました）</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/05/20140523_sw.001.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/20140523_sw.001.png" alt="ServiceWorkerの処理フロー" width="1024" height="768" class="alignnone size-full wp-image-7036" srcset="/wp-content/uploads/2014/05/20140523_sw.001.png 640w, /wp-content/uploads/2014/05/20140523_sw.001-300x225.png 300w, /wp-content/uploads/2014/05/20140523_sw.001-207x155.png 207w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>

<h3>Register(登録)</h3>

<p>まずServiceWorkerとして動作させたい処理を登録(register)します。</p>

<p></p><pre class="crayon-plain-tag">if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/assets/myapp.js').then(
  	function(serviceWorker) { 
  	  console.log("myapp.jsのインストールに成功しました")
    },
  	function(why) { 
  	  console.log("myqpp.jsのインストールに失敗しました");
  	}
  );
}</pre><p></p>

<p>上記により、/assets/myapp.jsがブラウザにダウンロード＆インストールされます。ひとたびmyapp.jsがインストールされると、次回以降のhttp://www.example.com/配下に存在するページにアクセス時に、myapp.jsの処理が起動します。前述したように、ネットワークが切断状態であってもmyapp.jsは起動しますし、もちろんブラウザ自体が持つキャッシュ機構よりも先に動作します。</p>

<p>なお、上記のコード例では http://www.example.com/ の配下すべてのリソースが対象となりますが、/hoge/* のように、scopeを制限することも可能です。その場合、以下のとおり、オプション引数であるscopeを設定してください。</p>

<p></p><pre class="crayon-plain-tag">if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/assets/myapp.js', {
    scope: 'hoge/*' // スコープを設定している
  }).then( ... );
}</pre><p></p>

<p>続いて、ServiceWorkerの処理を記載するmyapp.jsの例を見ていきましょう。</p>

<h3>Fetch(リソースの取得)</h3>

<p>myapp.jsは、WebWorker同様にWorkerスレッドで動作します。そのため、DOM操作はServiceWorkerでは利用できません。ServiceWorkerは、fetchイベントを利用してリソースへのリクエスト・レスポンスを処理します。</p>

<p></p><pre class="crayon-plain-tag">this.addEventListener('fetch', function(event) {
  console.log(event.request);
});</pre><p></p>

<p>上記の例では、http://www.example.com/*へアクセスしたすべてのタイミングで、fetchイベントが起動し、event.requestオブジェクトがコンソールに表示されます。event.requestオブジェクトは、例えば、URL、メソッド、ヘッダ等を含んでいます。</p>

<p>上記は単にリクエストを処理しているだけですが、任意のレスポンスをブラウザへ返すこともできます。</p>

<p></p><pre class="crayon-plain-tag">this.addEventListener('fetch', function(event) {
  event.respondWith(
    new Response({
      body: 'この内容はServiceWorkerが提供しています！'
    })
  );
});</pre><p></p>

<p>この例では、http://www.example.com/* へアクセスすると、「この内容はServiceWorkerが提供しています！」と表示されます。</p>

<h3>リソースのCache</h3>

<p>オフラインでも動作させるためには、キャッシュを利用する必要があります。キャッシュするためのコードは以下のようになります：</p>

<p></p><pre class="crayon-plain-tag">this.addEventListener('install', function(event) {
  var coreCache = new Cache();

  event.waitUntil(Promise.all([
    caches.add('core-v1', coreCache),
    coreCache.add(
      '/app.html',
      '/fallback.html',
      '/assets/v1/base.css',
      '/assets/v1/video.webm'
    )
  ]));
});</pre><p></p>

<p>ServiceWorkerのインストール成功時に発生するinstallイベントを利用して、キャッシュを準備します。Cacheおよびcaches(cacheListのインスタンス)は、ServiceWorkerが用意するストレージAPIです。上記例では、coreCache.add()にて、4つのリソースをキャッシュしています。</p>

<h3>Cacheしたリソースを取得する</h3>

<p>Cacheしたリソースを取得するには、fetchイベントを利用します：</p>

<p></p><pre class="crayon-plain-tag">this.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request).catch(function() {
      return cache.match('/fallback.html');
    })
  );
});</pre><p></p>

<p>上記では、event.requestで指定される内容がすでにcachesにあれば(caches.matchでrejectされなければ)、cacheされている内容を応答します。cachesにない場合は、.catch(&#8230;)の処理に進み、fallback.htmlの内容がブラウザに返されます。</p>

<h2>ServiceWorkerの更新</h2>

<p>ServiceWorkerは、Webページにアクセスするたびに、更新があるかどうか確認します。HTTP Cache-Controlヘッダにて、確認頻度を減らすことも可能ですが、ApplicationCacheに存在する問題を解決するために、長くとも24時間ごとにブラウザが更新を確認します。</p>

<p>もし、ServiceWorkerが以下のコード例のように少しでも異なるならば、新しいバージョンであるとブラウザは判断し、ServiceWorkerをインストールします。</p>

<p></p><pre class="crayon-plain-tag">this.addEventListener('install', function(event) {
  var coreCache = new Cache();

  event.waitUntil(Promise.all([
    caches.add('core-v2', coreCache), // v2にしている
    coreCache.add(
      '/app.html',
      '/fallback.html',
      '/assets/v2/base.css', // v2にしている
      '/assets/v1/video.webm'
    )
  ]));
});</pre><p></p>

<p>インストール処理の間は、現段階のバージョンがfetchイベントに対応し、新しいバージョンのServiceWorkerのインストール動作はバックグラウンドで動作します。</p>

<p>インストールが完了したら、新しいバージョンのServiceWorkerは待ち状態になり、、すべてのページにて現段階のバージョンの利用されなくなるのを待ちます。現段階のバージョンが利用されなくなると、新しいバージョンが動作を開始します。このとき、activateイベントが発生します：</p>

<p></p><pre class="crayon-plain-tag">this.addEventListener('activate', function(event) {
  event.waitUntil(
	// 古いキャッシュの削除等を実施
  );
});</pre><p></p>

<p>activateイベントは、上記コード例のように古いキャッシュの削除等、新しいバージョンのServiceWorkerで不要となるリソースの掃除に利用されます。</p>

<h2>まとめ</h2>

<p>本記事では、ServiceWorkerの登場背景、利用イメージについて解説しました。ServiceWorkerは今後、オフラインWebアプリケーションのコア技術となっていくと想定されます。まだ、ブラウザの実装も進んでいないことからも分かるように、ServiceWorkerはWebの最先端です。</p>

<p>今後も、HTML5 Experts.jpでは、今後も読者の皆様にWeb最先端の情報をお届けいたします！</p>

<h2>参考</h2>

<ul>
<li><a href="http://www.w3.org/TR/2014/WD-service-workers-20140508/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Service Workers &#8211; W3C First Public Working Draft（英語）</a></li>
<li><a href="https://github.com/slightlyoff/ServiceWorker" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ServiceWorkerの詳細（英語）</a></li>
<li><a href="https://github.com/w3c-webmob/ServiceWorker" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ServiceWorkerのユースケース（英語）</a></li>
</ul>
]]></content:encoded>
			</item>
	</channel>
</rss>
