<?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>Progressive Web Apps &#8211; HTML5Experts.jp</title>
	<atom:link href="/tag/progressive-web-apps/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 ～Progressive Web Appsの実装と応用～(de:code2018より)</title>
		<link>/osamum_ms/25709/</link>
		<comments>/osamum_ms/25709/#respond</comments>
		<pubDate>Thu, 05 Jul 2018 02:00:10 +0000</pubDate>
		<dc:creator><![CDATA[物江 修]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[PWA]]></category>
		<category><![CDATA[Progressive Web Apps]]></category>
		<category><![CDATA[Service Worker]]></category>
		<category><![CDATA[de:code]]></category>

		<guid isPermaLink="false">/?p=25709</guid>
		<description><![CDATA[2018年5月に開催された日本マイクロソフト主催のイベントde:code 2018で「進化するWeb ～Progressive Web Appsの実装と応用～」というセッションを担当しました。 イベントに参加できなかった...]]></description>
				<content:encoded><![CDATA[<p>2018年5月に開催された日本マイクロソフト主催のイベント<a href="https://www.microsoft.com/ja-jp/events/decode/2018/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">de:code 2018</a>で「進化するWeb ～Progressive Web Appsの実装と応用～」というセッションを担当しました。</p>

<p>イベントに参加できなかった方に向けてセッションの内容を記事にまとめましたので、ぜひご覧ください。</p>

<div style="margin-bottom:5px"> <strong> <a href="https://html5experts.jp//www.slideshare.net/osamum/web-progressive-web-apps" title="進化する Web ～ Progressive Web Apps の実装と応用 ～" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">進化する Web ～ Progressive Web Apps の実装と応用 ～</a> </strong> from <strong><a href="https://www.slideshare.net/osamum" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Osamu Monoe</a></strong> </div>

<p>この記事では、昨今話題に上ることが多いPWAことProgressive Webアプリケーションについて、実際の作り方を解説しながら、それがいったいどういったものであるかを詳(つまび)らかに紹介することを目的としています。</p>

<p>Webでは、「ネイティブアプリと同じことができる」「ネイティブアプリを置き換える」など、期待に胸を膨らませずにいられない浪漫に満ちた噂がありますが、それが本当かどうか記事をご覧いただくとご理解いただけると思います。</p>

<p>Progressive Web Appsの作り方を紹介する前に、簡単に概要を紹介しましょう。</p>

<h2>Progressive Web Appsとは?</h2>

<p>Progressive Web Apps(以下PWAと記述) は、一言でいうならば「ネイティブアプリのようなUXを提供するWebアプリの概念」といったところでしょう。2015年の11月に開催された<a title="Chrome Dev Summit 2015" href="https://codelabs.developers.google.com/chrome-dev-summit" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Chrome Dev Summit 2015</a>のキーノートで発表されて話題となりました。</p>

<p>もともとは、その年の10月にAlex Russell氏(Google)が<a title="Progressive Web Apps: Escaping Tabs Without Losing Our Soul" href="https://infrequently.org/2015/06/progressive-apps-escaping-tabs-without-losing-our-soul/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ブログ記事</a>に投稿した、クライアントの性能に合わせて段階的に進歩するWebアプリケーションのコンセプトでした。</p>

<p>PWAというと、&#8221;ネイティブアプリのような体験&#8221;といった特徴ばかりが注目されますが、大きな特徴がもう一つあります。それは、PWAという名前にも含まれているProgressiveというところです。</p>

<p>これはHTML5が普及しはじめた頃にあった、「HTML5が解釈できるモダンブラウザーにはリッチな体験を、そうでないブラウザーには従来とおなじ体験を」というデザインの考え方&nbsp;<a href="https://www.blwisdom.com/dictionary/item/6559-001474.html" title="プログレッシブ・エンハンスメント" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Progressive Enhancement</a>に由来します。</p>

<p>PWAはこの思想を踏襲し、性能の低いWebブラウザーを切り捨てることなく、クライアントの性能に合わせた機能提供を行います。</p>

<p>PWAは、性能の低いWebブラウザーからアクセスがあった場合は従来と同じWebページとして動作し、PWAが動作する機能を備えたWebブラウザーからアクセスがあった場合は、その機能を活かし、これまでのWebアプリにはなかったネイティブアプリのような体験を提供します。</p>

<p><img src="https://msdnshared.blob.core.windows.net/media/2018/06/pwa.png" alt="Web アプリケーションの Progressive Enhancement" width="1634" height="900" class="alignnone size-full wp-image-5485" /></p>

<h2>Progressive Web Appsを実現する機能</h2>

<p>それでは、&#8221;これまでのWebアプリにはなかったネイティブアプリのような体験&#8221;というのはどのようなものがあるでしょう? </p>

<p>代表的なものとしては以下の4つが挙げられます。</p>

<ol style="font-size:15px">
<li>オフラインサポート</li>
<li>プッシュ通知</li>
<li>バックグラウンド処理</li>
<li>デバイスへのインストール(デバイスのホーム画面から起動できる)</li>
</ol>

<p>これらはの機能はそれぞれ以下のような新しいAPIによって実現されます。</p>

<ol style="font-size:15px">
<li>オフラインサポート&nbsp;&#8211;&nbsp;<span style="color:blue;font-weight:bold">Cache API</span></li>
<li>プッシュ通知&nbsp;&#8211;&nbsp;<span style="color:blue;font-weight:bold">Push API</span></li>
<li>バックグラウンド処理&nbsp;&#8211;&nbsp;<span style="color:blue;font-weight:bold">Background Sync</span></li>
<li>デバイスへのインストール(OSのメニューから起動できる)&nbsp;&#8211;&nbsp;<span style="color:blue;font-weight:bold">Web App Manifest</span></li>
</ol>

<p>そして、これらの機能を提供しているのが1～3が<a href="https://developer.mozilla.org/ja/docs/Web/API/ServiceWorker_API" target="_blank" title="MDN - サービスワーカー API" data-wpel-link="external" rel="follow external noopener noreferrer">Service Worker</a>で、4が<a href="https://developer.mozilla.org/ja/docs/Web/Manifest" title="MDN - Web App Manifest" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Web App Manifest</a>です。</p>

<p><img src="https://msdnshared.blob.core.windows.net/media/2018/06/sw_new2.png" alt="新しいAPIの提供の図" width="1083" height="456" class="aligncenter size-full wp-image-5505" /></p>

<p>PWAの定義に明確なものはありませんが、上記の機能の中からオフラインサポートと、インストール（アイコンをデバイスのホーム画面に追加）機能をサポートしていれば、PWAを名乗ってもそう否定されることはないでしょう。</p>

<p>これらの機能により、デバイスのホーム画面から、ナビゲーションバーなどのブラウザーUIがない状態でアプリケーションを起動し、オフラインの状態でも使用できる、という体験をユーザーに提供できます。これらの体験は、これまでのWebアプリケーションにはなかったネイティブアプリのならではのメリットと言えるでしょう。</p>

<p>それでは、逆に Web ならではのメリットとはなんでしょう?</p>

<h2>Webのメリット</h2>

<p>ネイティブアプリにはないWebならではのメリットを、Googleさんのイベントではよく以下の<a href="https://paul.kinlan.me/slice-the-web/" title="SLICE: The Web - Tales of a Developer Advocate by Paul Kinlan" target="_blank" style="font-weight:bold" data-wpel-link="external" rel="follow external noopener noreferrer">SLICE</a>という言葉で表しています。</p>

<ul style="font-size:15px">
<li><span style="font-weight:bold">S</span>ecure (安全)</li>
<li><span style="font-weight:bold">L</span>inkable (リンク可能)</li>
<li><span style="font-weight:bold">I</span>ndexable (インデックス可能)</li>
<li><span style="font-weight:bold">C</span>omposable (再構成可能)</li>
<li><span style="font-weight:bold">E</span>phemeral (一時的な利用)</li>
</ul>

<p>これら従来のWebとネイティブアプリの体験上のメリットを合わせたものが、PWAのメリットとなります。</p>

<h2>Progressive Web Appsが提供する価値</h2>

<p>PWAの提供する価値について、Googleさんのイベントではよく<a href="https://youtu.be/NITk4kXMQDw?t=5m48s" title="PWAs: building bridges to mobile, desktop, and native (Google I/O &#039;18)" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">FIRE</a>という言葉で紹介されていますが、 </p>

<ul style="font-size:15px">
<li><span style="font-weight:bold">F</span>ast: パフォーマンスの良い、軽快な動作</li>
<li><span style="font-weight:bold">I</span>ntegrated: OSと統合されたユーザー体験</li>
<li><span style="font-weight:bold">R</span>eliable: オフラインでも動作する利便性と信頼性</li>
<li><span style="font-weight:bold">E</span>ngaging: Webサイトの価値向上</li>
</ul>

<p>この記事ではもう少しかみ砕いて紹介しましょう。</p>

<p><img src="https://msdnshared.blob.core.windows.net/media/2018/06/PWA_Merit.png" alt="" width="1100" height="455" class="aligncenter size-full wp-image-5515" /></p>

<h3 style="font-weight:bold">発見性</h3>

<p>PWAであれば、アプリを公開するのにアプリストアにわざわざお金を払ってアプリを提出したり、審査を通すための不自由なルールに縛られる必要はありません。これまでのWebアプリと同じようにインターネットに公開しておけば、検索エンジンがクロールして見つけてくれます。</p>

<p>いままでのSEOのスキルがそのまま使える上、Webはアプリストアとは比べものにならない数のユーザーが、比べものにならないくらいの回数、常に検索を行っています。この圧倒的なオポチュニティ（機会）の違いは、自分自身が今日何回Webを検索したか、アプリストアを何回検索したか、比べてみればよくわかるでしょう。</p>

<h3 style="font-weight:bold">インストール可能</h3>

<p>PWAはさまざまなデバイスにインストール可能ですが、そのためにプラットフォームごとに違う開発言語で書き直したりパッケージンクしなおしたりする必要はありません。PWAをサポートしているWebブラウザーであれば、同じアプリケーションをその全部にインストールして使うことができます。</p>

<p>また、&#8221;インストールしなくても使える&#8221;点もメリットです。もともとがWebページなので、ちょっとだけ使ってみるということが可能です。</p>

<p>サービスを試用してみようと思ったときに、&#8221;アプリのインストールが障壁になって利用を中断してしまった&#8221;、という経験は誰にでもあることでしょう。また、スマートフォンでコンテンツを閲覧中に、突然、アプリのストア画面が表示され、アプリのインストールを促されて不快な思いをしたこともあるかと思いますが、そういったことを避けられます。</p>

<p>PWAであれば提供者もユーザーもアプリのインストールについてのネガティブな点を回避することができます。</p>

<h3 style="font-weight:bold">再エンゲージ可能</h3>

<p>従来のWebページであれば、ユーザーがコンテンツから離脱したあとは、再び訪問してくれることを祈るくらいしかできませんでしたが PWAはサーバー側から通知をPushすることができます。</p>

<p>これによりユーザーに即時的な価値を提供できます。例えば、ECショップであればタイムセールの開始であるとか、オークションサイトであればオークションの開始や、最高落札額の更新などです。</p>

<p>通知機能を適切に利用することで、ユーザー側の機会獲得を増やし、再エンゲージを促すことができます。</p>

<p>逆にどうでもいいことを通知しすぎるとユーザーの心象を害するので注意が必要です。特に、初めてページを訪問したユーザーに「プッシュ通知を許可しますか?」というメッセージを表示するのは避けたいところです。</p>

<h3 style="font-weight:bold">ネットワーク非依存</h3>

<p>PWAはオフラインでの使用が可能ですので、ネットワークの状態に左右されないように作ることが可能です。また、常に使用されるアセットをローカルにキャッシュすることで表示のスピードアップや、回線の使用料を減らすことにも貢献します。</p>

<h3 style="font-weight:bold">プログレッシブとレスポンシブ</h3>

<p>PWAはきちんとその思想を理解して開発すれば、低機能なブラウザーやPWAをサポートしないデバイスにもサービスを提供できます。また、さまざまな画面サイズに対応するためのレスポンシブな機能については、WebにはMedia Queries等、そのためのナレッジもリソースも豊富に存在するため、既存のスキルを活かして機能を実装できます。</p>

<h3 style="font-weight:bold">安全</h3>

<p>PWAはWebコンテンツと同じWebブラウザーの強力なサンドボックス内で動作するため、ネイティブアプリのようにユーザーの強い権限で動作しないため、誤動作や悪意のあるコードによってシステムに深刻なダメージを与えることはありません。またhttpsによる接続でのみ動作するのでサーバーとのやりとりを安全に行うことができます。</p>

<h3 style="font-weight:bold">リンク可能</h3>

<p>PWAはインターネット上でユニークな URL をもっており、ハイパーリンクのあるさまざまなところからサービスに接続することができます。PWAを使用するのにアプリ ストアは必要なく、面倒なインストールプロセスも必要ありません。</p>

<p></p>

<p>PWAのメリットは、Webとネイティブ アプリのメリットを合わせたということだけでなく、それらを状況に合わせて取捨選択できることです。</p>

<h2>Progressive Web Appsを実現するAPI</h2>

<p>ここからはPWAを実現するためのAPIと、それらをどのように使ってアプリケーションを構築していくかについて紹介します。</p>

<h3>Service Worker</h3>

<p>PWAを実現する上で中心となる機能を提供するのが、Service Workerです。</p>

<p>Service Workerとは何か？ 端的に言うと、「バックグラウンドで動作する<span style="font-weight:bold">&#8220;プログラミング可能な&#8221;ネットワークプロキシ</span>」です。</p>

<p>Service WorkerはWeb Workerの一つで、Webページのスクリプトとは独立して動作しており、DOMにアクセスしたりすることはできませんが、Webページのネットワークリクエストすべてをインターセプトできます。</p>

<p>つまり、Webページからのリクエストを横取りしてキャッシュしたものを返したり、改ざんしたりといったことができます。そのため localhost、127.0.0.1接続以外はhttpsの使用が必須となります。</p>

<h3>Service Workerが提供する機能</h3>

<p>Service Workerが提供する機能は主に以下の4つです。</p>

<ul style="font-size:15px">
<li>キャッシュ</li>
<li>リクエストのハンドリング</li>
<li>Push通知</li>
<li>バックグラウンド同期</li>
</ul>

<p>これらの機能を図で紹介します。</p>

<h3 style="font-weight:bold">キャッシュとリクエストのハンドリング</h3>

<p>Service WorkerはWebページからのリクエストの中に、自分のキャッシュリストに含まれるアセットを見つけると、レスポンスからこれを取得してキャッシュします。</p>

<p><img src="https://msdnshared.blob.core.windows.net/media/2018/06/SW_Chache01.png" alt="" width="1207" height="546" class="aligncenter size-full wp-image-5525" /></p>

<p>それ以降、Webページからリクエストされたアセットがキャッシュ内に存在する場合は、そのキャッシュされたアセットを返します。ネットワークから取得しないので、アセットの取得は高速に完了し、通信コストは発生しません。</p>

<p><img src="https://msdnshared.blob.core.windows.net/media/2018/06/SW_Chache02.png" alt="" width="1206" height="545" class="aligncenter size-full wp-image-5535" /></p>

<h3 style="font-weight:bold">Push通知</h3>

<p>関連付けられたWebページがアクティブでなくても、サーバーからのPushを受け取り、Notification API等を使用してユーザーに通知を行えます。</p>

<p><img src="https://msdnshared.blob.core.windows.net/media/2018/06/sw_push1.png" alt="" width="1206" height="544" class="aligncenter size-full wp-image-5555" /></p>

<h3 style="font-weight:bold">バックグラウンド同期</h3>

<p>オフライン中にユーザーが行った操作をキャッシュし、</p>

<p><img src="https://msdnshared.blob.core.windows.net/media/2018/06/SW_Offline.png" alt="" width="1207" height="546" class="aligncenter size-full wp-image-5565" /></p>

<p>オンライン時にその内容を同期することができます。</p>

<p><img src="https://msdnshared.blob.core.windows.net/media/2018/06/sw_backgroundsync.png" alt="" width="1205" height="544" class="aligncenter size-full wp-image-5575" /></p>

<p>このように Service Worker は<span style="font-weight:bold">プログラミング可能なネットワークプロキシ</span>として、これまでにないさまざまな機能を提供します。</p>

<p>これらの機能の2018年6月時点の<a href="https://caniuse.com/#search=service%20worker" target="_blank" title="Can I use... Support tables for HTML5, CSS3, etc" data-wpel-link="external" rel="follow external noopener noreferrer">サポート状況</a>は以下のとおりです。</p>

<p><img src="https://msdnshared.blob.core.windows.net/media/2018/06/SW_Browser_support.png" alt="" width="1218" height="496" class="aligncenter size-full wp-image-5585" /></p>

<p>ここからは、Service Workerの具体的使い方について解説していきます。</p>

<h2>Service Workerを使う準備 </h2>

<p>Service Workerを使った開発を行う際に用意しなければならないものがあります。</p>

<p>まず、Service Workerを利用するためのWebアプリケーション、もしくはWebコンテンツが必要です。これはけしてSPA(Single Page Application)のようなアプリケーション然としたものである必要はなく、既存の一般的な Web ページであってもかまいません。</p>

<p>このWebページ、もしくはWebアプリケーションは、htmlやcss、jsや画像に代表されるメディアといった複数のファイルで構成されていると思いますが、それとはべつにService Worker用のJavaScriptファイルをひとつ用意します。ここでは便宜上sw.jsと名付けます。</p>

<p><img src="https://msdnshared.blob.core.windows.net/media/2018/06/webAsser.png" alt="" width="800" class="aligncenter size-full wp-image-5595" /></p>

<p>このService Worker用のJavaScriptファイルはWebコンテンツ側のJavaScriptコードから登録され稼働を開始します。</p>

<p>Service Workerは、自身のファイルが配置された以下のディレクトリに対しスコープを持つので、コンテンツ/アプリケーション全体をキャッシュするなど管理下におきたい場合はWebサイトのルートに配置します。</p>

<h2>Service Workerの登録</h2>

<p>Service Workerの登録はWebコンテンツのJavaScript から行います。</p>

<p>登録に必要なコードは非常にシンプルで、最低限、以下のコードで問題を発生させることなく、Service Workerの登録が行えます。</p>

<div style="width:100%">
<div style="width:600px;background-color:gainsboro;margin:0 auto;padding:10px;font-size:15px">
<div style="text-align:center;width:140px;height:20px;background-color:black;float:right;color:white;margin-top:-10px;margin-right:-10px">Webコンテンツ側</div>
<span style="color:#32CD32">//Service Workerがサポートされているかチェック</span>
if&nbsp;(navigator.serviceWorker)&nbsp;{
&nbsp;&nbsp;&nbsp;<span style="color:#32CD32">//Service Worker を登録</span>
&nbsp;&nbsp;&nbsp;<span style="font-weight:bold;color:fuchsia">navigator.serviceWorker.</span><span style="font-weight:bold;color:blue">register</span><span style="font-weight:bold;color:fuchsia">(&#8216;</span><span style="font-weight:bold;color:blue">/sw.js</span><span style="font-weight:bold;color:fuchsia">&#8216;);</span>
<br />
}
</div>
</div>

<p>&nbsp;<br /></p>

<p>Webコンテンツ側のコードから、navigator.serviceWorker.registerメソッドにより、Service Workerの登録が行われると、Service Worker用のJavaScriptコード（ここではsw.js）ではinstallイベントが発生します。</p>

<div style="width:100%">
<div style="width:600px;background-color:gainsboro;margin:0 auto;padding:10px;font-size:15px">
<div style="text-align:center;width:140px;height:20px;background-color:black;float:right;color:white;margin-top:-10px;margin-right:-10px">sw.js側</div>
<span style="color:#32CD32">//キャッシュするアセットのリスト</span><br />
var <span style="font-weight:bold;color:green">urlsToCache</span> = [<br />
&nbsp;&nbsp;&nbsp;&#8216;/&#8217;,<br />
&nbsp;&nbsp;&nbsp;&#8216;/index.html&#8217;,<br />
&nbsp;&nbsp;&nbsp;&#8216;/css/index.css&#8217;,<br />
&nbsp;&nbsp;&nbsp;&#8216;/script/index.js&#8217;<br />
];<br />
<span style="color:#32CD32">//install イベントのハンドラ</span><br />
<span style="font-weight:bold;color:fuchsia">Self.addEventListener(&#8216;</span><span style="font-weight:bold;color:blue">install</span><span style="font-weight:bold;color:fuchsia">&#8216;, function(event) {</span><br />
&nbsp;&nbsp;&nbsp;event.waitUntil(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#32CD32">//キャッシュを開く</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;caches.open(&#8216;キャッシュの名前&#8217;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.then(function(cache) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#32CD32">//アセットのリストをキャッシュに登録</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return cache.addAll(<span style="font-weight:bold;color:green">urlsToCache</span>);<br />
&nbsp;&nbsp;&nbsp;}));<br />
});
</div>
</div>

<p><br /></p>

<p>install イベントハンドラ内では、キャッシュを開き</p>

<div style="width:100%">
<div style="width:600px;background-color:gainsboro;margin:0 auto;padding:10px;font-size:15px">
<span style="color:#32CD32">//キャッシュするアセットのリスト</span><br />
var urlsToCache = [<br />
&nbsp;&nbsp;&nbsp;&#8216;/&#8217;,<br />
&nbsp;&nbsp;&nbsp;&#8216;/index.html&#8217;,<br />
&nbsp;&nbsp;&nbsp;&#8216;/css/index.css&#8217;,<br />
&nbsp;&nbsp;&nbsp;&#8216;/script/index.js&#8217;<br />
];<br />
<span style="color:#32CD32">//install イベントのハンドラ</span><br />
Self.addEventListener(&#8216;install&#8217;, function(event) {<br />
&nbsp;&nbsp;&nbsp;event.waitUntil(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#32CD32">//キャッシュを開く</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight:bold;color:fuchsia">caches.open(</span><span style="font-weight:bold;color:blue">&#8216;キャッシュの名前&#8217;</span><span style="font-weight:bold;color:fuchsia">)</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.then(function(cache) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#32CD32">//アセットのリストをキャッシュに登録</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return cache.addAll(urlsToCache);<br />
&nbsp;&nbsp;&nbsp;}));<br />
});
</div>
</div>

<p>&nbsp;<br /></p>

<p>キャッシュにアセットのリストを登録します。</p>

<div style="width:100%">
<div style="width:600px;background-color:gainsboro;margin:0 auto;padding:10px;font-size:15px">
<span style="color:#32CD32">//キャッシュするアセットのリスト</span><br />
var <span style="font-weight:bold;color:blue">urlsToCache</span> = [<br />
&nbsp;&nbsp;&nbsp;<span style="color:blue">&#8216;/&#8217;,<br />
&nbsp;&nbsp;&nbsp;&#8216;/index.html&#8217;,<br />
&nbsp;&nbsp;&nbsp;&#8216;/css/index.css&#8217;,<br />
&nbsp;&nbsp;&nbsp;&#8216;/script/index.js&#8217;</span><br />
];<br />
<span style="color:#32CD32">//install イベントのハンドラ</span><br />
Self.addEventListener(&#8216;install&#8217;, function(event) {<br />
&nbsp;&nbsp;&nbsp;event.waitUntil(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#32CD32">//キャッシュを開く</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;caches.open(&#8216;キャッシュの名前&#8217;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.then(function(<span style="font-weight:bold;color:fuchsia">cache</span>) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#32CD32">//アセットのリストをキャッシュに登録</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return <span style="font-weight:bold;color:fuchsia">cache.addAll</span>(<span style="font-weight:bold;color:blue">urlsToCache</span>);<br />
&nbsp;&nbsp;&nbsp;}));<br />
});
</div>
</div>

<p>&nbsp;<br /></p>

<p>Service Workerが登録され、installイベント内の処理が無事に完了すると、次にactivateイベントが発生します。（もしinstallイベント内の処理が失敗した際にはerrorイベントが発生します）</p>

<div style="width:100%">
<div style="width:600px;background-color:gainsboro;margin:0 auto;padding:10px;font-size:15px">
<span style="font-weight:bold;color:fuchsia">self.addEventListener(&#8216;</span><span style="font-weight:bold;color:blue">activate</span><span style="font-weight:bold;color:fuchsia">&#8216;,&nbsp;function(e)&nbsp;{</span><br />
&nbsp;&nbsp;e.waitUntil(<br />
&nbsp;&nbsp;&nbsp;&nbsp;caches.keys().then(function(keyList)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Promise.all(keyList.map(function(key)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(key&nbsp;!==&nbsp;&#8216;キャッシュの名前&#8217;)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;caches.delete(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}));<br />
&nbsp;&nbsp;&nbsp;&nbsp;})<br />
&nbsp;&nbsp;);<br />
<span style="font-weight:bold;color:fuchsia">});</span>
</div>
</div>

<p>&nbsp;<br /></p>

<p>installイベント内で&#8221;しなければいけない処理&#8221;というものは特にないのですが、一般的に古いキャッシュを削除するのに使用されます。このサンプルコードではキャッシュからキーの一覧を取り出し、</p>

<div style="width:100%">
<div style="width:600px;background-color:gainsboro;margin:0 auto;padding:10px;font-size:15px">
self.addEventListener(&#8216;activate&#8217;,&nbsp;function(e)&nbsp;{<br />
&nbsp;&nbsp;e.waitUntil(<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight:bold;color:fuchsia">caches.keys().then(function(</span><span style="font-weight:bold;color:blue">keyList</span><span style="font-weight:bold;color:fuchsia">)&nbsp;{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Promise.all(keyList.map(function(key)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(key&nbsp;!==&nbsp;&#8216;キャッシュの名前&#8217;)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;caches.delete(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}));<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight:bold;color:fuchsia">})<br />
&nbsp;&nbsp;);</span><br />
});
</div>
</div>

<p>&nbsp;<br /></p>

<p>キャッシュの名前（新しく指定された）と比較し、異なるものをすべて削除しています。</p>

<div style="width:100%">
<div style="width:600px;background-color:gainsboro;margin:0 auto;padding:10px;font-size:15px">
self.addEventListener(&#8216;activate&#8217;,&nbsp;function(e)&nbsp;{<br />
&nbsp;&nbsp;e.waitUntil(<br />
&nbsp;&nbsp;&nbsp;&nbsp;caches.keys().then(function(keyList)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;<span style="font-weight:bold;color:fuchsia">Promise.all(keyList.map(function(</span><span style="font-weight:bold;color:blue">key</span>)&nbsp;<span style="font-weight:bold;color:fuchsia">{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight:bold;color:fuchsia">if&nbsp;(</span><span style="font-weight:bold;color:blue">key</span>&nbsp;<span style="font-weight:bold;color:fuchsia">!==&nbsp;&#8216;キャッシュの名前&#8217;)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;caches.delete(</span><span style="font-weight:bold;color:blue">key</span><span style="font-weight:bold;color:fuchsia">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}));</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;})<br />
&nbsp;&nbsp;);<br />
});
</div>
</div>

<p>&nbsp;<br /></p>

<p>上記サンプルコードの、&#8221;キーの一覧と新しく登録されたキャッシュの名前を比較して異なるものをすべて削除してしまう&#8221;、というやり方は少々乱暴かもしれませんので、実際に実装を行う際にはどのようにキャッシュの削除を行うかは十分に考慮してください。</p>

<h3 style="font-weight:bold">なぜ、activateイベントでキャッシュを削除するのか？</h3>

<p>Service Worker自体は、Service Worker用のJSファイルを更新することで再登録されますが、キャッシュが削除されるわけではありません。よって、いずれどこかのタイミングで用済みとなった古いキャッシュを削除する必要が出てきます。</p>

<p>例えば、キャッシュの対象となっているindex.htmlに更新があった場合は、更新前のindex.htmlを保持しているキャッシュを削除しないかぎりユーザーにはいつまでも更新前のindex.htmlが表示されることになります。</p>

<p>Service Worker用のJSファイルが更新されたあと、新しいService Workerはバックグラウンドでインストールされますが、まだ動作はしません。新しいService Workerに制御が移るタイミングは、古いService Workerが制御しているすべてのページが閉じた後からになります。そのためinstallイベントで古いキャッシュを削除してしまうと、まだ動作している古いService Workerはキャッシュを使用できなくなってしまいます。</p>

<p>一方、activateイベントではページの制御が新しいService Workerに移っているので、古いService Workerが使用していたキャッシュを削除することができます。</p>

<h3 style="font-weight:bold">何をキャッシュさせるか？</h3>

<p>Service Workerにキャッシュさせるべきは、App Shellです。App ShellはアプリケーションのUIが機能するために必要な最小限のリソースです。App Shellをローカルにキャッシュすることで、アプリケーションのUI表示と使用可能となるまでの時間を短縮することができ、オフラインでの使用も可能になります。また要件に応じて、キャッシュが有効となるアセット類を指定してもよいでしょう。</p>

<p>しかし、何でもキャッシュさせればよいというものでもありません。例えば、WebGLベースのゲームは、一般的に使用するアセット類のサイズが大きく、これを毎度起動する際にサーバーからダウンロードするのは時間もかかり、通信コストもかさみます。たしかに、これらをキャッシュさせておけば、通信コストを下げ、ゲーム開始までの時間も短縮できます。</p>

<p>しかし、キャッシュストレージの容量には制限があり、また、cacheオブジェクトの代わりに容量の大きいIndexedDBを使用したとしてもクライアントのストレージを占有することになります。</p>

<p>PCなどのストレージ容量の大きいデバイスではあまり問題にならないかもしれませんが、スマートフォンのようなモバイルデバイスではストレージ容量を圧迫することにつながります。よって、なにをキャッシュさせるかは十分に考慮する必要があります。</p>

<h2>リクエストのハンドリング</h2>

<p>Service Workerは有効化(activate)された後、アイドル状態となり、WebページからのリクエストやサーバーからのPushを待ちます。</p>

<p>アイドル状態のとき、制御下にあるWebページでリンクをクリックするなどしてネットワークリクエストが発生するとService Worker ではfetchイベントが発生します。</p>

<div style="width:100%">
<div style="width:600px;background-color:gainsboro;margin:0 auto;padding:10px;font-size:15px">
<span style="font-weight:bold;color:fuchsia">self.addEventListener(&#8216;</span><span style="font-weight:bold;color:blue">fetch</span><span style="font-weight:bold;color:fuchsia">&#8216;,&nbsp;function(e)&nbsp;{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;e.respondWith(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;caches.match(e.request)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.then(function(response)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;response&nbsp;||&nbsp;fetch(e.request);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}));<br />
<span style="font-weight:bold;color:fuchsia">})</span>
</div>
</div>

<p>&nbsp;<br /></p>

<p>fetchイベントハンドラの引数として渡されるオブジェクトに、発生したリクエストが含まれるので、同リクエストがキャッシュ内に存在するのか調べ、</p>

<div style="width:100%">
<div style="width:600px;background-color:gainsboro;margin:0 auto;padding:10px;font-size:15px">
self.addEventListener(&#8216;fetch&#8217;,&nbsp;function(<span style="font-weight:bold;color:blue">e</span>)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;e.respondWith(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight:bold;color:fuchsia">caches.match(<span style="font-weight:bold;color:blue">e</span>.request)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.then(function(response)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;response&nbsp;||&nbsp;fetch(e.request);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}));<br />
})
</div>
</div>

<p>&nbsp;<br /></p>

<p>キャッシュ内にリクエストが存在すればそれを返し、存在しなければfetchメソッドを使用してネットワークにリクエストを投げます。</p>

<div style="width:100%">
<div style="width:600px;background-color:gainsboro;margin:0 auto;padding:10px;font-size:15px">
self.addEventListener(&#8216;fetch&#8217;,&nbsp;function(e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;e.respondWith(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;caches.match(<span style="font-weight:bold;color:blue">e.request</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight:bold;color:fuchsia">.then(function(</span><span style="font-weight:bold;color:green">response</span><span style="font-weight:bold;color:fuchsia">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return</span>&nbsp;<span style="font-weight:bold;color:green">response</span>&nbsp;<span style="font-weight:bold;color:fuchsia">||&nbsp;fetch(</span><span style="font-weight:bold;color:blue">e.request</span><span style="font-weight:bold;color:fuchsia">);</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;}));<br />
})
</div>
</div>

<p>&nbsp;<br /></p>

<p>それぞれの処理結果をリクエスト元のWebコンテンツ側に返します。</p>

<div style="width:100%">
<div style="width:600px;background-color:gainsboro;margin:0 auto;padding:10px;font-size:15px">
self.addEventListener(&#8216;fetch&#8217;,&nbsp;function(e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight:bold;color:fuchsia">e.respondWith(</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;caches.match(e.request)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.then(function(response&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;response&nbsp;||&nbsp;fetch(e.request);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight:bold;color:fuchsia">}));</span><br />
})
</div>
</div>

<p>&nbsp;<br /></p>

<p>この動作により、Webコンテンツ側ではService Workerやキャッシュを意識することなく、これまで通りの方法でページの制作を行うことができます。</p>

<p>また既存のWebコンテンツにService Workerの機能を追加する場合も、Service Workerを登録するためコードを追加する以外の作業は基本的に必要ありません。</p>

<p>de:code 2018のセッション動画で<a href="https://youtu.be/mk5qkxekFUs?t=20m3s" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Service Workerを追加するデモ</a>を行っていますので、ぜひ実際の動作をご覧ください。</p>

<h2>Web App Manifest</h2>

<p>Web App Manifestは、デバイスのブラウザーによって[ホーム画面に追加]される際のアイコンや、ホーム画面から起動した際のスプラッシュアイコンや背景色、アプリケーションが動作するウィンドウのスタイルを定義します。</p>

<p>manifestは、json形式で記述し、以下のようなlinkタグをWebコンテンツ/アプリケーション側に追加して参照させます。</p>

<div style="width:100%">
<div style="width:600px;background-color:gainsboro;margin:0 auto;padding:10px;font-size:15px;text-align:center">
&lt;<span style="font-weight:bold;color:fuchsia">link</span> rel=&#8221;<span style="font-weight:bold;color:blue">manifest</span>&#8221; href=&#8221;<span style="font-weight:bold;color:blue">/manifest.json</span>&#8220;&gt;
</div>
</div>

<p>&nbsp;<br /></p>

<p>Web App Manifestについては、詳しい解説が<a href="https://developer.mozilla.org/ja/docs/Web/Manifest" target="_blank" title="Web App Manifest | MDN" data-wpel-link="external" rel="follow external noopener noreferrer">MDN</a>にあるので、そちらを参照することをお勧めしますが、以下に簡単な説明を兼ねたサンプルを掲示します。</p>

<div style="width:100%">
<div style="width:600px;background-color:gainsboro;margin:0 auto;padding:10px;font-size:15px">
{<br />
&nbsp;&nbsp;&nbsp;&#8220;lang&#8221;:&nbsp;&#8220;ja&#8221;,<span style="color:gray">&nbsp;←&nbsp;言語</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&#8220;name&#8221;:&nbsp;&#8220;The enemy of galaxy&#8221;,<span style="color:gray">&nbsp;←&nbsp;アプリケーションの名前</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&#8220;short_name&#8221;:&nbsp;&#8220;T.E.O.G&#8221;,<span style="color:gray">&nbsp;←&nbsp;アプリケーションのショートネーム</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&#8220;start_url&#8221;:&nbsp;&#8220;/?utm_source=pwd&#8221;,<span style="color:gray">&nbsp;←&nbsp;開始するときの&nbsp;URL&nbsp;(※1)</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&#8220;display&#8221;:&nbsp;&#8220;standalone&#8221;,<span style="color:gray">&nbsp;←&nbsp;ウィンドウのスタイル</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&#8220;background_color&#8221;:&nbsp;&#8220;black&#8221;,<span style="color:gray">&nbsp;←&nbsp;背景色</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&#8220;description&#8221;:&nbsp;&#8220;銀河に平和を取り戻すためのゲームです。&#8221;,<span style="color:gray">&nbsp;←&nbsp;説明文</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&#8220;orientation&#8221;:&nbsp;&#8220;portrait&#8221;<span style="color:gray">&nbsp;←&nbsp;画面の向き</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&#8220;icons&#8221;:&nbsp;[{<span style="color:gray">&nbsp;(※2)</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;src&#8221;:&nbsp;&#8220;images/homescreen48.png&#8221;,<span style="color:gray">&nbsp;←&nbsp;画像ファイルのパス</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;sizes&#8221;:&nbsp;&#8220;48&#215;48&#8221;,<span style="color:gray">&nbsp;←&nbsp;サイズ</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;type&#8221;:&nbsp;&#8220;image/png&#8221;<span style="color:gray">&nbsp;←&nbsp;画像の種類</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;src&#8221;:&nbsp;&#8220;images/homescreen72.png&#8221;,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;sizes&#8221;:&nbsp;&#8220;72&#215;72&#8221;,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;type&#8221;:&nbsp;&#8220;image/png&#8221;<br />
&nbsp;&nbsp;&nbsp;}]<br />
}
</div>
<div style="width:600px;margin:0 auto">
<p style="margin-top:10px">(※1)Google Analytics等を使用しているときはクエリーストリングを使用することでPWAとして起動されたのか、ブラウザからページにアクセスしたのか判断が可能</p>
<p>(※2)iPhoneやiPadでアイコンが反映されない場合は、apple-touch-iconを使用</p>
</div>
</div>

<p>de:code 2018のセッション動画で<a href="https://youtu.be/mk5qkxekFUs?t=27m24s" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Web App Manifest を追加するデモ</a>を行っているので、ぜひ実際の動作をご覧ください。</p>

<h3>現在のWindows 10バージョン 1803のProgressive Web Appsの動作</h3>

<p>なお、2018年6月現在のWindows 10バージョン1803(OS ビルド 17134.112)では、残念ながらWeb App Manifestによるウィンドウの制御は有効になりません。</p>

<p>例えば、Windows 10のMicrosoft EdgeでProgressive Web Appsのページをタスクバーにピン留めして起動したとしてもWebブラウザーのUIを表示したまま起動してきます。</p>

<p>Windows 10でProgressive Web Appsにそれらしい動作をさせるにはUWP(Universal Windows Platform)アプリでラップする必要があります。</p>

<p>しかし、Windows 10の次のアップデートでは、Web App Manifestのdisplayの設定に対し、PWAのウィンドウは<a href="https://youtu.be/6fb-t9ffDvo?t=10m5s" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">以下のような表示になるそうです。</a></p>

<p><img src="https://msdnshared.blob.core.windows.net/media/2018/07/win10display.png" alt="" width="1283" height="449" class="aligncenter size-full wp-image-5605" />
<br />&nbsp;</p>

<h2>マイクロソフトのProgressive Web Appsへの<br />取り組み</h2>

<p>Windows 10の[Microsoft Store]から Progressive Web Appsとして作られたアプリを入手することができます。</p>

<p>Web App Manifestのところで書いたとおり、現在のWindows 10にプレーンな Progressive Web Appsをインストールしても、ネイティブアプリのような外観にはなりません。そのためMicrosoft Storeから入手できるProgressive Web AppsはUWPアプリにラップされています。</p>

<h3>MicrosoftストアでのProgressive Web Appsの公開</h3>

<p>MicrosoftストアでProgressive Web Appsを公開するには 2つの方法があります。</p>

<p>1つめがBingによる自動インデックスによる登録と、2つめがProgressive Web Appsの提供者がMicrosoftストアにProgressive Web Appsを提出するセルフパブリッシングです。</p>

<p>以下でこの 2つの方法について紹介します。</p>

<h3>Bingによる自動インデックス(BETA)</h3>

<p>現在はまだBETAの状態ですが、BingがWeb上のProgressive Web Appsを検出し、レビューを行い、自動的にMicrosoftストアに公開します。</p>

<p>Bingに自動インデックスされるための条件は、現在のところ以下のようなものがあります。</p>

<ul>
<li>HTTPS、セキュアなエンドポイント</li>
<li>高品質の manifest</li>
<li>オフラインサポート</li>
<li>ストアの審査をパス
   <ul>
      <li>デジタルグッズを販売しないこと</li>
      <li>アダルトコンテンツを含まないこと</li>
      <li>不快なコンテンツは不可</li>
</ul></li>
<li>Windowsならではの差別化がされている</li>
</ul>

<p>上記リストで、最後の&#8221;Windowsならではの差別化がされている&#8221;というのは、少しわかりづらいかもしれません。</p>

<p>Microsoft Storeで公開されるProgressive Web Appsは、UWPアプリにラップされるので<a href="https://docs.microsoft.com/ja-jp/uwp/api/" target="_blank" title="Windows UWP Namespaces" data-wpel-link="external" rel="follow external noopener noreferrer">WinRT (Windows Runtime) API</a>を使用することができます。</p>

<p>つまりWinRT APIを使用することで、Windows 10で使用した際には、純粋なProgressive Web Appsからはアクセスできないプラットプラットフォームやハードウェアリソースの機能を使用することができるため、これらを利用した機能を実装することで差別化を図ることができます。</p>

<h3>Microsoftストア向けProgressive Web Appsの検証</h3>

<p>決して、Progressive Web Appsの検証に限ったものでなく、ましてやMicrosoftストア向けのWebコンテンツ用に限定するものではありませんが、WebサイトやProgressive Web Appsの品質をチェックするための<a href="https://sonarwhal.com/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">sonarwhal</a>というサービスが公開されています。</p>

<p><a href="https://sonarwhal.com/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="https://msdnshared.blob.core.windows.net/media/2018/07/sonarwhal.png" alt="" width="400" class="aligncenter size-full wp-image-5625" /></a></p>

<p>sonarwhalはProgressive Web AppsがMicrosoftストア向けの準備がてきているか、だけでなく、一般的なWebサイトやアプリケーションのパフォーマンスやユーザーエクスペリエンス、セキュリティの向上の役に立つ情報を提供してくれます。</p>

<h3>Bingに検出されないようにするには</h3>

<p>インターネットで公開しているProgressive Web AppsをMicrosoftストアから配布されたくない場合、Progressive Web Appsが以下のいずれかの条件に合致していた場合、Bingは自動インデックスを行いません。</p>

<ul>
<li>manifest なし</li>
<li>https なし、もしくは オフラインで動作しない</li>
<li>Robot.txtファイルが設定されている</li>
<li>manifestのdisplay設定がbrowser</li>
</ul>

<p>既に Microsoftストアで公開されているものを取り消したい場合は、アプリを削除するよう <a href="reportapp@microsoft.com" data-wpel-link="internal">reportapp@microsoft.com</a>宛にサービスリクエストを出します。</p>

<h3>セルフパブリッシングによるMicrosoftストアでの公開</h3>

<p>Bingの自動インデックスに期待するのではなく、明示的にMicrosoftストアでProgressive Web Appsを公開するには<a href="https://developer.microsoft.com/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">dev.microsoft.com</a>で開発者アカウントを取得し、パッケージ(appx)化してMicrosoftストアに提出します。アプリの内容がMicrosoftストアの審査をパスすればMicrosoftストアで公開されます。</p>

<p>Progressive Web Appsをパッケージ化するには以下の方法があります。</p>

<ul>
<li><a href="https://visualstudio.microsoft.com/ja/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Visual Studio 2018</a> を使用する</li>
<li><a href="https://www.pwabuilder.com/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">PWABuilder</a> を使用する</li>
<li><a href="https://github.com/pwa-builder/ManifoldJS/releases" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">pwa-builder CLI</a> を使用する</li>
</ul>

<h3 style="font-weight:bold">PWABuilder</h3>

<p><a href="https://www.pwabuilder.com/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="https://msdnshared.blob.core.windows.net/media/2018/07/PWABuilder.png" alt="" width="400" class="aligncenter size-full wp-image-5635" /></a></p>

<p>PWABuilderはインターネットにホストされているサービスで、同じくインターネットにホストされているWebアプリケーションのためのmanifestファイルやService Workerのコード、Service Workerを登録するためのコードを生成します。</p>

<p>また、UWPのHostedアプリのパッケージも生成できるので、Progressive Web AppsをMicrosoftストアで公開する際にはこれをストアに提出します。</p>

<p>PWABuilderを使用した既存のWebアプリケーション用のmanifestファイルやService Workerのコードを生成する手順については de:code 2018 の
<a href="https://youtu.be/mk5qkxekFUs?t=35m19s" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">セッション動画のデモ</a>をご覧ください。</p>

<h3 style="font-weight:bold">Windows ストア(UWP) アプリの価値</h3>

<p>前述しましたが、Progressive Web AppsをUWPアプリ(<a href="https://msdn.microsoft.com/en-us/magazine/mt797652.aspx" target="_blank" title="UWP Apps - Develop Hosted Web Apps for UWP" data-wpel-link="external" rel="follow external noopener noreferrer">Hosted Web アプリ</a>)としてラップすることで WinRT が提供するすべての機能を利用することができます。</p>

<p>これは予定表やアドレス帳といったプラットフォームが提供するソフトウェア的なリソースはもちろん、USBやセンサー類といったハードウェアリソースも含まれます。</p>

<p>アプリケーションが通常のWebブラウザー上で動作しているのか、UWPで動作しているかは JavaScriptのif文で簡単に判断できるので、WinRT APIにアクセスするためのコードをインターネットでホストされているコンテンツに含めておくことができます。</p>

<div style="width:100%">
<div style="width:600px;background-color:gainsboro;margin:0 auto;padding:10px;font-size:15px">
//UWP として動作しているかどうか<br />
if(window.Windows){<br />
&nbsp;&nbsp;&nbsp;//セカンダリータイルをピン留めする<br />
&nbsp;&nbsp;&nbsp;tile&nbsp;=&nbsp;new&nbsp;Windows.UI.StartScreen.SecondaryTile(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tileId,&nbsp;text,&nbsp;text,&nbsp;&nbsp;activationArguments,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newTileDesiredSize,&nbsp;logoUri);<br />
}
</div>
</div>

<p><br /></p>

<p>JavaScriptで記述したUWPから,WinRT APIを使用するサンプルコードは以下に豊富に用意されているので、Windows 10限定となってしまいますが、純粋なProgressive Web Appsの機能だけでは実現できない要件がある場合は、こういった方法もあるということを覚えておくとよいかもしれません。</p>

<p><a href="https://developer.microsoft.com/ja-jp/windows/samples" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">・コードサンプル &#8211; Windows アプリの開発</a></p>

<p>Visual Studio 2018を使用してProgressive Web AppsをUWPでラップし、WindowsRT APIを使用する方法については、de:code 2018 の<a href="https://youtu.be/mk5qkxekFUs?t=42m9s" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">セッション動画のデモ</a>をご覧ください。</p>

<p>その他、Progressive Web AppsをUWPとしてMicrosoftストアに公開することで、Microsoftストアの提供するマーケティングデータ (ダウンロード数、ユーザーの性別、年齢層、国、etc.)や、決済のためのストアのAPIが利用できたり、人気があればMicrosoftストアのトップページに掲示されたり、とさまざまなメリットもあります。</p>

<p>しかも、Hostedアプリであれば、共通のコンテンツでありながら純粋なままのProgressive Web Appsがインターネットでホストされているので、アプリストアを通さない場合のメリットも享受できます。</p>

<p>【参考】<br />
<a href="https://developer.microsoft.com/ja-jp/windows/pwa" target="_blank" style="font-size:15px" data-wpel-link="external" rel="follow external noopener noreferrer">・Windows デベロッパーセンター &#8211; PWAとWindows10</a>
</p>

<p>この記事では、UWPのHostedアプリについて紹介しましたが、Apache Cordovaでもさまざまなモバイル プラットプラットフォーム向けに Hostedアプリを開発することができます。興味のある方は以下の記事をご覧ください。</p>

<p><a href="https://docs.microsoft.com/en-us/visualstudio/cross-platform/tools-for-cordova/first-steps/create-a-hosted-app?view=toolsforcordova-2015" target="_blank" style="font-size:15px" data-wpel-link="external" rel="follow external noopener noreferrer">・Create a hosted web app using Apache Cordova</a></p>

<h2>Progressive Web Appsの価値を高める API</h2>

<p>ここまでWindows 10で動作するUWPアプリでラップされたProgressive Web Appsの紹介をしていましたが、ここからは再びプレーンな Progressive Web Appsについてです。</p>

<p>Progressive Web Appsは、ネイティブアプリのような体験を提供しますが、WebアプリケーションなのでWebブラウザーの機能を超えて動作することはできません。</p>

<p>例えば、表示速度や動作速度はネイティブアプリと比較するとどうしても劣ります。</p>

<p>しかし、Webブラウザーで新しくサポートされた以下のような機能を使用すれば、その能力的な差を縮めることができます。これまでの Webコンテンツにはなかった新しい体験をユーザーに提供したり、決済の仕組みもWeb標準のAPIを使用してこれまでよりも少ない工数で組み込むことができるので、これらを使用してアプリケーションの価値を高めることができます。</p>

<ul>
<li><span style="font-weight:bold;font-size:15px"><a href="https://www.w3.org/TR/css3-namespace/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">CSS3</a></span>
3D Transform関連等GPUを使用する設定があり、これを意識的に利用することで描画速度を向上させることができます。
</li>
<li><span style="font-weight:bold;font-size:15px"><a href="https://webassembly.org/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">WebAssembly</a></span>
C言語などで記述し、あらかじめコンパイルしたものをWebブラウザーで動作させるため高速な計算が可能となります。
</li>
<li><span style="font-weight:bold;font-size:15px"><a target="_blank" data-wpel-link="internal">WebVR</a></span>
VRデバイスの提供するAPIをサポートし、ユーザーによりImmersiveな体験を提供できます。
</li>
<li><span style="font-weight:bold;font-size:15px"><a href="https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/paymentrequest/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Payments</a></span>
決済画面その他、支払いに関する機能を提供します。これとPaypalやStripeなどが提供する決済用のAPIを繋げれば少ない工数で独自に決済期の機能を実装できます。自前の決済の仕組みがあれば、もう何かを販売するたびにアプリ ストアに使用料を支払う必要はありません</li>
</ul>

<p>この他にも、最新のWebブラウザーにはこれまでできなかった機能が日々搭載されてきます。そういった新機能をいち早く利用できるのも、逆にレガシーなWebブラウザーには引き算した機能を提供できるのもProgressive Web Appsの良いところです。(もちろん、そう作れば、ですが)</p>

<h1>Progressive Web Appsの位置づけ</h1>

<p>PWAことProgressive Web Appsは「ネイティブアプリのような体験を提供する」という言葉が独り歩きしてしまい、まるで「ネイティブアプリを置き換える」といった印象を持っている人も多いようです。とはいえ、「ネイティブアプリを置き換えることはできない」というのも真ではないでしょう。</p>

<p>例えば、スマートフォンアプリには、アプリとしてインストールさせるためだけに外側をWeb Viewでラップしたいわゆる「ガワアプリ」と呼ばれるものがあります。こういったものは今後はProgressive Web Appsに置き換えられていくでしょう。</p>

<p>実際にイベントサイトや、カンファレンスのセッションスケジュールの部分をPWA化してユーザーが持ち歩けるようにしているサイトはすでにいくつか存在します。</p>

<ul>
<li><a href="https://abc.android-group.jp/2018s/" target="_blank" style="font-size:15px" data-wpel-link="external" rel="follow external noopener noreferrer">ABC 2018 Spring | 日本最大級のAndroidデベロッパーの祭典</a></li>
<li><a href="https://ngjapan.org/" target="_blank" style="font-size:15px" data-wpel-link="external" rel="follow external noopener noreferrer">ng-japan &#8211; The Angular conference in Tokyo, Japan (2018/6/16)</a></li>
</ul>

<p>こういったものもProgressive Web Appsが出てくる以前はWebページとは別にスマートフォン用のアプリを、場合によってはプラットフォームごとに別々の言語で開発し、それぞれのアプリストアに提出して審査を受けるといったことをしていました。</p>

<p>Webページとアプリの開発が共通化でき、配布の手間もかからないということは予算や時間的にも非常に大きなメリットがあります。</p>

<p>しかし、Webブラウザー内のJavaScriptからアクセスできないプラットフォームの機能を利用するアプリケーションや、高速な動作や描画を必要とする用途には今後もネイティブ アプリが選択されることでしょう。</p>

<p><img src="https://msdnshared.blob.core.windows.net/media/2018/07/PWA_position.png" alt="" width="1141" height="292" class="aligncenter size-full wp-image-5645" /></p>

<p>Progressive Web AppsはWebアプリケーションとネイティブアプリの体験的なメリットを受け継ぎ、ちょうどその中間に位置し、その隙間を埋めるものです。</p>

<p>Webのページではpoorだったもの、逆にネイティブアプリではtoo muchだったものが、Progressive Web Appsには最適なのかもしれません。</p>

<p>少し作って試すだけの実装ならそれほど難しくありませんので、気になる人はぜひProgressive Web Appsを作ってみることをお勧めします。</p>

<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>/osamum_ms/25709/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>「改めまして、Progressive Web Appsと申します」── Web UXの新たな基準を考える</title>
		<link>/uskay/25391/</link>
		<pubDate>Thu, 19 Apr 2018 03:23:45 +0000</pubDate>
		<dc:creator><![CDATA[宇都宮佑亮]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[PWA]]></category>
		<category><![CDATA[Progressive Web Apps]]></category>
		<category><![CDATA[Service Worker]]></category>
		<category><![CDATA[UX]]></category>
		<category><![CDATA[Webアプリ]]></category>

		<guid isPermaLink="false">/?p=25391</guid>
		<description><![CDATA[Progressive Web Appsというワードが世に出て約2年半が経ちました。2015年10月に開催されたChrome Dev SummitにてFlipkartの事例をもってお披露目となったそのコンセプトは、201...]]></description>
				<content:encoded><![CDATA[<p><strong>Progressive Web Appsというワードが世に出て約2年半が経ちました。</strong>2015年10月に開催されたChrome Dev Summitにて<a href="https://www.youtube.com/watch?v=StdKz32M1RM" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Flipkartの事例</a>をもってお披露目となったそのコンセプトは、2018年現在までに徐々に成功事例を増やしながらWeb界隈の注目を集め、ついに先日（忘れもしない2018年3月30日！）iOS 11.3からiOSデバイスでも一部の機能が利用できるようになるまで成長しました。これは、まるで進学する我が子を見ているかのような、新年度にふさわしい晴れやかなニュースですし、<strong>いい機会なので PWAとは何かを改めて振り返ってみようと思います。</strong></p>

<p><img src="/wp-content/uploads/2018/04/pwa01.jpg" alt="pwa01" /></p>

<h2>Webに足りなかったもの</h2>

<p>私はWebが大好きです。リンクを1つクリックしたら（インストールなど煩わしい手続きなしで）すぐに新しいコンテンツを読めるのは最高の体験だなと常日頃感じています。ただし、<strong>今までのWebアプリのユーザー体験は決して最適なものではないとも思っています。</strong>たとえば以下のような体験をした覚えはありませんか？</p>

<ul>
<li>朝の満員電車でも情報収集に勤しむ現代のビジネスパーソンのあなた。つり革に捕まりながらなんらかの記事コンテンツを見ようとリンクをタップする</li>
<li>途端にHTMLのレスポンス待ちで真っ白な画面。レスポンスが返ってきたと思ったら今度はWebアプリ側のローディングGIFが動き出す。</li>
<li>しばらく待つとテキストが表示され読み始めるものの、時間差で画像が差し込まれレイアウトがずれる（どこを読んでいたんだっけ？）。極めつけは全画面広告が画面を占拠し、嫌になってそっとブラウザを閉じる（代わりにソーシャルアプリやゲームアプリを起動する）。</li>
</ul>

<p>このように世に出回っている多くのWebアプリはパフォーマンスに課題があります。特に、さまざまなスペックなデバイスがあらゆる環境で利用されるモバイルにおいては、Webアプリは単純に耐えられないくらい遅く、実測で3G回線と同等な環境における平均ページロード時間は19秒もかかっているという統計もあります[1]。 <strong>Webアプリはとにかくこのパフォーマンスをどうにかしなければなりません。</strong></p>

<p>一方ですでにネイティブ アプリに慣れ親しんでいるユーザーの期待値を満たすためには、パフォーマンスを改善するだけでは十分ではありません。</p>

<ul>
<li>ホーム画面にアイコンを追加したり</li>
<li>プッシュ通知がタイミングよく送られてきたり</li>
<li>オフラインでも動作する信頼性だったり</li>
</ul>

<p>「ユーザー体験の基準」がどんどん上がっていくなか、Webアプリだけがこのような体験を提供できずに取り残されている状況がずっと続いていました。<strong>時代に合わせて、ユーザーが求める機能性もWebアプリで実現できなければならないのです。</strong></p>

<h2>PWAはベストプラクティス集である</h2>

<p>そこで満を持して登場したのがPWAです。PWAと聞くと何かを特定の技術を指すものと思われるかもしれませんが、実はそのコンセプトは幅広く、どちらかというと前述した <strong>Webアプリ本来の課題を解決し、よりよいユーザー体験を実現するためのベストプラクティス集のようなものです。</strong>Googleが提供している<a href="https://developers.google.com/web/progressive-web-apps/checklist" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Progressive Web App Checklist</a>
なるものがあり詳細な内容はそちらを確認いただければと思いますが、PWAのコンセプトをざっくり申し上げると以下となります。</p>

<ul>
<li><strong>とにかくパフォーマンスいいWebアプリを作りましょう。</strong>SPAでもSPAじゃなくても、どんなフレームワーク使っても使わなくても、なんでもいいので、表示が速くて画面遷移がスムーズなものにしてユーザーに好かれましょう。</li>
<li>また、最新のWeb APIを積極的に使って、機能性も身につけましょう。たとえば、Webアプリをホーム画面に追加できるようにしたり、オフラインでも動作するようにしたり。<strong>そんな今までWebアプリでは実現できなかった機能が実装できるようになったんだから、やらない手はないでしょう？</strong></li>
</ul>

<p>少し上記でも触れていますが、PWAはあくまでベストプラクティス集なので特定のサードパーティーフレームワークやライブラリには依存しません。世の中には ReactやAngularを使ったPWAもありますし、Vanilla JavaScriptなPWAもあります。また、サーバーサイドの構成には一切言及しません。<strong>したがって技術スタックを変えずとも適用可能なベストプラクティスでありますし、一度に全部を適用するのではなく段階的に（= Progressively）最適化することもできます。</strong></p>

<p>以下の項目でPWAの特徴をより具体的に見ていきます。</p>

<h3>ハイパフォーマンス</h3>

<p>何より重要であり最も難しいテーマとなります。パフォーマンスの基準としては、2015年にChromeチームが発表したユーザー中心に考えるパフォーマンスモデルである<strong>RAIL</strong>[2]を前提に考えていただければ間違いありませんが、各Webアプリの特性や環境に応じてそれぞれのサービスごとに <strong>Performance Budget</strong>（ロード時間やファイルサイズ等の上限を決め、それを「予算」として管理する）を設けることをオススメします。たとえば、2017年のChrome Dev SummitでChromeチームが推奨したPerfromance Budgetは、<strong>TTI（Time to interactive)を5秒以内</strong>、それを実現するために<strong>クリティカルパスのファイルサイズを170KB以内に収める</strong>というものです。[3][4]</p>

<p>何事もまずは現状分析から。Webアプリのパフォーマンス測定やプロファイリングをする<a href="https://developers.google.com/web/tools/lighthouse/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Lighthouse</a>や<a href="https://developers.google.com/web/tools/chrome-devtools/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Chrome DevTools</a>等のツールを使って現状の評価とボトルネックを確認し、対応すべきポイントを決めて最適化を進めます。その後は<a href="https://calibreapp.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Calibre</a>や<a href="https://speedcurve.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">SpeedCurve</a>といったパフォーマンスモニタリングツールを利用して定点観測するといいでしょう。</p>

<p><img src="/wp-content/uploads/2018/04/pwa02.png" alt="pwa02" /></p>

<p>ハイパフォーマンスなPWAを作るためのデザインパターンである<a href="https://developers.google.com/web/fundamentals/performance/prpl-pattern/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">PRPLパターン</a>もまた参考にすべき方式です。PRPLパターンは<strong>Push 、Render、Pre-cache、Lazy-load</strong>の頭文字を取ったもので、主に<a href="https://developers.google.com/web/fundamentals/architecture/app-shell?hl=ja" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">App Shell モデル</a>やSPAを採用したWebアプリのために用意されたパターンですが、それ以外の構成に関してもパフォーマンス向上のヒントとなる点が多くあります。</p>

<ul>
<li><strong>Push/Render:</strong> 初期描画に必須なリソースを<a href="https://tools.ietf.org/html/rfc7540#section-8.2" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTTP/2 Server Push</a>するか <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">link rel=preload</a> を利用することで先行取得します。そしてそのリソースを利用し、特にAbove the fold [5] (スクロールしないで見える範囲)を優先してレンダリングします。</li>
<li><strong>Pre-cache:</strong> 次ページ（またはルート）で使用するであろうリソースを先読みします。これには<a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Service Worker</a>を利用するといいでしょう。</li>
<li><strong>Lazy-load:</strong> 初期描画に必要なもの以外はすべてLazy-loadします。SPAであれば別ルートの取得がこちら該当しますし、スクロールに合わせたフラグメントの取得であれば<a href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Intersection Observer API</a>を利用するといいでしょう。</li>
</ul>

<p>上記のとおり、Webアプリでもパフォーマンスをあげるためのツールやデザインパターンなど、使えるナレッジが多くたまってきました。ぜひともこれらを利用してハイパフォーマンスなWebアプリの開発を実現してください。</p>

<h3>ホーム画面に追加</h3>

<p><a href="https://developer.mozilla.org/en-US/docs/Web/Manifest" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web App Manifest</a>を実装するとWebアプリをホーム画面に追加できるようになります。以下のようなJSON形式のマニフェストファイルを用意し、</p>

<p></p><pre class="crayon-plain-tag">{
   "name": “PWA Demo Application”,    
   "short_name": “PWA demo”,
    "icons": [{
        "src": “/assets/icon.png”, "sizes": “192x192”
     }],
    "start_url": “/index.html”,
    "display": “standalone”,
    "scope": “/”
}</pre><p></p>

<p>link タグでページにひも付けた上で、Service Workerをインストールすると、</p>

<p></p><pre class="crayon-plain-tag">&lt;link rel="manifest" href="/manifest.json"&gt;

&lt;script&gt;
if ('serviceWorker' in navigator)    
   navigator.serviceWorker.register('/sw.js')
&lt;/script&gt;</pre><p></p>

<p>このようにホーム画面へ追加を促すプロンプトが上がってきます。ホームに追加した後はフルスクリーンで起動しますし、Androidの場合は1つの アプリとしてみなされディープリンクまで可能です。</p>

<p><img src="/wp-content/uploads/2018/04/pwa03.gif" alt="pwa03" /></p>

<p>1点補足すると、この「ホーム画面に追加」は強力ですが、よりユーザーに気持ちよく追加してもらえるように、<strong>意味のあるタイミングでプロンプトを表示するとさらにいいでしょう。</strong>これを実現するためにぜひとも<code>onbeforeinstallprompt</code>イベントハンドラーを利用してください。</p>

<p><code>onbeforeinstallprompt</code>イベントハンドラーはプロンプトが表示される直前に呼び出されます。そのタイミングでプロンプト表示が適切でなければ表示をキャンセルし、別の任意のタイミングで表示することができます。たとえば、画面上に独自の「ホームに追加アイコン」を作成し、それの <code>onclick</code>のイベントハンドラ内でプロンプトを表示させることも可能です。</p>

<p></p><pre class="crayon-plain-tag">var deferredPrompt;
window.addEventListener('beforeinstallprompt', (e) =&gt; {
  console.log('beforeinstallprompt Event fired');
  // デフォルトのタイミングでは表示させない
  e.preventDefault();
  // Eventオブジェクトを保存しておく
  deferredPrompt = e;
  return false;
});
// どっか別のタイミングで...
deferredPrompt.prompt();</pre><p></p>

<p>また執筆時点での最新の<a href="https://www.google.com/chrome/browser/canary.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Chrome Canary</a> (67.0.3394.0)ではプロンプト表示形式を以下のように変更して、ホームに追加の体験をより良くすべく機能検証をしています。ポイントはページ下部に表示されるバナーがコンテンツの邪魔にならないサイズに調整され、PWAが追加済であればそのディープリンク用のバナーに差し替えます。また、前述の<code>prompt</code>関数を利用してユーザーのインタラクションに応じてプロンプトを表示する際は、モーダル表示に切り替わります。</p>

<p><img src="/wp-content/uploads/2018/04/pwa04.png" alt="pwa04" /></p>

<h3>オフライン対応</h3>

<p>ハイパフォーマンスの解説でも少し登場した<strong>Service Worker</strong> と <a href="https://developer.mozilla.org/en-US/docs/Web/API/Cache" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Cache API</a>を利用することでWebアプリをオフラインで実行することが可能になります。Service Workerとはオリジン単位（またはパスの粒度）でインストール可能なJavaScriptで書かれたクライントサイドプロキシのことで、ページ内で発生するHTTPリクエスト / レスポンスを監視したり、それを書き換えたり、必要に応じてリソースを先読みすることもできます。これとCache APIというHTTPリクエスト/ レスポンスオブジェクトをKey-Value形式で保存できるAPIを組み合わせることで、<strong>オフライン時でもあらかじめキャッシュしておいたレスポンスを利用すことができるようになるわけです。</strong></p>

<p><img src="/wp-content/uploads/2018/04/pwa05.png" alt="pwa05" /></p>

<p>このService WorkerとCache APIの組み合わせは<a href="https://developers.google.com/web/fundamentals/primers/service-workers/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">「Service Worker の紹介」</a>に記載の方法で使用することができますが、より汎用的な使い方をまとめた<a href="https://developers.google.com/web/tools/workbox/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Workbox</a>というライブラリを利用するのも1つの手です。Workbox を利用すると実装が煩雑になる、特定のファイルのラインタイムキャッシュも以下のようにシンプルに記述することができます。</p>

<p></p><pre class="crayon-plain-tag">workbox.routing.registerRoute(
  new RegExp('.*\.js'),
  workbox.strategies.networkFirst()
);</pre><p></p>

<p>Workboxはその他にも、<a href="https://developers.google.com/web/tools/workbox/modules/workbox-precaching" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ファイル単位でリビジョンを付与したPrecaching</a>、<a href="https://developers.google.com/web/tools/workbox/modules/workbox-cache-expiration" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Expirationの定義</a>や<a href="https://developers.google.com/web/tools/workbox/guides/enable-offline-analytics" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Background Syncを利用したオフライン時の Google Analytics の計測</a>などの機能も提供します。</p>

<p>オフラインの戦略はWebアプリの特性に応じて変わってくるものです。例えばニュースサイトであれば、トップページに出ている注目記事をすべて先読みし、オフラインでも読めるようにすることも考えられますし、ECサイトであればまた別の戦略が適している場合もあるでしょう。電波状況が比較的良好な日本においても、速度制限や電車内などオフライン（または不安定なネットワーク）になりえるユースケースは存在しますし、最低限でも <a href="https://www.google.co.jp/search?q=Offline+Dinosaur&amp;source=lnms&amp;tbm=isch&amp;sa=X&amp;ved=0ahUKEwiHmNqQ05vaAhUDOJQKHUkjBh0Q_AUICigB&amp;biw=1745&amp;bih=1003" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Offline Dinasour</a>はユーザーに見せないようにフォールバックページを用意すべきです。</p>

<h3>その他のWeb API</h3>

<p>以下にPWAを実装する上で注目すべきその他のWeb APIを列挙します。</p>

<ul>
<li><strong>プッシュ通知:</strong> <a href="https://developer.mozilla.org/en-US/docs/Web/API/Push_API" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Push API</a> / <a href="https://developer.mozilla.org/en-US/docs/Web/API/notification" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Notification API</a></li>
<li><strong>自動ログイン:</strong> <a href="https://developer.mozilla.org/en-US/docs/Web/API/Credential_Management_API" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Credential Management API</a></li>
<li><strong>支払いフォームの強化:</strong> <a href="https://developer.mozilla.org/en-US/docs/Web/API/Payment_Request_API" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Payment Request API</a></li>
</ul>

<p>上記のAPIも組み合わせることによって、リエンゲージメント性の向上や商品の購買フローを最適化することができます。</p>

<h2>クロスプラットフォームなイニシアチブ</h2>

<p>上記にあげたPWAで利用するWeb APIは、すべてのブラウザで利用できることを目標に標準化を進めています。個別の対応状況を確認するには<a href="https://caniuse.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Can I Use</a>をご参照いただければと思いますが、冒頭に述べましたとおりiOSでもiOS 11.3からSafariでService Workerが動作するようになりましたし、Microsoft はWindowsストアにPWAを載せはじめました[6]。このように、さまざまな形でPWAのクロスプラットフォーム利用の機運が高まっていると言えます。</p>

<p>また、PWAは<a href="https://en.wikipedia.org/wiki/Progressive_enhancement" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Progressive Enhancement</a>な実装を推奨している点も改めて触れておきます。たとえばService Workerを利用したオフラインキャッシュの実装は、Service Workerが未実装なブラウザでもWebアプリ本来の動作には影響がないように以下のように条件分岐をいれることを推奨しています。</p>

<p></p><pre class="crayon-plain-tag">// ServiceWorkerが利用できる場合にのみ
if ('serviceWorker' in navigator) {
  // ServiceWorkerを登録する
  navigator.serviceWorker.register('/sw.js')
}</pre><p></p>

<p>特定の環境のみでしか動かないWebアプリを作るのではなく、どの環境でもハイパフォーマンスに動作するようにし、最新のWeb APIが利用できる環境では進んでそれをレバレッジするとよいでしょう。</p>

<h2>Webアプリ vs ネイティブ アプリ</h2>

<p>PWAはその機能性や実現したいコンセプトから「PWAはネイティブ アプリを潰そうとしているのか？」「Webアプリがネイティブアプリにかなうはずない！」など当該テーマにおいては辛辣なコメントを見かける場面もあります。ここで1つお伝えしたいことは、多くのユーザーはネイティブアプリなのかWebアプリなのかというプラットフォームの選択には関心がないということです。大事なのは「うまい、やすい、はやい」ユーザー体験の良いサービスを提供することです。PWAの出現によりWebアプリでもそれを実現する準備が整いつつあり、<strong>事業者やソフトウェア エンジニアとしては理想のサービスを提供できるプラットフォームのオプションが増えるという意味で、このWebの進化を前向きに捉えていただければ幸いです。</strong></p>

<p>実際Webアプリにはまだできないこともあります[7]。ただし、Webアプリには他のプラットフォームよりも優れたリーチがあり、<strong>その意味でWeb アプリとネイティブ アプリがむしろ手を取ることは、戦略としても決して矛盾しません。</strong></p>

<p><img src="/wp-content/uploads/2018/04/pwa06.png" alt="pwa06" /></p>

<p>使用したい機能がWebプラットフォームが提供するもので十分であり、技術スタックをWebのみに集約するメリットも感じるのであれば「PWA のみ」という選択肢も今後は出てくるかと思います。しかし、前述した「まだできないこともある」という前提を加味するとネイティブアプリが活躍する場面は引き続きありますし、<strong>PWAは「Webアプリ vs ネイティブアプリ」という二者択一を迫る提案ではない点をご理解ください。</strong></p>

<h2>ユーザー体験の新たな基準</h2>

<p>このようにPWAはWebアプリの「ユーザー体験の新たな基準」を満たすために作られたベストプラクティスでしかありません。重要なのはそれぞれの機能を単純に実装するのではなく、Webアプリの特性に応じて使い分け、ときにはカスタマイズし、ユーザーによりよいサービスを提供することです。今回ご紹介しました各種ツールやデザインパターン、iOSでもService Workerが利用できるようになった点など、舞台は整いつつあります。<strong>ぜひとも最高のWeb体験を実現すべくPWAの考え方を取り入れてみてください。</strong></p>

<ul>
<li>[1] <a href="https://www.doubleclickbygoogle.com/articles/mobile-speed-matters/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">The need for mobile speed: How mobile latency impacts publisher revenue</a></li>
<li>[2] <a href="https://developers.google.com/web/fundamentals/performance/rail" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">RAILモデルでパフォーマンスを計測する</a></li>
<li>[3] <a href="https://youtu.be/_srJ7eHS3IM" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Fast By Default: Modern Loading Best Practices (Chrome Dev Summit 2017)</a></li>
<li>[4] <a href="https://infrequently.org/2017/10/can-you-afford-it-real-world-web-performance-budgets/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Can You Afford It?: Real-world Web Performance Budgets</a></li>
<li>[5] <a href="https://support.google.com/adsense/answer/132618" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Above the fold</a></li>
<li>[6] <a href="https://www.windowscentral.com/first-batch-windows-10-progressive-web-apps-here" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">First Windows 10 Progressive Web Apps (PWA) published by Microsoft hit the Store</a></li>
<li>[7] <a href="https://whatwebcando.today/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">What Web Can Do Today</a></li>
</ul>
]]></content:encoded>
			</item>
		<item>
		<title>AIファースト時代のSEOはどうなる？―辻正浩さんに“SEOに効く”Web制作でのポイントを聞いてみた！</title>
		<link>/miyuki-baba/25271/</link>
		<pubDate>Tue, 20 Mar 2018 01:00:51 +0000</pubDate>
		<dc:creator><![CDATA[馬場 美由紀]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Progressive Web Apps]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[検索エンジン]]></category>
		<category><![CDATA[辻正浩]]></category>

		<guid isPermaLink="false">/?p=25271</guid>
		<description><![CDATA[連載： Webの未来を語ろう 2018 (3)HTML5 Experts.jp編集部の馬場です。毎回豪華ゲストをお呼びして、Webの現在と未来について語っていただく公開座談会企画「Webの未来を語ろう」シリーズ第3弾！ ...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/future-of-web-2018/" class="series-496" title="Webの未来を語ろう 2018" data-wpel-link="internal">Webの未来を語ろう 2018</a> (3)</div><p>HTML5 Experts.jp編集部の馬場です。毎回豪華ゲストをお呼びして、Webの現在と未来について語っていただく公開座談会企画「Webの未来を語ろう」シリーズ第3弾！</p>

<p>今回は検索エンジン最適化（SEO）の第一人者である辻正浩さんをお招きし、2018年のSEOを語る上で欠かせないことやWeb制作で気をつけたいポイント、「AI First」時代のSEOはどうなっていくのかなどを語っていただきました。</p>

<p><img src="/wp-content/uploads/2018/03/DSC00026-2.jpg" alt="" width="640" height="386" class="alignnone size-full wp-image-25289" srcset="/wp-content/uploads/2018/03/DSC00026-2.jpg 640w, /wp-content/uploads/2018/03/DSC00026-2-300x181.jpg 300w, /wp-content/uploads/2018/03/DSC00026-2-207x125.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>今回のゲスト</h2>

<h4>辻正浩さん（株式会社 so.la 代表取締役SEO）</h4>

<p><img src="/wp-content/uploads/2018/03/DSC00057.jpg" alt="" width="100" height="150" class="alignleft size-full wp-image-25307" srcset="/wp-content/uploads/2018/03/DSC00057.jpg 200w, /wp-content/uploads/2018/03/DSC00057-138x207.jpg 138w" sizes="(max-width: 100px) 100vw, 100px" />Search Engine Optimizer。<br>1974年北海道生まれ。営業、広告制作、Web制作の経験の後、株式会社アイレップでSEOの専門家としての活動を開始。様々な業界・規模のWebサイトのSEOを担当する。 2011年10月に独立の後、株式会社so.laを設立。SEO専門家としてWebサービスやECサイト、企業サイトのSEOに取り組む。特に大規模サイトを得意とし日本有数の大規模サイトのSEOを多数担当している他、各地での講演にてSEOの啓蒙活動を行なっている。</p>

<p><br></p>

<h2>SEOのエキスパート、辻さんの空前絶後な仕事術</h2>

<p><strong>白石</strong>：日本で検索される約5％は辻さんの顧客のサイトなのだそうですね。現在はお一人で13社のSEO支援をされているとのことですが、どうやってそれだけの仕事をこなされてるのか気になります。1日のスケジュールはどんなかんじで仕事されているんですか？</p>

<p><strong>辻</strong>：だいたい規則的ですね。平日は朝8時か9時に起きて、昼くらいまではメールなどをチェックします。午後はお客様とのミーティングに出かけ、夕方帰ってきたらその日のうちの作業やメール対応などをしています。深夜0時くらいから翌日の作業の準備をして、4時か5時くらいに寝ます。</p>

<p><strong>白石</strong>：えっ、朝起きる時間はそんなに早くないなと思ったら、夜中の4時とか5時まで起きて仕事してるんですか。遅くまで仕事をしすぎなんじゃ…。</p>

<p><strong>辻</strong>：13社のお客様とは、月に1回か2回必ず1～2時間のミーティングを入れているので、平日の午後はほぼ埋まるんですね。そのミーティングのために、各社のSEOの分析や提案の準備で短くても5～6時間はかかります。翌日の準備をしているとどうしても朝5時くらいになっちゃうんですよ。</p>

<p>ツールも使っていますが、マンパワーでなんとかやってしまうので、同業のSEO業界の人に話をしてもまったく参考にならないって言われてます(笑)。</p>

<p><img src="/wp-content/uploads/2018/03/DSC00051.jpg" alt="" width="640" height="427" class="alignnone size-full wp-image-25342" srcset="/wp-content/uploads/2018/03/DSC00051.jpg 640w, /wp-content/uploads/2018/03/DSC00051-300x200.jpg 300w, /wp-content/uploads/2018/03/DSC00051-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><strong>白石</strong>：クライアントワークやってる辻さんもすごいんですけど、仕事以外でも辻さんは検索結果を常に広い領域でウォッチしているイメージがあります。</p>

<p><strong>辻</strong>：30万キーワードくらいは定期的にウォッチしてます。私が他社に勝っている点があるとすると、全部一人で見ていることですね。日頃の順位や流入の変化からサイト変更による変化を一人で全部見ていれば、傾向が把握できますから。</p>

<p><strong>白石</strong>：辻さんを医療系サイト「WELQ」問題（※）で記憶している人も多いと思うのですが、このときの医療業界の動向はたまたま気づいたんですか？</p>

<blockquote>
  <p><span style="font-size: 80%;">（※<strong>「WELQ（ウェルク）」問題</strong>：DeNAが運営する医療情報のキュレーションメディア「WELQ」が、クラウドソーシングなどを使って記事を安く大量に作り、その記事が検索結果で上位表示されていた件。医療系の情報にも関わらず信頼度が低い、記事の制作過程で多数の著作権侵害が認められるなど、多くの批判を受けて現在サイトは停止中）</span></p>
</blockquote>

<p><strong>辻</strong>：医療・金融・法律関連といった深刻な情報の検索では、特殊なアルゴリズムが動いています。その中でも医療関連は動きが顕著ですので定期的に確認していました。医療を追っていればけば、その後の他業界がどういう動きになるか予想できますので。</p>

<p>例えば医療系なら一般的な薬や病名とか症状などのキーワードを、それぞれ数百づつ定期的に検索しておいて、上位表示されるサイトの傾向を見ていると面白いですね。動きが変わってきたときに、じゃあペットの病気だと同じような動きか？などとずらして比較するといろいろ見えてきて、興味深いです。</p>

<p><strong>白石</strong>：すごいな…。そういった動きを調べているときは何かツールも使ってるんですか？</p>

<p><strong>辻</strong>：データはツールを使って分析しています。ただちゃんと分析するときは、ツールだけではできないので、力業ですね(笑)。</p>

<p><strong>白石</strong>：辻さんの大事にしているポリシーや哲学的な話も聞いてみたいです。WELQのときって「これは許せない！」という社会正義みたいな想いもあったんですか？</p>

<p><strong>辻</strong>：あまり社会正義的なことはやりたいくないです(笑)。基本的に楽しい仕事しかしたくないですし、好きなサイトとか面白いサイトの仕事だけを受けています。そういうサイトだけに関わっていれば仕事も大変ではないですから。</p>

<p>ただ、自分の義務として検索に関わる問題提起をしていくべきとも思っています。SEOを行っている会社にとって、検索エンジンが取引先となることが多いので、おおっぴらに文句は言いづらい人が多いんですね。私は利害関係はありませんし、身軽な立場なのでいくつか話していると、いろんな人からの相談やタレコミがどんどん来るようになって、半分義務のようになってしまっているところはあります。</p>

<p><img src="/wp-content/uploads/2018/03/DSC00038.jpg" alt="" width="640" height="399" class="alignnone size-full wp-image-25340" srcset="/wp-content/uploads/2018/03/DSC00038.jpg 640w, /wp-content/uploads/2018/03/DSC00038-300x187.jpg 300w, /wp-content/uploads/2018/03/DSC00038-207x129.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>モバイルファーストの流れでSEOはどうなる？</h2>

<p><strong>白石</strong>：続いては、SEOの過去から現在までの大まかな流れと制作者向けのポイント、SEOの未来を聞いていきたいと思います。まず、モバイルファーストはGoogleのSEOにどういう影響を及ぼしているんでしょうか。</p>

<p><strong>辻</strong>：2016年、2017年、2018年の今くらいまででいうと　モバイルファーストの影響は大きいと思います。Googleの仕様として大きな変化は、モバイルファーストインデックス（MFI：Mobile First Indexing）ですね。</p>

<blockquote>
  <p><span style="font-size: 80%;">（モバイルファーストインデックス：Googleがこれまで検索エンジンがPCサイトの内容をもとにコンテンツの質を評価していたのを、スマートフォンサイトを評価の主軸に評価し、インデックスするという方針転換のこと）</span></p>
</blockquote>

<p>Googleはレスポンシブウェブデザインでやっているサイトについては、PCサイトのページとモバイルページのソースに違いはないので一切影響はないと言っています。レスポンシブ以外のところはどうかというと、同じURLで別のHTMLを出しているダイナミックサービングも、別のURLでPCとモバイルを対応しているサイトも、内容が同じなら影響はないと言っています。</p>

<blockquote>
  <p><span style="font-size: 80%;">（ダイナミックサービング：URLはPCサイトとスマホサイトで一緒だが、アクセスするデバイスによって見せるページやテンプレートを切り替える方式）</span></p>
</blockquote>

<p>ただ、レスポンシブウェブデザイン以外では、Googleが見るページのデザインや動線が大幅に変わることになるわけですよね。おそらく経験がある方も多いと思いますが、コンテンツを変えずにデザインと導線を全部変える大幅なリニューアルをすると検索順位に大きな影響があるものです。</p>

<p>しかしGoogleはその影響がほぼないようにすると言っているんですよ。今までの経験上そうなるはずはないのですが、そう言い切るからには、Googleはいろいろな今までにない処理をしてくるんだろうなあと思っています。</p>

<p>本当にそうなればいいのですが、やはり大きな変化になるかもしれないとして、ウォッチしていく必要があると考えています。</p>

<p><img src="/wp-content/uploads/2018/03/IMG_5906.jpg" alt="" width="640" height="424" class="alignnone size-full wp-image-25338" srcset="/wp-content/uploads/2018/03/IMG_5906.jpg 640w, /wp-content/uploads/2018/03/IMG_5906-300x199.jpg 300w, /wp-content/uploads/2018/03/IMG_5906-207x137.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><strong>白石</strong>：PCサイトしかないサイトはどうですか？</p>

<p><strong>辻</strong>：モバイルファーストインデックスでも大きな変化はないはずです。ただ、昔からモバイル版を用意していないサイト、モバイルフレンドリーではないサイトは、モバイルからの検索では順位が大幅に落ちていますので、どうにかするべきでしょうが。</p>

<p><strong>白石</strong>：スマホ用URLがあるサイトやスマホ用コンテンツが違うというサイトはいかがでしょう？</p>

<p><strong>辻</strong>：そういうサイトはアノテーションなどを複雑に対応する必要があって難易度が高いですね。Googleはカンファレンスの質問などで「完璧に実装できた場合は問題ない」と回答してします。ただし「そういうサイトはめったにないし、だいたいみんなミスをする」とも言われていたそうですが。私なら早めにコンテンツの整理をお願いしますね。</p>

<p>このPC版とスマホ版という話は、サイトの規模によってはクロールの観点で複雑になることもあります。PC版とスマホ版でソースが違う巨大なサイトでは、PC版しかまともにクロールできていないところが多いです。</p>

<p>毎日数万とかページが増える巨大サイトは毎日数百万何千万とGooglebotがデータを取りに来て、Googleのためにサーバ負荷対応が必要なところも多いのですが、PC版とモバイル版の両方を取得するためには、さらに倍の負荷になってサーバ費用もかなり増えます。</p>

<p>そういう事情への配慮なのか、巨大なサイトではPC版を中心にクロールをかけて、スマホ版ページはパターン認識による推測ですましていることがあります。</p>

<p>巨大なサイトのクロールでは、かなり複雑な処理が行われているんです。モバイルファーストインデックスになるとそのあたりも変わるでしょうから、巨大なサイトではなにか特殊な変化が発生する可能性は十分にあるでしょうね。</p>

<p><img src="/wp-content/uploads/2018/03/DSC00048.jpg" alt="" width="640" height="427" class="alignnone size-full wp-image-25344" srcset="/wp-content/uploads/2018/03/DSC00048.jpg 640w, /wp-content/uploads/2018/03/DSC00048-300x200.jpg 300w, /wp-content/uploads/2018/03/DSC00048-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><strong>白石</strong>：今後はモバイルクロールがメインになると？</p>

<p><strong>辻</strong>：私がログを見られる巨大サイトの多くでは、PCクローラとモバイルクローラの割合が8：2くらいなんですが、今後は逆転させるそうなんです。巨大サイトではPCページは認識できていてモバイルページは認識できていないようなケースも多いので、データベースの処理も複雑になるんだろうなと。そのタイミングでは何かイレギュラーなことが起こるかもしれません。</p>

<p>Googleは問題ないといいますが、過去にない大規模な仕様変更ですので、どういう影響があるかはやはり分からないですね。</p>

<p>普通の規模のサイトや、レスポンシブウェブデザインのサイトは確かに問題は起きないと思いますが、そうではないところにとってはいろいろイレギュラーがあるかもという想定で注意して監視しておいたほうがいいと思います。</p>

<h2>Webコンテンツの「正しさ」への流れ</h2>

<p><strong>白石</strong>：では、話題を変えて。最近はWebコンテンツの「正しさ」への流れがありますが、どうお考えですか？</p>

<p><strong>辻</strong>：WELQ問題が端を発し、Googleは2017年12月6日にウェブマスター向け公式ブログで、日本語検索の結果について「医療や健康に関する検索結果の改善」を発表しました。医療や健康に関する部分はここで非常に大きな変化があったわけですが、この前後にGoogleはいろんなことをやっているんですよね。</p>

<p>明確に違法と言えないけど怪しいサイトや悪質なサイトの順位を露骨に落とした、と思える動きもありました。昨年末に逮捕者も出たようなフィッシングサイトへの対応も進んでいます。大きな社会問題になったことに対して積極的に対応するようになった、と思いますね。フェイクニュースなどインターネットへの信頼性が疑われるようになって、明らかに態度を変えたように思います。</p>

<p><img src="/wp-content/uploads/2018/03/IMG_59001.jpg" alt="" width="640" height="416" class="alignnone size-full wp-image-25345" srcset="/wp-content/uploads/2018/03/IMG_59001.jpg 640w, /wp-content/uploads/2018/03/IMG_59001-300x195.jpg 300w, /wp-content/uploads/2018/03/IMG_59001-207x135.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><strong>白石</strong>：それまでのGoogleは「インターネットの自由」を優先していて、それは面白さでもありましたが…。「正しさ」が大事という方向に舵を切ったと？</p>

<p><strong>辻</strong>：はい。情報の正確性を意識するようになったことはいわれています。「Googleは検閲はすべきでない」というポリシーとインターネットの自由を大切していることは確かです。Googleを含めたインターネット全体が自由だけでは問題があるという方向に流れています。いいことかはわかりませんが、どんどん加速化していますね。</p>

<p><strong>白石</strong>：でも、人によって「正しさ」が違う情報っていっぱいあるじゃないですか。Googleがその「正しさ」を決めるのは、限られたことにしかできないんじゃないかなって思うんですけど。</p>

<p><strong>辻</strong>：難しいですね。最近は癌について検索したら、国の医療機関などしかまともに出なくなりました。ただお医者さんの眉をひそめるような高額だったり、実績に乏しい微妙な治療方法の多くは違法ではないですよね。それらがGoogleの判断によって多くの人に知られづらくなったわけですよね。これはGoogleの検閲ともとれる行為かもしれませんが、それが受け入れられています。難しいことですよね。</p>

<p>個人的には、深刻な病気に悩む人が検索の情報で迷惑をかけられたという話をたくさん聞いてきたので、今の状態が悪いとはまったく思わないんです。インターネットの自由も大事だけど、その自由の中でも規制したほうがいいこともあります。ただ、これがどんどん拡大するようではまずいですよね。</p>

<p><strong>白石</strong>：価値中立、道徳的に中立という言葉がありますが、Googleは今まではそこを頑張ってたんでしょうけど、あまりに誤った情報などを出してしまうのはまずいと考えたんでしょうね。ただ、Googleの一存で何が正しくて、何が間違っているのかという思想の部分を決めてしまうのはどうかという問題もありますね。</p>

<p><strong>辻</strong>：本当にそう思います。ただこの問題、Googleは本当に慎重に考えていると思います。Googleの考え方は発表される声明だけではなくて、実際の順位の動きなどで大分理解できているつもりですが、今のGoogleでも表現の自由とかインターネットの自由の尊重とかは、過剰なほど慎重だと思います。</p>

<p>ただ、それでも対応を変えていかないと行けないほどインターネットは複雑になったということかなと思います。現状のGoogleには不安はないし、変なことはやらないと信じています。でも今後どう変わるかはわからないので、今後も動向は見ないといけないですね。</p>

<h2>全てのサービスとGoogleが競合化する！？</h2>

<p><strong>白石</strong>：次のテーマ「Googleの競合化」ですが、これはどういう意味でしょうか？</p>

<p><strong>辻</strong>：最近、Googleでグルメ関連の検索をすると一番上に地図が出ますよね。ユーザー評価もあるし、ローカルガイドにもなって、とても便利ですよね。あと飛行機の予約ができるGoogleフライトも、ホテルの予約もできるし、ユーザーには便利でいいサービスなんですが、これらによって奪われてしまったサービスも出てきます。</p>

<p>Googleマップではスマホを持ったユーザーの行動がオプトインで記録されていますが、そのあたりの独自データを激しく使い出すと、他のサービスはなかなか太刀打ちできないですよね。</p>

<p><img src="/wp-content/uploads/2018/03/IMG_5888.jpg" alt="" width="640" height="439" class="alignnone size-full wp-image-25347" srcset="/wp-content/uploads/2018/03/IMG_5888.jpg 640w, /wp-content/uploads/2018/03/IMG_5888-300x206.jpg 300w, /wp-content/uploads/2018/03/IMG_5888-207x142.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><strong>白石</strong>：あらゆるサービスにGoogleが競合として参入していくわけですね。</p>

<p><strong>辻</strong>：増えていることはたしかです。Googleが持てない価値を考えて作るしかないんですが、情報を集めて出すサービスは勝ち目がなかなかない厳しい状況になると思います。</p>

<h2>Web制作におけるSEOのポイントは？</h2>

<p><strong>白石</strong>：ここからはWeb制作におけるSEOのポイントについて聞いていきたいと思います。マークアップなどで気をつけることとかありますか？</p>

<p><strong>辻</strong>：昔は「<code>&lt;strong&gt;</code>をつけろ」とかありましたけど、最近は効かなくなりましたね。私もマークアップを変えろという指摘はほぼしなくなりました。普通にミスのないマークアップでWebサイトを作れば評価されるので、SEOのためにマークアップで何かするということが減ってしまったんですよね。</p>

<p>ただ、サイト設計については口を出さなくてはいけないことが、多くなってきました。Googleは公式に認めていませんが、どんなユーザーがどういうページを見ていていて、どこで離脱しているかなど、ユーザー行動を見ているんですね。</p>

<p><strong>白石</strong>：まあ、肯定しにくいですよね。</p>

<p><strong>辻</strong>：Googleは否定するけど、一般ユーザーがWebページ内でどういう行動をするかが検索結果に影響するようになってきました。その影響力はどんどん大きくなっています。</p>

<p><strong>白石</strong>：昔は内部リンクを充実させるために、人間が踏まなさそうなリンクをフッターに大量に仕込んでたじゃないですか。あれはまだ有効ですか？</p>

<p><strong>辻</strong>：2012年くらいから一切やらなくなりました。そういう人が使わないリンクをはずして順位がかわるか実験を何度もしてみたのですが、一切変わらなかったんです。それからはSEOだけの目的でリンクを張ることはあまりしなくなりましたね。</p>

<p><img src="/wp-content/uploads/2018/03/IMG_5905.jpg" alt="" width="640" height="423" class="alignnone size-full wp-image-25349" srcset="/wp-content/uploads/2018/03/IMG_5905.jpg 640w, /wp-content/uploads/2018/03/IMG_5905-300x198.jpg 300w, /wp-content/uploads/2018/03/IMG_5905-207x137.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><strong>白石</strong>：クローラーのためにAタグを書いておくのはもう必要ないんですね。</p>

<p><strong>辻</strong>：これからはユーザーが使いやすいページを作ることを優先した上で、どうやって検索に強くするかを考えることが有効になってきます。例えば、グローバルメニューとかカテゴリとか本来はユーザ動線として強いはずなのに、ニーズがない情報が並んでるサイトってあるじゃないですか。ユーザが好む動線に検索ニーズもある情報をまとめるとか、マークアップとかよりもユーザーの検索ニーズを意識したサイト作り、などが重要ですね。</p>

<p><strong>白石</strong>：ユーザーにとって自然な導線をちゃんと作り込むようにしなさいということですね。</p>

<p><strong>辻</strong>：はい、それがSEOの観点として大事になったということです。</p>

<p><strong>白石</strong>：一般ユーザーはあまり気にしてないと思いますが、URLは未だに重要ですか？</p>

<p><strong>辻</strong>：少なくとも日本国内ではURLの深さとかは、最近は関係なくなくなってきました。パラメータをつけるとどうこうとかありましたが、今のGoogleだけでいうなら認識するようになってきた。ただし、Google以外の検索エンジンは上手く認識できない場合が多いので、やるしかないんですが。</p>

<p><strong>白石</strong>：コンテンツづくりについても聞いてみたいと思います。昔、辻さんがGoogleに好かれるための記事を書いてたじゃないですか。検索エンジンには好かれるキーワードを散りばめて、見出しをちゃんと書いて、先に結論があって、見出しの近くに重要キーワード置いてとか。</p>

<p><strong>辻</strong>：それは今でもまだガリガリ効きます。SEOを考えたキーワードは大事ですね。ただし、キーワードを書かなくても、テーマによって検索ニーズがあるものはランキングが上がるという流れもあります。</p>

<p><strong>白石</strong>：以前流行ったキーワードたくさん入れたSEO用の記事も効くのでしょうか。</p>

<p><strong>辻</strong>：そういう何も考えてないSEO記事は大分効かなくなりましたね。Googleはユーザーを見出したということもあり、読み込んでくれる文章じゃないとユーザーは離脱するので効果はなくなっていくと思います。</p>

<p><img src="/wp-content/uploads/2018/03/IMG_58971.jpg" alt="" width="640" height="436" class="alignnone size-full wp-image-25351" srcset="/wp-content/uploads/2018/03/IMG_58971.jpg 640w, /wp-content/uploads/2018/03/IMG_58971-300x204.jpg 300w, /wp-content/uploads/2018/03/IMG_58971-207x141.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><strong>白石</strong>：AMPのSEO観点は何かありますか？</p>

<p><strong>辻</strong>：AMPということだけではなく、考えなくてはいけないことがあります。例えば、最近はパーマリンクの重要性がすごく高まっていると思います。3年前くらいはパーマリンクのURLを評価をするサービスは少なかったと思いますが、最近はスマートニュースやグノシーなど、評価付けする存在が増えてきました。</p>

<p>URL単位で評価をするサービスにとって、AMPのURLでシェアなどをされると本来の記事と価値を統合するのに時間がかかったり、されなかったりすることもあります。他にも様々なデメリットはありますが、表示スピードが上がるといったメリットもあるわけで、メリットデメリットを考えて判断するべきですね。</p>

<p>個人的には、ニュースなどAMPに対応すると表示枠が増えるジャンル以外は、まだ様子見をするべきだと思います。先に言いましたパーマネントリンクの問題も今後の仕様改定で解決されるようですし、AMP関連の仕様はまだまだ進化を続けています。対応の工数も大きいですし、大きな利益が見込めないならもう少し仕様が固まってからでいいのではないでしょうか。</p>

<h2>パフォーマンス・スピードはSEOに影響しない！？</h2>

<p><strong>白石</strong>：パフォーマンススピードが高いサイトは評価するとGoogleが言ってますが、実際はどうでしょう？</p>

<p><strong>辻</strong>：実はそれ勘違いなんですね。Googleのウェブマスターブログでは、極めて遅い体験を提供しているサイトだけを落とすと言っています。昔行った以前の実験によると、読み込み速度が25秒以上かかるサイトはだいたい順位が落ちました。</p>

<p><strong>白石</strong>：辻さん、そんな実験もやってるんですね(笑)。</p>

<p><strong>辻</strong>：はい！どれだけ速くしてもランキングが上がることはなく、遅いサイトが落ちます。ただ、スピードを上げることはユーザーの行動が良くなります。結果的に順位が高くなることはあります。</p>

<p>個人的な経験では、サーバーの速度がある程度早ければ、さらにサーバ環境を向上してもユーザー体験は目に見えて変わらないですよね。それだと順位も変わりません。ただ、速度の実測値は変わらなくてもCSSの配慮などでサクサク動いているような感覚にしたほうがランキングが上がるんですよね。</p>

<p><strong>白石</strong>：ということは、本当の速度を見ているのではなく、Googleはユーザー体験の方を見ているということですね。</p>

<p><strong>辻</strong>：はい、良いユーザー体験を提供すれば順位が上がります。勘違いしてはいけないのは、速度改善でユーザー行動を良くするのは素晴らしいことなんです。</p>

<p><strong>白石</strong>：なるほど。ユーザーのためにやるのはいいことなのに、SEOのためにやるのは違うということですね。</p>

<p><strong>白石</strong>：最後はネイティブアプリのようなUXをWebページでも提供することができるProgressive Web Apps（PWA）について。プッシュ通知がWebサイトでできたり、ホームスクリーンにアイコンが出てアプリをダウンロードしてもらえたら、以降はアプリで作ってもらえるとか、クロスプラットフォームで対応できるなど便利な機能がいろいろある上に、SEOにもいいということで盛り上がっています。</p>

<p><img src="/wp-content/uploads/2018/03/DSC00046.jpg" alt="" width="640" height="427" class="alignnone size-full wp-image-25353" srcset="/wp-content/uploads/2018/03/DSC00046.jpg 640w, /wp-content/uploads/2018/03/DSC00046-300x200.jpg 300w, /wp-content/uploads/2018/03/DSC00046-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><strong>辻</strong>：Googleはアプリ内のユーザの行動はあまり把握できていませんよね。ユーザーが自社アプリに流れた結果、メインサイトのユーザ行動が減って検索順位が落ちる影響は明らかにあります。そういう観点ではPWAはアプリより良いと考えています。</p>

<p><strong>白石</strong>：PWAが有望なのであれば、クロスプラットフォームでWebページからアプリ版も作れる。SEO効果もあるし、ゲーム仕様でなければ普通に作れるし、今後は全部PWAでいいんじゃないでしょうか。</p>

<p><strong>辻</strong>：PWAのニーズは高まっていくでしょうね。逆に、アプリ開発しかできない開発者はPWAによって活躍の場が減っていくかもしれません。</p>

<h2>「AI First」で変わるSEOの未来</h2>

<p><strong>白石</strong>：「AI First」という言葉をいままで使っていませんでしたが、未来の話もしたいですね。</p>

<p><strong>辻</strong>：Googleが公式でも「AI First」と言うようになってきましたね。プロダクトの全てにAIを入れ出しているので、今後AIでいろんな判断がされるようになっていくのが一番影響されるところです。</p>

<p><strong>白石</strong>：これまで、Googleがユーザー行動を見ているという話がたくさんありました。結局のところ、今までのクローラーが単純すぎたということで、普通の人間がページを見たときにいい印象を受けるかを判断をするようになる。人間の判断にどんどん近づいているということでしょうか。</p>

<p><strong>辻</strong>：その通りだと思います。その状況でSEOを考えると、GoogleのAIに上質な餌をどう与えていくかを意識することが大事になっていきます。</p>

<p><img src="/wp-content/uploads/2018/03/DSC00081.jpg" alt="" width="640" height="427" class="alignnone size-full wp-image-25354" srcset="/wp-content/uploads/2018/03/DSC00081.jpg 640w, /wp-content/uploads/2018/03/DSC00081-300x200.jpg 300w, /wp-content/uploads/2018/03/DSC00081-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><strong>白石</strong>：「餌付け」というのはユーザーに有益な情報を提供しようということですね。Googleに情報をあげるとAIが賢くなる。Googleはその先に何を作っていくのか考えちゃいますね。</p>

<p><strong>辻</strong>：そうですね。その先に過剰な怖さを感じている話もよく聞きますが、「Google怖い」は「電気怖い」と同じような話かなとも思っています。Googleを恐れるときは正しく恐れるべきだと言っておきたいです。</p>

<p><strong>白石</strong>：ただしく恐れろということですね。辻さんに大きな拍手をもって終わりにしたいと思います。ありがとうございました！</p>
]]></content:encoded>
		
		<series:name><![CDATA[Webの未来を語ろう 2018]]></series:name>
	</item>
		<item>
		<title>Progressive Web Appで実現する動画アプリの最新テクニック ──Google I/O 2017 セッションレポート</title>
		<link>/ryoyakawai/23440/</link>
		<pubDate>Wed, 31 May 2017 01:00:16 +0000</pubDate>
		<dc:creator><![CDATA[河合良哉]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Google I/O 2017]]></category>
		<category><![CDATA[Progressive Web Apps]]></category>

		<guid isPermaLink="false">/?p=23440</guid>
		<description><![CDATA[連載： Google I/O 2017特集 (1)この記事は2017年5月17、18、19日に米国カリフォルニア州マウンテンビューにあるAmphitheatreで行われたGoogleの開発者向けカンファレンスGoogle...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/google-io-2017/" class="series-450" title="Google I/O 2017特集" data-wpel-link="internal">Google I/O 2017特集</a> (1)</div><p>この記事は2017年5月17、18、19日に米国カリフォルニア州マウンテンビューにあるAmphitheatreで行われたGoogleの開発者向けカンファレンスGoogle I/Oの3日目に「The Future of Audio and Video on the Web」というタイトルのセッションの内容です。</p>

<h1>はじめに</h1>

<p>タイトルをパッと見て、例えばWeb Audioの話も絡むのか！？と思いきや、内容はビデオでしたが、2000年からwebのみならずリビングにあるテレビ（動画）から、YouTube、SNSでの動画も含めて歴史を追った説明、デモをまじえ動画を中心としたwebサイトの現在できる最高のExperience、そして見えかけている未来のwebでの動画の拡がり、とwebで動画という切り口から幅広く説明をした中身の濃いセッションでした。</p>

<p>登壇したのはこのお二方。Product ManagerのJohn Pallettと、Developer Programs EngineerのFrancois Beaufortです。</p>

<p><img src="/wp-content/uploads/2017/05/John_Francois.png" alt="" width="640" height="230" class="aligncenter size-full wp-image-23451" srcset="/wp-content/uploads/2017/05/John_Francois.png 640w, /wp-content/uploads/2017/05/John_Francois-300x108.png 300w, /wp-content/uploads/2017/05/John_Francois-207x74.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>それでは内容を見ていきましょう。</p>

<h1>動画が机、リビングから手の上に乗り外に向けて歩き出す</h1>

<p>2000年から10年はほとんど変わらなかった。
2000年は私(John Pallett)がHDのテレビを買った最初の年。この当時はHD動画を録画する機器すらなかったが、直後にHD録画機器も出始めSkypeも同じ頃に登場。2005年にYouTube、2007年にはAmazonのPrimeビデオ、Netflixがストリーミングサービスを開始。しかし、この頃は机、リビングで見るのが主でした。
<img src="/wp-content/uploads/2017/05/tv_living.png" alt="" width="640" height="364" class="aligncenter size-full wp-image-23453" srcset="/wp-content/uploads/2017/05/tv_living.png 640w, /wp-content/uploads/2017/05/tv_living-300x171.png 300w, /wp-content/uploads/2017/05/tv_living-207x118.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>2010年からは私の娘を軸に見ていきます。
2010年はタブレットが出始めた年。娘はこの頃から場所を選ばず受動的に動画、音楽を聞いたり、一方で能動的に録画、録音するようになっていました。</p>

<p>ちょうどその頃にはFaceTimeが登場し、ビデオチャットが気軽にできるようになり、2011年にはTwitchでゲーム動画の配信、2013年にはSnapchat、2014年にmusical.lyで若者が音楽ビデオを録り、さらにそれを友達同士で配信するようになった。さらに過去数年では、VR、AR、360度動画が出てきたりと、イノベーションがここ数年の動画の進化を加速。</p>

<p><img src="/wp-content/uploads/2017/05/tv_mobile.png" alt="" width="640" height="384" class="aligncenter size-full wp-image-23456" srcset="/wp-content/uploads/2017/05/tv_mobile.png 640w, /wp-content/uploads/2017/05/tv_mobile-300x180.png 300w, /wp-content/uploads/2017/05/tv_mobile-207x124.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>この進化を裏付けるように、現在のインターネットのトラフィックの70%が映像（ビデオ）で、Cisco社は2020年までにこれが80%まで伸びるだろうと予測しています。</p>

<p><img src="/wp-content/uploads/2017/05/badMovie4.png" alt="" width="640" height="107" class="aligncenter size-full wp-image-23461" srcset="/wp-content/uploads/2017/05/badMovie4.png 640w, /wp-content/uploads/2017/05/badMovie4-300x50.png 300w, /wp-content/uploads/2017/05/badMovie4-207x35.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h1>モバイルwebでの動画の過去と未来</h1>

<p>先程挙げた、Twitch、Snapchat、musical.ly、これらのサイトに行くと実はアプリ（Android, iOS）のインストールを求められます。</p>

<p>しかし、モバイルwebでこれらのアプリを作ればアプリのインストールは不要、そしてすぐにやりたいことができるはずなのに、なぜそうなっていないのでしょう？少し奇妙です。</p>

<p>理由を考えると実はそれにはいくつかの問題、課題がありました。一言でいうと、モバイルwebは動画が得意ではなかったのです。その問題点を見ていきます。</p>

<h3>Buffering</h3>

<p>動画の提供側はFlashを第一に、第二にHTML5に向けて公開するという時代が続いていて、モバイルwebは眼中の外でした。なぜならモバイルwebで動画にアクセスすると動画のダウンロードに時間がかかり、再生までにかなりの時間がかかっていたからです。</p>

<h3>映像のクオリティの低さ</h3>

<p>「ダウンロードに時間がかかるのなら、映像のクオリティを落とし、ファイルサイズを小さくしよう！」となりますが、小さくすればするほど映像のクオリティは低下します。</p>

<h3>いけてないレイアウト</h3>

<p>動画の提供側はモバイルwebは眼中の外だったので、サイト全体のデザイン、レイアウトはデスクトップに最適化されていて、モバイルwebでは動画の一部しか表示されていなかったりした。しかし、この現象は防ぐためのAPIがなかったことが大きい要因で、対策はできなかったかもしれないというのも事実。</p>

<h3>オフラインでは利用不可</h3>

<p>オフラインでの利用はできなかった。もちろんChromeではOffline時には恐竜ゲームはできて楽しいけど、動画を観たいのに恐竜ゲームを例えば飛行機に乗って数時間するのは現実的ではありません。</p>

<p>では現在のモバイルwebでどうなっているかを紹介します。</p>

<p>デモアプリとしてDeveloper Relations TeamのPaul Lewisが書いたアプリを例に紹介します。アプリの名前は「<strong>Biograf</strong>」で、アプリとソースコードは以下のURLにあります。</p>

<ul>
<li><strong>アプリ</strong> <a href="http://bit.ly/pwa-media" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">bit.ly/pwa-media</a></li></li>
<li><strong>ソースコード</strong> <a href="http://bit.ly/pwa-media-code" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">bit.ly/pwa-media-code-media</a></li>
</ul>

<p><img src="/wp-content/uploads/2017/05/biograf.png" alt="" width="640" height="386" class="aligncenter size-full wp-image-23472" srcset="/wp-content/uploads/2017/05/biograf.png 640w, /wp-content/uploads/2017/05/biograf-300x181.png 300w, /wp-content/uploads/2017/05/biograf-207x125.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>（セッションではここで実際にデモを行います。併せてご覧になると分かりやすいと思います。<a href="https://youtu.be/z9unKFzAj1w?t=4m51s" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">デモの動画</a>）</p>

<p><a href="https://youtu.be/z9unKFzAj1w?t=4m51s" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2017/05/demo1.png" alt="" width="640" height="470" class="aligncenter size-full wp-image-23471" srcset="/wp-content/uploads/2017/05/demo1.png 640w, /wp-content/uploads/2017/05/demo1-300x220.png 300w, /wp-content/uploads/2017/05/demo1-207x152.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a>
（クリックでデモ部分の動画が再生可能です）</p>

<p>特徴は以下です。これはwebアプリですよ！</p>

<ul>
<li>Progressive Web App</li>
<li>Nativeアプリのようにホーム画面からアイコンをタップして起動可能</li>
<li>起動アニメーション（Splash）が表示できる</li>
<li>Chrome（ブラウザ）の枠はなく、全画面でアプリ全体を表示</li>
<li>スクロールも非常にスムース</li>
<li>動画は再生をタップしてから一瞬で開始</li>
<li>デバイスを横にするとフルスクリーンでも動画の表示が可能</li>
<li>タイムラインをスクロールすると、サムネイルも表示可能</li>
<li>フルスクリーン中にタップすると、「再生、停止、コマ送り・戻し」のコントロール画面が表示可能</li>
<li>通知エリアにもコントロールを表示することが可能</li>
<li>動画のダウンロード機能もあり、ダウンロードした動画はプラウザを閉じても、機内モードでも再生可能（Background Fetch）</li>
<li>ロック画面からのコントロールも可能</li>
<li>ロック画面で動画のサムネイルを背景としても表示可能</li>
<li>制限付き動画でもライセンスをハンドルして再生可能</li>
</ul>

<p>これらのExperienceは動画の再生時「ページのロードが遅いとユーザはサイトから離脱してしまう」事実を元に考えると非常に重要な機能でもあります。Akamai社の調査では2秒で表示されないとサイトからの離脱が始まり、また動画の再生に関しては6秒以内に再生されないとユーザは再生開始を待たず離脱してしまうという調査結果を出しています。</p>

<p>では、このアプリを例にExperienceを1つ1つ見ていきましょう。</p>

<p><img src="/wp-content/uploads/2017/05/experience.png" alt="" width="640" height="362" class="aligncenter size-full wp-image-23476" srcset="/wp-content/uploads/2017/05/experience.png 640w, /wp-content/uploads/2017/05/experience-300x170.png 300w, /wp-content/uploads/2017/05/experience-207x117.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h3>反応の速い再生(Fast Playback)</h3>

<p>これはAdaptive Bitrate Streamingで実現しています。動画を再生するには動画のダウンロードは必須だが、モバイル環境下ではダウンロードするデバイスがトンネルを通ったり、帯域を失ったりする。Adaptive Bitrate Streamingがこれらのネットワークがコンスタントでない部分を解決します。</p>

<p>再生するビデオは複数のBitrateでエンコードして、それらがさらにある時間間隔で断片化して保存する。断片化されたファイルをダウンロードするアプリ側で低域等の状況に合わせてBitrateと断片の組み合わせの最適化を施すことで、反応の速い再生を可能にします。</p>

<p>これを実装したのがOpen Sourceの<a href="http://github.com/google/shaka-player" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Shaka Player</a>です。</p>

<p>また、再生ボタンをクリック/タップしてからの再生の反応に関しては、Service Workersで動画をPre-Cacheすることで速くしている。これが実装されているのが<a href="https://www.theoplayer.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">THEOPlayer</a>です。Biografにも実装されているが、動画の説明等も一緒に、事前にキャッシュ（Pre-Cache）することで再生までの時間を短縮している。またService Workersを使うとサイト自体のスピードもアップすることが可能です。</p>

<p>VIACOM18の<a href="https://www.voot.com/public_html/index.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Voot</a>という動画サイト（5月25日現在、インドでの提供のみ）ではページロード時間が5倍速くなり、これによってユーザがが77%増加、日々に動画を再生するユーザは15％増加したという結果もあります。</p>

<h3>Offline</h3>

<p>Offlilneは例えば飛行機に乗っている時など、インターネットアクセスがない場所では非常に重要な機能。BiografではService Workersを使って、ページに表示する動画の説明、また動画に関してはリーズナブルなBitrateで事前にダウンロードしキャッシュとしてブラウザ側に保存することでどこでも再生できるようにしています。このBitrateは開発者側からService Workersのロジックの中で、またはユーザ側が例えばダウンロード開始時に選択することが可能。</p>

<p><img src="/wp-content/uploads/2017/05/Offline.png" alt="" width="640" height="358" class="aligncenter size-full wp-image-23479" srcset="/wp-content/uploads/2017/05/Offline.png 640w, /wp-content/uploads/2017/05/Offline-300x168.png 300w, /wp-content/uploads/2017/05/Offline-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
Offlineはオーディオにも適応可能です。例えばオーディオブックを考えると、Service Workersを使って事前にブック内のプレイリストのオーディオを事前にキャッシュしておくことで、Offlineでも再生が可能になる。</p>

<p>Biografでは動画をキャッシュするためにBackground FetchというAPIを使っていますが、この機能は現在開発中でExperimental Web Platform features（Chromeのアドレスバーに<code>chrome://flags/#enable-experimental-web-platform-features</code>を入力すると変更可能です）をEnableにすることで利用が可能になります。このAPIに関するフィードバックをお待ちしています。</p>

<h3>VP9</h3>

<p>コーデックに関してです。クオリティを落とさずに2倍のコンテンツを保存できたらよいですよね。VP9は一般的なコーデックに比べると50％程圧縮率が高いので、質を落とさずにファイルサイズを50％減らすことができます。既に20億のデバイスがサポートされている状態なのでとてもよい選択肢。例えばYouTubeではVP9を使うことで他のコーデックで配信したときよりも再生までの時間を15〜80％縮めることができています。</p>

<h3>User Experience</h3>

<h4>Media Session API</h4>

<p>ロック画面、通知エリアでサムネイルをバックグラウンドに表示していたのと、コントロールボタンを表示していたのがこのAPI。ウェアラブル側にも表示されます。</p>

<p><img src="/wp-content/uploads/2017/05/SessionOrientationAPI.png" alt="" width="640" height="375" class="aligncenter size-full wp-image-23483" srcset="/wp-content/uploads/2017/05/SessionOrientationAPI.png 640w, /wp-content/uploads/2017/05/SessionOrientationAPI-300x176.png 300w, /wp-content/uploads/2017/05/SessionOrientationAPI-207x121.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
実装は簡単でMetadataとしてタイトル、アーティスト、アルバム名、表示する画像を指定をし、コントロール（再生、ストップ等）のボタンが押された時のHandlerをそれぞれ書くことで実装が可能です。</p>

<h4>Session Orientation API</h4>

<p>デバイスを回転させたときの動作を指定できるAPI。Biografでは横にした場合に全画面表示にしている。縦、横になった場合のHandlerを書くことで実装が可能。
<img src="/wp-content/uploads/2017/05/MediaSessionAPI.png" alt="" width="640" height="376" class="aligncenter size-full wp-image-23482" srcset="/wp-content/uploads/2017/05/MediaSessionAPI.png 640w, /wp-content/uploads/2017/05/MediaSessionAPI-300x176.png 300w, /wp-content/uploads/2017/05/MediaSessionAPI-207x122.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>webでの動画の未来</h2>

<p>タイトル通りの未来のお話をします。映像周辺の仕様の進化はディスプレイをよりリアルな表現の表示に近づけてくれます。</p>

<h4>Wide Color Gamut</h4>

<p>まずは色からお話します。現在のテレビ（4Kや8K）で実現されている色がモバイル、デスクトップのwebで表現できるようになります。</p>

<p>現在のディスプレイで表現できている色は目で見えているよりも色の表現は乏しい。その色は存在する色が外側の枠だとすると、最も内側にある三角枠が現在のディスプレイ（SRGB）の守備範囲。これがBT2020になると真ん中の三角枠まで表現できるようになります。</p>

<p><img src="/wp-content/uploads/2017/05/WideColorGamut.png" alt="" width="300" class="aligncenter size-full wp-image-23484" srcset="/wp-content/uploads/2017/05/WideColorGamut.png 598w, /wp-content/uploads/2017/05/WideColorGamut-280x300.png 280w, /wp-content/uploads/2017/05/WideColorGamut-193x207.png 193w" sizes="(max-width: 598px) 100vw, 598px" /></p>

<p>僕の履いている靴、実はこのディスプレイ（登壇者の背面にある）では正しい色で表示されていない。けども4K、8Kではより近い色が出てるはず。<br />
（独り言：もしや登壇者のJohn Pallettさん、このために靴を新調したのかな？）
<img src="/wp-content/uploads/2017/05/Screen-Shot-2017-05-25-at-9.52.00-PM.png" alt="" width="640" height="364" class="aligncenter size-full wp-image-23486" srcset="/wp-content/uploads/2017/05/Screen-Shot-2017-05-25-at-9.52.00-PM.png 640w, /wp-content/uploads/2017/05/Screen-Shot-2017-05-25-at-9.52.00-PM-300x171.png 300w, /wp-content/uploads/2017/05/Screen-Shot-2017-05-25-at-9.52.00-PM-207x118.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h4>High Dynamic Range (Brightness)</h4>

<p>いままでよりも明るいものは明るく、暗いものは暗く表示できるようになる仕様です。現在の一般的なディスプレイではSDR（Standard Dynamic Range）しか表現できません。これは現実の世界の明るさからするとかなりの差があります。</p>

<p>HDR(High Dynamic Range)をサポートしたディスプレイがこれから市場に出てきます。これはOTF（electric Optical Function、またはガンマFunctionともいう）を変えます。デジタルの数字からディスプレイでどれだけの明るさで表示するかのFunctionのことで、それが変更されるので映像・画像を扱う方はどのディスプレイが何をサポートしているか、またそのディスプレイの特性を知った上で選択する必要が出てくるということです。
<img src="/wp-content/uploads/2017/05/sdr-hdr.png" alt="" width="640" height="350" class="aligncenter size-full wp-image-23487" srcset="/wp-content/uploads/2017/05/sdr-hdr.png 640w, /wp-content/uploads/2017/05/sdr-hdr-300x164.png 300w, /wp-content/uploads/2017/05/sdr-hdr-207x113.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>Wide Color GamutとHigh Dynamic Rangeのコードは以下です。上部についてです。CSS Media Query Level4で可能になります。現在のChromeではcolor-gamutがサポートされていますが、デバイスでどの色が使えるかをクエリすることが可能で、それによって決定することが可能です。</p>

<p>また下部のコードではVP9がHDRとOTFでどの色で表示できるかをクエリによって決定することができます。</p>

<p><img src="/wp-content/uploads/2017/05/CSSL4.png" alt="" width="640" height="348" class="aligncenter size-full wp-image-23490" srcset="/wp-content/uploads/2017/05/CSSL4.png 640w, /wp-content/uploads/2017/05/CSSL4-300x163.png 300w, /wp-content/uploads/2017/05/CSSL4-207x113.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h4>Alliance for Open Media(AOM)</h4>

<p>アライアンスです。このアライアンスはYouTube、Google、Amazon、Twitch、Netflix、Microsoft、Mozilla、Hulu、BBCが参加していて、Open SourceでRoyalty-Freeの新しいCodecを作ろうとしています。</p>

<p>HDRだけでなく、Wide Color Gamut、また8K、4K、360どビデオも低いBitrateでも届けることができるようなCodecを考えています。なぜなら世界で皆が同じレベルのネットワークを使えるわけではないから。</p>

<p>このアライアンスではAV1という名前のCodecを開発している。数週間前はまだ開発も終えていないし、使えるフォーマットではなかったが、NetflixがVP9よりも20％高い圧縮率のフォーマットを実現することができたとの報告を受けている。</p>

<p>恐らく疑問に思うのは「AV1がどれだけのデバイスでサポートされているのか？」というところだと思います。ここがwebのユニークで面白いところ。1GHzと3GHzのデバイスでは再生のされ方が違う。ではそこをどうするか、VP9を例にコードを見てみます。Media Capabilities APIを使うことで以下のようにいろいろな値を指定することが可能です。</p>

<p><img src="/wp-content/uploads/2017/05/VP9query.png" alt="" width="640" height="358" class="aligncenter size-full wp-image-23492" srcset="/wp-content/uploads/2017/05/VP9query.png 640w, /wp-content/uploads/2017/05/VP9query-300x168.png 300w, /wp-content/uploads/2017/05/VP9query-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>APIにResolution、Bitrate、再生したいCodecを渡すと、指定した形式をサポートしているか、指定した形式でスムースにつまらずに再生できるか、バッテリパワー的に効率的かを返してくれるので、この情報をどのタイプで再生するかのみならず、どのResolutionで再生するか等、ユーザに最適なExperienceを提供することができるようになる。</p>

<h2>録音・録画とシェアとSNS</h2>

<p>ここ数年、映像とオーディオに関してここ数年で飛躍的に前進している。私の娘がモバイルで音楽の制作、映像の撮影をしている。顔に飾り物をディスプレイ上でつけたりカスタマイズして、そのまま友達とSNSでシェアしてる。これは5、6年前では考えられなかったことです。SNSでは即座に撮影してシェアすることがキーになります。これはwebにはとても得意ところ。なので、ここでSNSやコミィニケーションについて話をします。</p>

<p>WebRTCはあたらしい技術ではないが、ここ数年で急速にブラウザベンダとアプリケーションプラットフォームとしての両方に適応されてきました。そしてWebRTCを使えばLiveStreamingもすることが可能です。</p>

<p>そしてユーザがシェアする動画・音楽の制作に関して、簡単に探せて、簡単に見ることができ、さらにそれを見た友達が動画・音楽の制作ができ…となれば、とてもよいサイクルが生まれます。
<img src="/wp-content/uploads/2017/05/Creation.png" alt="" width="640" height="369" class="aligncenter size-full wp-image-23494" srcset="/wp-content/uploads/2017/05/Creation.png 640w, /wp-content/uploads/2017/05/Creation-300x173.png 300w, /wp-content/uploads/2017/05/Creation-207x119.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>このサイクルの実現はwebでなら難しくはありません。それではこのサイクルがwebで実現できるかどうかを、デモを交えてフランソワから紹介してもらいます。</p>

<h1>Mustache（髭）</h1>

<p>映像とシェアに関わる部分で現在のwebでできることを盛り込んだデモをご紹介します。アプリは「Mustache」という名前です。</p>

<p><img src="/wp-content/uploads/2017/05/Mustache01-1.png" alt="" width="640" height="548" class="aligncenter size-full wp-image-23504" srcset="/wp-content/uploads/2017/05/Mustache01-1.png 640w, /wp-content/uploads/2017/05/Mustache01-1-300x257.png 300w, /wp-content/uploads/2017/05/Mustache01-1-207x177.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>Progressive Web Appになっています。ホーム画面のアイコンから起動すると、起動アニメーション（Splash）が表示されます。このExperienceですと、既にwebアプリだと認識するのが難しいと思います。顔には髭、頭には帽子をかぶっています。動かしても映像はとてもスムーズです。動画の撮影も可能で、それをシェアすることももちろん可能です（上の画像の右側）。</p>

<h3>Mustacheが利用しているAPI</h3>

<h4>映像を扱う(getUserMedia())</h4>

<p>カメラを扱い、画面に表示するコードが以下になります。
<img src="/wp-content/uploads/2017/05/getusermedia-2.png" alt="" width="640" height="354" class="aligncenter size-full wp-image-23505" srcset="/wp-content/uploads/2017/05/getusermedia-2.png 640w, /wp-content/uploads/2017/05/getusermedia-2-300x166.png 300w, /wp-content/uploads/2017/05/getusermedia-2-207x114.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><code>getUserMeida()</code>でカメラの映像と音声を取得します。Mustacheの場合は映像のみを利用します。その他の条件として利用するカメラ（前面、背面）、Framerate、サイズをしています。そして下部のコードで取得した映像を画面に表示しています。</p>

<h4>形状の検知（Shape Detection API）</h4>

<p>現在、実験中のAPIであるShape Detection APIを使っています。動いている顔へ髭、そして頭に帽子をと、このAPIが重ねる正しい場所を検知することを可能にしています。つい先週完成したばかりのAPIです。</p>

<p>コードは以下のようになります。とてもシンプルです。<code>FaceDetector()</code>に顔を取得するか、また、顔を最大いくつ検知するかの数を指定するだけです。ブラウザ側のAPIなのでインターネットへの接続は不要です。</p>

<p>このShape Detection APIはBarcode、QR Codeを検知するAPIと同時に9月にはChrome安定版でテスト利用という目的で利用可能になります。また、現在でも「Experimental Web Platform features」をEnableにすることで利用可能です。もし要望、バグがあったら知らせてください。</p>

<p><img src="/wp-content/uploads/2017/05/shapedetectionapi.png" alt="" width="640" height="354" class="aligncenter size-full wp-image-23507" srcset="/wp-content/uploads/2017/05/shapedetectionapi.png 640w, /wp-content/uploads/2017/05/shapedetectionapi-300x166.png 300w, /wp-content/uploads/2017/05/shapedetectionapi-207x114.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h4>映像の録画（Media Recording API）</h4>

<p>Mustacheでは、以下のようにMedia Recording APIを使っています。<code>MediaRecorder()</code>へCodecをVP9と指定して、映像を受け取ったら処理をするHandler、また録画を停止した時のHandlerを書いている。Chromeに公開されて1年になるのでAPIは安定しています。</p>

<p><img src="/wp-content/uploads/2017/05/mediarecording.png" alt="" width="640" height="358" class="aligncenter size-full wp-image-23509" srcset="/wp-content/uploads/2017/05/mediarecording.png 640w, /wp-content/uploads/2017/05/mediarecording-300x168.png 300w, /wp-content/uploads/2017/05/mediarecording-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h4>シェア機能（Web Share API）</h4>

<p>シェアボタンを押したときにAndroidのNativeのシェア選択画面が出てきていましたよね。自然過ぎてわからなかったかもしれませんが…。これはWeb Share APIを使っています。<br />
コードは以下です。<code>share()</code>にタイトル、テキストと映像のURLを指定します。このAPIは今年末には利用できるようになるでしょう。
<img src="/wp-content/uploads/2017/05/webshare.png" alt="" width="640" height="347" class="aligncenter size-full wp-image-23510" srcset="/wp-content/uploads/2017/05/webshare.png 640w, /wp-content/uploads/2017/05/webshare-300x163.png 300w, /wp-content/uploads/2017/05/webshare-207x112.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>Mustacheは以下のURLで公開しています。<br />
Chrome for AndroidのCanaryを使い、Experimental Web Platform featuresのEnableにして利用してください。</p>

<ul>
<li><a href="bit.ly/mustaches-io" data-wpel-link="internal">Mustache</a></li>
</ul>

<p><img src="/wp-content/uploads/2017/05/MustacheURL.png" alt="" width="640" height="356" class="aligncenter size-full wp-image-23512" srcset="/wp-content/uploads/2017/05/MustacheURL.png 640w, /wp-content/uploads/2017/05/MustacheURL-300x167.png 300w, /wp-content/uploads/2017/05/MustacheURL-207x115.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>全てのAPIを1つのノードとしてみるとwebではPlug-inなしでこれらノード同士を無限につなげることができます。例えば、Media Streamを使えばカメラからCanvasに描画、アップロード、またマイクからWeb Audioそして、WebRTCのRTCPeerConnectionへと、たくさんのAPIと接続して利用することが可能です。</p>

<h1>まとめ</h1>

<p>デモに交えてたくさんのAPIを話しました。多くが現在でも利用可能なAPIです。</p>

<p>Biografでは、Service Workers、Media Session API、Full Screen API、Screen Orientation APIなどを使っています。フランソワが<a href="bit.ly/mobile-web-video-playback" data-wpel-link="internal">こちらに記事として</a>まとめてくれていますので詳しくはそちらを参照してください。</p>

<p>映像の再生等に関わるProgressive Web Appを書く場合は<a href="bit.ly/pwa-media-code" data-wpel-link="internal">Biografのコード</a>を参考にするとよりよいExperienceを提供できるでしょう。<br />
そしてMustacheで使っているMediaStream Recording API、Media Capture API、Media Streams APIは現在でも利用可能です。</p>

<p>最後に、以下の3つは特にFeedbackをお待ちしています。</p>

<ul>
<li><a href="http://wicg.github.io/background-fetch" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Background Fetch</a></li>
<li><a href="http://wicg.github.io/shape-detection-api" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Shape Detection API</a></li>
<li><a href="http://wicg.github.io/web-share" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Share API</a></li>
</ul>

<p>ありがとうございました！</p>

<h1>おわりに</h1>

<p>個人的に数年前から年に数回はFacebookをモバイルwebから使う儀式をしています。写真や動画を撮ってシェアしたりするのが特にですが不自由な点がありました。</p>

<p>また、QRコードの読み取りも必ずモバイルのNativeアプリ、またはインターネットへの接続が必須とされていました。それを元に考えると近年のWebブラウザの進化には目を見張るところがあり、また同時にその進化を肌で実感できるエキサイティングなプラットフォームの1つだと思います。</p>

<p>今後も映像のみならず、他の分野でのWebブラウザの発展、拡張も期待できそうですし、その進化から目が離せないですね。</p>
]]></content:encoded>
		
		<series:name><![CDATA[Google I/O 2017特集]]></series:name>
	</item>
		<item>
		<title>ブラウザベンダーとエキスパートが語るWebテクノロジーの未来【後編】──Webの未来を語ろう 2017</title>
		<link>/yoshikawa_t/22014/</link>
		<pubDate>Thu, 09 Feb 2017 01:00:54 +0000</pubDate>
		<dc:creator><![CDATA[吉川 徹]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Progressive Web Apps]]></category>

		<guid isPermaLink="false">/?p=22014</guid>
		<description><![CDATA[連載： Webの未来を語ろう 2017 (4) 特別企画「Webの未来を語る」のエキスパート、ブラウザベンダー対談の後編です。前編はこちらから。今年1年のWeb業界を占うということで、エキスパート、ブラウザベンダーの方々...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/future-of-web-2017/" class="series-426" title="Webの未来を語ろう 2017" data-wpel-link="internal">Webの未来を語ろう 2017</a> (4)</div><p><style>
b.speaker {
  font-weight: bold;
}
b.speaker::after {
  content: ": ";
}
</style>
特別企画「Webの未来を語る」のエキスパート、ブラウザベンダー対談の後編です。前編は<a href="https://html5experts.jp/yoshikawa_t/21986/" data-wpel-link="internal">こちら</a>から。今年1年のWeb業界を占うということで、エキスパート、ブラウザベンダーの方々に「Webの未来」について、がっつりお話を聞いてきました。</p>

<h1>どこから、どこまでが Progressive Web Apps？</h1>

<p><b class="speaker">白石</b>
PWAは、すごい重要なキーワードだと思いますが、どこまでがPWAなんですかね？ 厳密に定義付けする必要があるとも思わないんですが、モバイルのホーム画面にアイコンを追加するとか、プッシュができますというところまではPWAなんだろうと思うんですが、BluetoothだとかUSBだとかはPWAと言えるのかどうか。</p>

<p><b class="speaker">えーじ</b>
一応基準として挙げられるものは2つあって、1つは<a href="https://developers.google.com/web/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Fundamentals</a>というサイトに<a href="https://developers.google.com/web/progressive-web-apps/checklist" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">チェックリスト</a>をのせています。あまり明確に定義するのはやめようという話は当初ありましたが、ただそれだとちょっと曖昧すぎるということで、いくつかポイントを挙げてチェックリストになっています。チェックリストの中身は、今後増える可能性はあります。</p>

<p>もう1つは、「Lighthouse」というものを<a href="https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Chromeの拡張機能</a>と<a href="https://www.npmjs.com/package/lighthouse" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">node module</a>で出しています。拡張機能のほうを使うと、見ているページのスコアを出しくれるというものです。今後これがDevToolsにも入る予定で、AuditでWebサイトの分析をユーザーエクスペリエンス視点でやるという感じになります。その評価基準のひとつとして、PWAの対応状況をスコアリングしてくれるようになります。</p>

<p><b class="speaker">矢倉</b>
そういえば、<a href="https://developer.chrome.com/devsummit/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Chrome Dev Summit</a>のセッションの中のひとつで、<a href="https://www.youtube.com/watch?v=U52dD0tegsA&amp;t=5m9s" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Chromeチームの定義として「Webのエクスペリエンスを根本的に向上させるもの」</a>という風に紹介されていました。ここで言うエクスペリエンスは何かというと、速くて、信頼できて、ユーザーとのエンゲージメントもある。それでいて、モバイル向けサイトとPWAと別に作るんじゃなくて、<strong>ひとつのドメインでWebのエクスペリエンスを向上させるのがPWA</strong>だよ、と説明していました。<strong>使う技術スタックだけではPWAじゃないというとこに踏み込んだ</strong>なっていう印象がありますね。</p>

<p><b class="speaker">えーじ</b>
<strong>スピード周りもすごく重要で、そういう意味ではHTTP/2だとかHTTPSへの対応もPWAの要素のうちのひとつ</strong>と数えるといえば数えられます。モジュールローディングなどで、どうやってモジュールをいかに早くロードするか、などもそうですね。そこはノウハウとかもこれからどんどん溜まっていって、そのあたりが今一番面白いところだと思うんですけど、これから1年ぐらいでおそらくいろいろ整備されてくるかなと思います。</p>

<p><b class="speaker">白石</b>
WHATWGのローダーみたいな？</p>

<p><img src="/wp-content/uploads/2017/01/038994f99bc81d0cb4aaf0d3a5d57424.jpg" alt="" width="640" height="419" class="aligncenter size-full wp-image-22054" srcset="/wp-content/uploads/2017/01/038994f99bc81d0cb4aaf0d3a5d57424.jpg 640w, /wp-content/uploads/2017/01/038994f99bc81d0cb4aaf0d3a5d57424-300x196.jpg 300w, /wp-content/uploads/2017/01/038994f99bc81d0cb4aaf0d3a5d57424-207x136.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker">矢倉</b>
それよりかはどちらかというと、フレームワークとかのほうになるのかなって思います。Webpack 2のtree-shakingとか。仕様は実装を待たないといけないので、いま手をつけ始めやすいところという意図なのかなと。</p>

<p><b class="speaker">白石</b>
少し前に公開した<a href="https://html5experts.jp/shumpei-shiraishi/21837/" data-wpel-link="internal">Angularのインタビュー</a>で、結論のところでAngularも半年ごとにメジャーバージョンアップしていって、もしかしたら後方互換性のことは気にせずにやっていくかもしれないと。なので、Webの進化にどんどん追随していくという感じで、Webの進化とAngularの進化が両輪で進んで行くみたいな感じになるのかな、っていう形で終わったんですけど、そんな感じで捉えていけばいいんでしょうか？</p>

<p><b class="speaker">えーじ</b>
それとはあんまり関係ないかな（笑）。一般的なエコシステムというか<strong>プラットフォーム（基盤）が動いていく仕組みとして、Webの場合どんどん変えていく、進んでいる</strong>っていうことなのかなと思います。Angularもそれに追随するためにそういう動きをとっていると捉えれば、<strong>当然開発者側もそういう体制をとっていく必要がある</strong>なと僕はすごく感じます。</p>

<p>なので、受託開発で年に1回大きく予算を取って開発するというよりは、ちゃんと継続的に開発していくような体制をとっていったほうがいいんじゃないかなと思いますね。</p>

<h1>Progressive Web Appsは、完全にモバイルアプリとしても動くようになる</h1>

<p><b class="speaker">えーじ</b>
ひとつ面白いのは、こないだのChrome Dev Summitで発表したんですが、<strong>PWAをホーム画面に追加するだけじゃなくてバイナリにもなります</strong>。apkファイル（Androidのアプリケーションパッケージ）ですね。</p>

<p><img src="/wp-content/uploads/2017/01/87f58726130db708d076eca38744285f.jpg" alt="" width="640" height="430" class="aligncenter size-full wp-image-22049" srcset="/wp-content/uploads/2017/01/87f58726130db708d076eca38744285f.jpg 640w, /wp-content/uploads/2017/01/87f58726130db708d076eca38744285f-300x202.jpg 300w, /wp-content/uploads/2017/01/87f58726130db708d076eca38744285f-207x139.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker">白石</b>
それって何か利点があるんですか？</p>

<p><b class="speaker">矢倉</b>
ランチャーの中に入ります。</p>

<p><b class="speaker">えーじ</b>
リソースの管理とかもアプリと同様にできるので、ユーザーからしてみると完全にアプリだと思って使うことができます。</p>

<p><b class="speaker">矢倉</b>
設定の中のアプリ一覧の中にリストされたりとかしますね。</p>

<p><b class="speaker">白石</b>
なるほど。Androidだと、このアプリはSDカードにデータを保存するとかそういう設定ができますよね。そういうこともできるようになるのかな？</p>

<p><b class="speaker">えーじ</b>
ちょっとそこまでは把握していないですけど、できるんじゃないですかね。</p>

<p><b class="speaker">白石</b>
完璧なアプリ扱いですね。それは面白いな。</p>

<h1>Firefox、EdgeのProgressive Web Apps対応状況は？</h1>

<p>あとMozillaさんにも聞きたいんですけど、Android版のFirefoxとかでPWAはやっているんですか？</p>

<p><b class="speaker">浅井</b>
やっていますよ。PWAをサポートしますっていうのは用語の出来た <a href="https://blog.mozilla.org/futurereleases/2015/11/17/extending-the-webs-capabilities-in-firefox-and-beyond/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">2015 年から表明していて</a>、アプリをホーム画面に追加するなど一通りできるようになってきていますが、フルスクリーンで起動するオプションへの対応などが抜け落ちていたり、細部でまだChromeさんに追いついていないところがあるのが正直な状況ですね。</p>

<p>何で遅れてるいるかについては、Firefox OSをやめてMozilla内で開発体制を切り替えていた影響もあります。Firefox OSをやめた理由は、純粋にWeb技術で全てを実現可能にしましょうって自分たちでリードして標準も作っていったんですが、誰も同じ標準を実装してくれない（笑）。<strong>それが単独実装の独自仕様状態になってしまなら、それはよくないエコシステム</strong>、もうひとつのWebベースのネイティブみたいになってしまうと良くないのでやめました。</p>

<p><strong>スマートフォンだけじゃなくてもっと多くのものがインターネットに繋がる時代なので、その時代に対応していくため力点を変えましょう</strong>と、スマートフォン向けのFirefox OSに注力していたモバイル周りの開発体制を切り替えている中で、PWA対応も一部遅れてしまいました。</p>

<p>よく見てる人はわかるかも知れませんが、Android版Firefoxは機能面の追加が少し緩やかな時期があります。ちょっと遅れているところはありますが、PWA対応も普通に入ってくると思ってください。Service Worker対応やホーム画面にアイコンを追加するメニューなどが(一部は開発版だけに)入っている通りです。</p>

<p><img src="/wp-content/uploads/2017/01/30de9eab044fbed0c1f6596c4a954da9.jpg" alt="" width="640" height="416" class="aligncenter size-full wp-image-22052" srcset="/wp-content/uploads/2017/01/30de9eab044fbed0c1f6596c4a954da9.jpg 640w, /wp-content/uploads/2017/01/30de9eab044fbed0c1f6596c4a954da9-300x195.jpg 300w, /wp-content/uploads/2017/01/30de9eab044fbed0c1f6596c4a954da9-207x135.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker">白石</b>
Firefoxでホーム画面にアイコンを追加して、それを押すとFirefoxで起動するんですか？</p>

<p><b class="speaker">浅井</b>
今は、Firefoxの新しいタブとして起動するっていう形です。Chromeだとオプション次第でフルスクリーンで起動できます。もう一つChromeとの違うのはFirefoxの場合は、今はアプリマニフェストがあるとメニューに「ホーム画面に追加」が出てきます。Chromeの場合には、何度も使っていたり、一週間の別の日に2回以上同じサイトを訪問すると勝手にバナーが出てきて、インストールしませんかと聞いてきますが、それをFirefoxでやるかどうかは未定です。</p>

<p><b class="speaker">白石</b>
プッシュ通知はどうですか？</p>

<p><b class="speaker">浅井</b>
プッシュ通知は随分昔に実装してますね。</p>

<p><b class="speaker">矢倉</b>
Edgeは、どうなんでしょう？</p>

<p><b class="speaker">物江</b>
現在、実装中です。<strong>もしかしたら次のバージョンで入るかも？</strong></p>

<p><b class="speaker">浅井</b>
僕らとしては、みんなで同じようにPWAに対応していくというのはある意味コンセンサスを取りながら実装する取り組みのひとつだと思っています。APIレベルのものってプログレッシブに、使う使わないって判断を段階的にできるから、それぞれのペースで実装したらいいと。</p>

<p>それに対してWeb Assemblyは、JavaScript言語仕様が違うと構文エラーで全く動かなくなるのと同様、バイナリ形式は最初から全員で確実に統一することが必須になるため、自分たちがリードしている取り組みでも先行アナウンスなどはせず、何から何まで各社と同時に行う体制にしているんですね。この辺りは特に頑張って一緒にやることを重視している取り組みです。</p>

<h1>次世代ブラウザエンジンを作るMozillaのQuantumプロジェクト</h1>

<p><b class="speaker">浅井</b>
Firefox OSのときにAPIを作りまくっても、リードしても誰もついてこなくて悲しい思いをするってのはある意味反省点としています。特にハードウェア系のAPI、例えば加速度センサーとか近接センサーなどはAndroid版の初期から実装してましたが、そういう単独でのAPI先行実装は一段落しています。</p>

<p>どちらかというと今は<strong>パフォーマンスをすごく重要視</strong>していて、Web Assemblyもその一つですが、同時に<strong>そもそもAPIレベルじゃなくってブラウザエンジン自体のアーキテクチャ自体を大きく変える余地があるだろう</strong>と、GPUを使ったり、CPUのマルチコアを活かすといったところに注力して、ブラウザエンジンを次世代のアーキテクチャに置き換えていく動きをしているところです。</p>

<p><img src="/wp-content/uploads/2017/01/143e9ff84d5f7a7d0a67441524fb0ca4.jpg" alt="" width="640" height="420" class="aligncenter size-full wp-image-22050" srcset="/wp-content/uploads/2017/01/143e9ff84d5f7a7d0a67441524fb0ca4.jpg 640w, /wp-content/uploads/2017/01/143e9ff84d5f7a7d0a67441524fb0ca4-300x197.jpg 300w, /wp-content/uploads/2017/01/143e9ff84d5f7a7d0a67441524fb0ca4-207x136.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker">矢倉</b>
Quantumですよね。</p>

<p><b class="speaker">浅井</b>
そうですね。<a href="https://dev.mozilla.jp/2016/11/a-quantum-leap-for-the-web/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Quantumプロジェクト</a>と呼んでいますが、Mozillaでは珍しく一時的に社内Confidentialとされていて、話をまとめて決めてから大々的に発表したプロジェクトです。といっても数ヶ月後にはすぐ発表されたので、長い間秘密にしていたわけではないですが。</p>

<p><b class="speaker">えーじ</b>
これは、<a href="https://servo.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Servo</a>と関係あるんですか？</p>

<p><b class="speaker">浅井</b>
関係あります。Servoは何年も前からの取り組みなのですが、高速な並列処理を書きやすいのは勿論セグメンテーション違反などはコンパイル時にエラーとして検出でき、確実で高速な並列処理をガンガン実装できる新言語<a href="https://www.rust-lang.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Rust</a>を作るレベルからブラウザエンジン自体のアーキテクチャまで、全てをイマドキに刷新した、新しいブラウザエンジンを実験的に開発してきたプロジェクトです。並列化大好きなインテルとかサムスンなども参加してくれました。</p>

<p>ただ、Servoというのはあくまで実験的なブラウザエンジンであり、本当にすべてのAPIとかすべてのブラウザ機能を実装することを目標にしているわけじゃないんですね。Servoで新しいアーキテクチャを確認して、検証されたアーキテクチャでうまくいくものを実際のユーザ向け製品であるFirefoxのコンポーネント単位で置き換えていくっていうのがQuantumプロジェクトです。<strong>Servoの成果をFirefoxに取り入れるっていうのがQuantum</strong>という関係です。</p>

<p>このQuantumプロジェクトでは例えば、レイアウトやCSSのスタイリング処理を高速化します。CSSのスタイリングってまずDOMツリーを使ってそれにCSSのルールを適用していくのですが、DOMツリーって要するにツリーだから、このサブツリーとこのサブツリーを並列処理できるっていうのは当たり前のデータ構造じゃないですか。</p>

<p>構造的に並列化が容易だっていうのは分かっているので、並列化しやすい言語とアーキテクチャを採用して作り直しました。よくブラウザが遅い原因にリフローとか挙げられますけど、そのリフロー時に発生する<strong>レイアウト処理時間の半分がスタイリングで、そのスタイリング処理が2倍、4倍とかいうオーダーで高速化します</strong>。</p>

<p>例えばこちらのビデオなどを見れば違いが分かります。</p>


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


<p>エフェクトが非常に滑らかになるデモ</p>


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


<p>たくさんのオブジェクトを高fpsで描画するデモ</p>

<p>こういうのって、やっぱりこれまで十何年もつかっていたブラウザエンジンそのままじゃ難しくって、次の世代のブラウザエンジンを作ろうって取り組みがこのプロジェクトです。Mozillaは、今ここに一番注力しています。</p>

<p><strong>2017年の前半のうちに、今お見せしたスタイルのスタイリングが数倍早くなる実装がFirefoxに入るのを目標にしていたり、WebRenderと呼んでるものなどもなんとか形にしたい</strong>なと思っています。他にもネットワークの並列化とか、キャッシュをうまくするとか、そのあたりもQuantamプロジェクトで取り組んでいるところは、まだまだお楽しみにというところです。Mozillaはいま、APIとかよりエンジンの世代交代にエンジニアのリソースをがっつり割いてる感じです。</p>

<h1>Mozillaのビジョンは、ブラウザに限らずインターネットのオープン性や、それに触れるための機会をどこまでも広げること</h1>

<p><b class="speaker">白石</b>
Mozillaさんは、IoTとか、そちらのほうに注力しているというのは存じてますが、そういったあたり、Webブラウザがどこまで広がるのか、広げられるのかとか、そういったビジョンみたいなものをお聞きしたいですね。</p>

<p><b class="speaker">浅井</b>
単純にモバイルのスマートフォンだけに注力するってのをやめて、IoT時代のブラウザとかブラウザエンジンみたいなことを考えて開発をしています。だから、個別のデバイスの話よりも、そういうインターネットがどこにでも広がって、Web技術がどこでも使われる時代に適したものを作る。</p>

<p>だから、Quantumのようにマルチコア時代のモダンなCPUをフル活用するプロジェクトに注力するし、日本ではGeckoを組み込み用のハードウェアに移植してブラウザエンジンをより広く使えるようにする<a href="https://github.com/mozilla-japan/gecko-embedded/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">プロジェクトGecko Embedded</a>に取り組んでいます。組み込み機器では普通、スマートフォンとは違うCPU (SoC)を使うんですけど、そちらではChromeもFirefoxもWebKitも、みんなまともにビルドすら通らないし、パフォーマンスも全然でない。</p>

<p>そういう課題をちゃんと解消し、組み込み機器でも使えるブラウザ1個ぐらい作りましょうって取り組みです。全体的に、具体的なプラットフォームや製品よりも、本当にベースラインとしての誰もが使い易いコアの部分を改良をしているという感じです。</p>

<p><b class="speaker">白石</b>
じゃあそういったどこまでも広げていこうっていうのがMozillaのビジョンになるわけですね。</p>

<p><b class="speaker">浅井</b>
そうですね。もともとインターネットのオープン性とか、それに触れるための機会とかを広げるのが目的で、そのための手段がブラウザなので。じゃあ、そのブラウザっていうのはインターネットが広がるに従って、全部、ブラウザという形をとるのか、ただのJavaScriptエンジンととるのかわからないですが、それを広げるというのが僕らのミッションです。</p>

<p><b class="speaker">白石</b>
最後に、Mozillaさんが考えているPWAも、Googleが考えているPWAも変わらなと思っていいんですかね？</p>

<p><b class="speaker">浅井</b>
僕らの独自のPWAの定義は作っていません。そういう意味では変わらないと思います。</p>

<h1>EdgeはWindowsの一部、当然これからもどんどん改良していく</h1>

<p><b class="speaker">白石</b>
物江さんにもいろいろお聞きしたいんですが、Microsoftが考えるPWAとかもGoogleやMozillaと変わらないんですかね？</p>

<p><b class="speaker">物江</b>
PWA自体の考えは変わらないですね。ただ、こちらにはまだ動いているものが何もなく、それがどういったものになるかということについては、社外で話して良いかどうか許可も取れていないので私の口からはなんとも言えません。だだ、さきほど矢倉さんがおっしゃってた Edge チームの Jacob Rossi の記事によれば、<strong>アプリのようにすべてのアクセス権をもっていて、ブラウザなしで実行されるようなものを目指している</strong>ようですね。あくまでもこの記事によれば、ですが。</p>

<p><b class="speaker">白石</b>
なるほど。PWAをのっけていくプラットフォームというのは、きっとWindowsになると思いますが、そのWindows × PWAっていうのがちょっと面白いところですね。</p>

<p><b class="speaker">物江</b>
今、<strong>収益の柱はクラウドになっているので、クライアントがなんであるとか、実はあまりに気にしていない</strong>んですよね。Azure使ってくれれば。本当にみんなPWAでアプリ作ってAzureを使ってください（笑）。</p>

<p><b class="speaker">白石</b>
でもビジネス上の話って結構重要かなと思っていて、Edgeのシェアをどこまで本気で伸ばすつもりがあるのか。ブラウザって直接収益には結びつかないじゃないですか。その上で、Microsoftがどこまで本気で今後もブラウザを改良していくのかっていうところは興味があります。</p>

<p><img src="/wp-content/uploads/2017/01/566aa19bc38ee8beb3c1ea65f21edb8e.jpg" alt="" width="640" height="416" class="aligncenter size-full wp-image-22053" srcset="/wp-content/uploads/2017/01/566aa19bc38ee8beb3c1ea65f21edb8e.jpg 640w, /wp-content/uploads/2017/01/566aa19bc38ee8beb3c1ea65f21edb8e-300x195.jpg 300w, /wp-content/uploads/2017/01/566aa19bc38ee8beb3c1ea65f21edb8e-207x135.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker">物江</b>
もちろんどんどんやります。何故かというと、うちのブラウザはWindowsの一部なので、Windowsに付随するところがいろいろあるんですね。例えば、<strong>例えば、<a href="https://blogs.msdn.microsoft.com/msedgedev_japan/2016/12/22/introducing-windows-defender-application-guard-for-microsoft-edge/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Windows Defender Application Guard</a>という機能では、Edgeの設定で信頼済みのサイトじゃないところでリンクをクリックするとHyper-Vシステムで完全にOSから仮想化されたプロセスが立ち上がって、そこでブラウザが動くのでマルウェアが動いたとしても外に出れない</strong>っていうものがあります。</p>

<p>そういった、Windowsとユーザーの安全、アクセシビリティを守るっていうところに注力していく形で進んでいます。<strong>ブラウザはWindowsの一部であり、Windowsユーザーの利便性をあげるために今後も取り組んでいきます</strong>。</p>

<p>現場でもすごく頑張っていて、<strong>DOMのパフォーマンスを上げることに非常に躍起になっています</strong>。こないだのアニバーサリーアップデートでも相当早くなりましたが、次回のアップデートでもさらに早くなります。EdgeからIEも起動できますが、<strong>IEはブラウザではなくて、従来のIEでしか動かないものを動かすためのランタイム</strong>として見ていただければ。</p>

<p>日本だと大人しく見えるかもしれないですけど、アメリカのほうではEdgeでWebのセッションとかすごくやってますね。Edgeサミットとかもやっていて、オンラインイベントとかも頑張っています。他にもEdgeのデベロッパー向けのサイトには、そこで求人することはまずないんですが、ブラウザ作りませんかっていう求人募集もやっていて、それぐらい力を入れて人を集めています。MozillaさんからもX-tag（Web Componentsのポリフィル）を作ってた方に来ていただいて、今はそれもMicrosoftがやってます。</p>

<p><img src="/wp-content/uploads/2017/01/2d6c8e6710f485c21d2f6be8cc015903.jpg" alt="" width="640" height="417" class="aligncenter size-full wp-image-22051" srcset="/wp-content/uploads/2017/01/2d6c8e6710f485c21d2f6be8cc015903.jpg 640w, /wp-content/uploads/2017/01/2d6c8e6710f485c21d2f6be8cc015903-300x195.jpg 300w, /wp-content/uploads/2017/01/2d6c8e6710f485c21d2f6be8cc015903-207x135.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker">白石</b>
じゃあ全然やる気ありますよって感じなんですね。ちなみにCordovaにも注力してるって聞いたんですけどほんとですか？</p>

<p><b class="speaker">物江</b>
はい、注力してますね。Visual Studioが絡んでいるのもあるし、やはり周り回ってAzureのお客さんになるじゃないですか。ぶっちゃけた話、Windows Phoneがバカ売れしてたらCordovaはやらなくてもいいんですが、お察しのとおり Windows Phone は数が出ていないんですよね（笑）。Webの技術者の方々がアプリを作ってくれて、Azureを使ってくれれば最高です。</p>

<p><b class="speaker">白石</b>
なるほど、じゃあMicrosoftは、XamarinやCordovaっていう<strong>クロスプラットフォームのテクノロジーに注力していく</strong>形ですね。</p>

<h1>そして、Appleは…？</h1>

<p><b class="speaker">白石</b>
話は変わりますが、ここにいないAppleは、どうなんでしょうか。ここにいるひとは、Webに対してものすごくアグレッシブに、こう変えていこう、良くしていこうとしていると思うんですけど、Appleがどう思っているのかは気になります。何かAppleについて知っていること、感じていることがあれば教えてください。</p>

<p><b class="speaker">えーじ</b>
面白いと思ったのは、WebKitからBlinkがフォークしたときにShadow DOMが入っていたんですけど、それをWebKitから消したんですよね。にもかかわらず、<strong>去年いきなりWeb Componentsの議論にAppleさんが入ってきて、過去に我々が作っていたWeb Components周りの仕様をv0として、Appleが加わって新しく刷新した仕様をv1という形でSafariにもめでたく、Shadow DOMが入りました</strong>。今後もCustom Elementなんかも入ってくることを考えるとすごくポジティブに捉えてもいいんじゃないかなと。</p>

<p><b class="speaker">白石</b>
いきなり今年頑張り始めて、ECMAScriptとかも一気に対応したんですよね。</p>

<p><img src="/wp-content/uploads/2017/01/2-DSC08585.jpg" alt="" width="640" height="412" class="aligncenter size-full wp-image-22057" srcset="/wp-content/uploads/2017/01/2-DSC08585.jpg 640w, /wp-content/uploads/2017/01/2-DSC08585-300x193.jpg 300w, /wp-content/uploads/2017/01/2-DSC08585-207x133.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker">浅井</b>
そうそう、なんかテクノロジープレビューだして、すごいアップデートニュース飛ばしまくってるなと思ったら、<strong>突然ECMAScriptの対応100%</strong>ですってすべてのブラウザをぶち抜いていったっていう。</p>

<p>ちなみに、現在ECMAScript 2015の対応はSafariが100%で、ECMAScript 2017くらいまでの仕様が安定している部分もSafari Technology Previewがリードしてるんですが、仕様議論中の先行実装ではFirefoxがトップでChromeが次、あとはその他大勢という感じで一気に下がるという感じで進められてきました。JavaScriptに限らず先進部分はだいたいその２者で実装していて、ある程度仕様が固まってくるとMSさんが追いついてくる、そんな流れですよね。Appleさんは、標準化されたものをどこかの段階でやるって決めたらいきなり投入してくる、サプライズが好きな会社。そんなイメージを持っています。</p>

<p><b class="speaker">矢倉</b>
かなり少数精鋭っていう印象を受けるし、やっぱり1年に1回しかアップデートされないブラウザエンジンというのももう少ないですし、やっぱり過去数年でWeb開発者のフラストレーションが溜まっていて、Safariが新しいIEだと揶揄されていた。そういう風に<strong>Web開発者からの印象が悪かったんですね、それを改善しようって本気になって、例えばテクノロジープレビューを出したりとかWebKitのブログをリニューアルして積極的に情報公開したり</strong>とかというのをやっています。</p>

<p>カンファレンスなんかのパネルディスカッションとかにも、あんまり出ないと思うんですけど、<strong>彼らは愚直に彼らの思うWebブラウザっていうものに対してしっかり取り組んでいるなっていう印象があります</strong>。とくにJavaScript APIも実装するだけじゃなくて、早くなくちゃ意味がないと言ってますし、かなり尖ったことをやっていると。</p>

<p>ただ、新しい機能、例えばService Workerとかに対しては、あまり反応がないってところで、やっぱりSafariがネックになるっていう感じのところはありますけど、別に彼らはAppleストアがあるからってあぐらをかいて、Webに関して注力していないとかそういうわけではないかなと思います。</p>

<p><img src="/wp-content/uploads/2017/01/60e1206c2867d66f70663c814af9e0c7.jpg" alt="" width="640" height="428" class="aligncenter size-full wp-image-22048" srcset="/wp-content/uploads/2017/01/60e1206c2867d66f70663c814af9e0c7.jpg 640w, /wp-content/uploads/2017/01/60e1206c2867d66f70663c814af9e0c7-300x201.jpg 300w, /wp-content/uploads/2017/01/60e1206c2867d66f70663c814af9e0c7-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker">白石</b>
ここ数年そう見えなくもなかったけど、実はそうでもないと。</p>

<p><b class="speaker">矢倉</b>
MacでSafari使うんですが、やっぱり普通に他のより速いんですよね。だからしばらくデフォルトブラウザにしてみたりとかしているんです。開発者ツールの違いや、新しい機能が載るまでに時間がかかる点で、開発者にとってはあんまり嬉しくない部分があるかもしれないですが、でもユーザーにとって使いやすいもの、早いものって考えると、それが彼らにとって一番の価値だろうと思います。もうちょっと開発者のほうにもアピールができるともっと健康的なのかなと思いますけどね。</p>

<h1>おわりに</h1>

<p><b class="speaker">白石</b>
最後に、皆さんからいろいろお話を聞いて、「Webの今後のビジョンとは何か」という問いに対しては、概ねPWAであるという印象を受けましたが、それで良いでしょうか？</p>

<p><b class="speaker">物江</b>
いろいろな動向を見ていると、そうとしか思えないですよね。</p>

<p><b class="speaker">えーじ</b>
少なくてもGoogleはそう考えています。というよりPWAっていう言葉が全部飲み込んでいるんですよ。なので、<strong>細かいところ見るとたぶん各社注力するところは違うと思うんですが、大きな視点で見ると全部PWAと言えるんじゃないかなと思います</strong>。そういう意味では、バズワード的な感じでよろしくないのかもしれないですけど、モバイルのWebを良くしていきましょう、クロスプラットフォームの部分を良くしていきましょうという想いなのかなと。</p>

<p><b class="speaker">矢倉</b>
えーじさんが最初にバズワードっていうふうに揶揄されてるって言ってましたけど、けどわかりやすいってところでPWAがある。でもPWAの細かいところをつついていくと、ただ<strong>Webの良さっていうのをもっと全面に押し出していこうというのを具現化したにすぎない</strong>のかなと思っていて、まあ新たなマーケティング要素という側面もありますが、ちゃんとWebをWebとしてプロモートするっていうところに再び舵をきったのかなと思います。</p>

<p><b class="speaker">白石</b>
なるほど。皆さん、貴重にご意見をどうもありがとうございました！
これにて対談を終わりにしたいと思います。</p>

<p><img src="/wp-content/uploads/2017/01/734fab59ce3b8b01cbf49333c1a26a1f.jpg" alt="" width="640" height="400" class="aligncenter size-full wp-image-22046" srcset="/wp-content/uploads/2017/01/734fab59ce3b8b01cbf49333c1a26a1f.jpg 640w, /wp-content/uploads/2017/01/734fab59ce3b8b01cbf49333c1a26a1f-300x188.jpg 300w, /wp-content/uploads/2017/01/734fab59ce3b8b01cbf49333c1a26a1f-207x129.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>
]]></content:encoded>
		
		<series:name><![CDATA[Webの未来を語ろう 2017]]></series:name>
	</item>
		<item>
		<title>ブラウザベンダーとエキスパートが語るWebテクノロジーの未来【前編】──Webの未来を語ろう 2017</title>
		<link>/yoshikawa_t/21986/</link>
		<pubDate>Wed, 08 Feb 2017 01:00:15 +0000</pubDate>
		<dc:creator><![CDATA[吉川 徹]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Progressive Web Apps]]></category>
		<category><![CDATA[Web標準]]></category>

		<guid isPermaLink="false">/?p=21986</guid>
		<description><![CDATA[連載： Webの未来を語ろう 2017 (3) HTML5 Experts.jp 副編集長兼エキスパートの吉川です。今年1年のWeb業界を占うということで、エキスパート、ブラウザベンダーの方々に「Webの未来」について、...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/future-of-web-2017/" class="series-426" title="Webの未来を語ろう 2017" data-wpel-link="internal">Webの未来を語ろう 2017</a> (3)</div><p><style>
b.speaker {
  font-weight: bold;
}
b.speaker::after {
  content: ": ";
}
</style>
HTML5 Experts.jp 副編集長兼エキスパートの吉川です。<strong>今年1年のWeb業界を占うということで、エキスパート、ブラウザベンダーの方々に「Webの未来」について</strong>、がっつりお話しを聞いてきました。</p>

<p>HTML5 Experts.jp 編集長の<a href="https://html5experts.jp/shumpei-shiraishi/" data-wpel-link="internal">白石</a>が、Googleのデベロッパーアドボケイトの<a href="https://html5experts.jp/agektmr/" data-wpel-link="internal">えーじさん</a>、
Web標準ウォッチャーとして有名な<a href="https://html5experts.jp/myakura/" data-wpel-link="internal">矢倉さん</a>、MicrosoftのWebエバンジェリスト<a href="https://html5experts.jp/osamum_ms/" data-wpel-link="internal">物江さん</a>、Mozillaの技術戦略マネージャ<a href="https://html5experts.jp/dynamitter/" data-wpel-link="internal">浅井さん</a>をお迎えして、興味深いお話が盛りだくさんです。今後のWeb業界の動向を追いかける上で、重要な内容となっているので、ぜひ読んでみてください！</p>

<p><img src="/wp-content/uploads/2017/01/925bb3aa11d7e25da388f51bfee74e49.jpg" alt="" width="640" height="406" class="aligncenter size-full wp-image-22033" srcset="/wp-content/uploads/2017/01/925bb3aa11d7e25da388f51bfee74e49.jpg 640w, /wp-content/uploads/2017/01/925bb3aa11d7e25da388f51bfee74e49-300x190.jpg 300w, /wp-content/uploads/2017/01/925bb3aa11d7e25da388f51bfee74e49-207x131.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h1>今、Web標準ってどうなってるの？ WHATWGとW3Cとか</h1>

<p><b class="speaker">白石</b>
皆さん、よろしくお願いします。最初に、僕が個人的に思っていることとして、最近Webのビジョンが見えないな、と。これまでのWebの歴史を見ると、例えば1990年代だったらWebが急拡大して、いろいろなサイトが出てきてきてわくわくしました。2000年代前半になると、Servletとか書きまくったり、XHTMLとかXMLも出てきて面白かった。2000年代後半だとWeb2.0のブームがあって、そして2010年代前半には、HTML5のムーブメントがあった。</p>

<p>それに対して、今どこに向かっているかということを考えると、そんなに楽しいビジョンが見えるかというと、あまりそうは感じていなくて。例えば、モバイルアプリが使う時間がのびて、Webブラウザ使う時間が短くなったかなとか。各社のWebに関する戦略の変更もあるかなと思うんですが、Chrome Appsがサポート終了だとか、IEの開発が終了してEdgeに移行したりとか、Firefox OSも今年終了ということもあって、これまでイケイケでWebを拡大していこうっていうところから曲がり角に来てるのかなと僕は感じています。</p>

<p>今後のWebがどういう流れになっていくのか、というところも見え難くなっていると。今日はWebの未来について何かビジョンを描くとか、少しでもそういうことができると嬉しいなと思います。</p>

<p>さっそくですが最初にWeb標準について、ちょっとお聞きしたいと思います。現在、WHATWGとW3CといったWeb標準はどうなっているのか、そこらへんの現状とかを教えてほしいと思います。では、矢倉さんお願いできますか？</p>

<p><img src="/wp-content/uploads/2017/01/613c0771d062008416b812affccdd1c8.jpg" alt="" width="640" height="410" class="aligncenter size-full wp-image-22034" srcset="/wp-content/uploads/2017/01/613c0771d062008416b812affccdd1c8.jpg 640w, /wp-content/uploads/2017/01/613c0771d062008416b812affccdd1c8-300x192.jpg 300w, /wp-content/uploads/2017/01/613c0771d062008416b812affccdd1c8-207x133.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker">矢倉</b>
正直、最近あんまり追いかけていないところもありますが、聞きたいのはWHATWG、W3Cだとか、HTMLの仕様がどうなっているのかというところだと思います。どこから話しましょうか。</p>

<p><b class="speaker">白石</b>
そうですね、仕様が分かれているというのはみんな知っていて、ただ詳しく仕様を追いかけていない僕ぐらいのレベルからすると、W3Cというのはスナップショットを取る団体に見えていると。W3CとWHATWGの仕様がちょっとぐらいズレがある、ぐらいは把握しているんですけど、まずそういう世の中の認識は正しいのか、みたいなところとか。現実の標準化の現場ではどうなのかというところが聞きたいですね。</p>

<p><b class="speaker">矢倉</b>
わかりました。まずW3CのHTML仕様というのは、10年前にスタートしましたが、その時点で既にあった2007年当時のWHATWGのWeb Applications 1.0という仕様をベースに進めたというのがW3Cの仕様です。WHATWGの仕様は、基本的にエディター（当時はIan Hickson）がフィードバックをMLから集めて、それを頭の中で考えてこねこねして書いたものが仕様に反映される。それをみんながレビューするという形です。それに対して、W3Cの策定プロセスは、<strong>とりあえず何か議題があったら、それについてみんなで話し合ってコンセンサスをまとめて、それから仕様に反映させる</strong>ということをやってたので、やり方に相違があったと思います。</p>

<p>WHATWGのほうは、<strong>ソフトウェア開発的なモデルとして仕様も同じように作っていくべき</strong>という意識でずっとやっていて、だからバージョンというのもとくに切っていません。マーケティング的な要素で「HTML5」と一瞬名前を変えたときもありますが、べつにバージョンを切ったというわけではありません。コミットされるたびに更新されるので、W3Cの仕様にある日付がついた仕様のドラフトも（一瞬つけたものが出たりしたんですが）、特にやらずに進めています。最新版が常にベストみたいな感じですかね。</p>

<p>一方で、W3Cにはまず勧告プロセスがあり、勧告しなきゃいけない以上、どこかでフィーチャーフリーズしないといけない。なので結局スナップショットになってしまう。勧告が必要なのかというと、<strong>勧告されないと特許ポリシーが発効されないので、IPR（知的財産権）的に危うい状況になる</strong>んですね。そういうのがあって、仕様を固めないといけない。</p>

<p><img src="/wp-content/uploads/2017/01/0be44faae6809251e95f51732abe905c.jpg" alt="" width="640" height="423" class="aligncenter size-full wp-image-22036" srcset="/wp-content/uploads/2017/01/0be44faae6809251e95f51732abe905c.jpg 640w, /wp-content/uploads/2017/01/0be44faae6809251e95f51732abe905c-300x198.jpg 300w, /wp-content/uploads/2017/01/0be44faae6809251e95f51732abe905c-207x137.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>W3Cのほうがだんだんと乖離してきた原因のひとつが、Web Applications 1.0でHTML 4.01から変わった箇所、特にマークアップやアクセシビリティの変更に対して、HTML WG内外からいろんな議論があって、それに対処しないといけなかった。W3C側は、HTML WGだけじゃなくて関連する他のグループとも仕様について調整しないといけないんですが、特にアクセシビリティ関連の機能で話がまとまらなかった。まあ生産的でない議論がずっと続いているというのがあって、それに対処していった結果少しずつ離れてしまっている部分がでた。で、Hixieなどはそれをよしとしないので、Web Applications 1.0に反映されない。そういうのが続いて、<strong>完全にコミュニケーションがこじれた</strong>ので、今のよくわからない2つの仕様があるんですね。</p>

<h1>風向きが少し変わったGitHubへの移行</h1>

<p><b class="speaker">矢倉</b>
少しだけ風向きが変わったのが1〜2年前で、WHATWG HTMLがそれまでHixie(ヒクシー: Ian Hicksonの通称)がwhatwg.org上のリポジトリで個人でやってたものがGitHubに移行したんですね。そしたら、<strong>みんなPull Requestを投げたりとか、issueを作って議論するようになってきたりして、少しずつコミュニティみたいに、みんなで作る仕様みたいになってきた</strong>。そうしたら、W3C側からも仕様を一致させようという動きが少しあって、多少一致したところもあります。ただ、マークアップ絡みのところだとやっぱり、Hixieや彼の周りの人が入れた仕様が受け入れられずまたこじれたまま、どうにもいかないところもあります。いまHixieは完全に離れちゃったんですけどねえ。</p>

<p>例えば、アウトラインアルゴリズムでWHATWGのほうでは、セクションの見出しとしてh1をレベルに応じて使うんじゃなくて、全部h1でいいよっていうのがあったんですけど、W3Cの中ではそれが省かれちゃったんですね。というのもスクリーンリーダーがちゃんと対応していないからという理由です。実装状況とかも反映するのがWHATWGのやり方なんで、W3C側で省かれた変更を取り込もうというのもGitHubのほうでissueができたんですが、それが受け入れられずに放置されているとかいうのもあります。ひいてはコミュニケーション不足、解消するにしてもちょっとこじれすぎててどうしたらいいのかわからないっていう気がします。</p>

<p><b class="speaker">白石</b>
なるほど。Hixieはもう離れちゃったんですね。</p>

<p><b class="speaker">矢倉</b>
離れてますね。今は<a href="https://flutter.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Flutter</a>っていう、ちゃんと見てないんですが、アプリ版のUnity…つまりXamarinみたいなものですかね、それに関わってるようです。あと個人では、IoTみたいな感じのことやってるみたいです。</p>

<p><b class="speaker">白石</b>
あ、Googleもやめたんですか？</p>

<p><b class="speaker">矢倉</b>
Googleはやめてないですね。FlutterはGoogleでつくられてるので。あと、Flutterに関わってる人を見ると、以前Chromeをやってた人とDartをやってたひとが集結していたりもしてて、なんか不思議です。</p>

<p>W3Cがフォークになってしまってる状況はぼくもなんとかしてくれとは思うんですけど、結局、特許ポリシーまわりなのかなあと。<strong>特許ポリシーがないと、実装に特許的な問題がでたときに、どこからも守ってもらえなくなる</strong>じゃないですか。そうすると<strong>Webプラットフォーム自体の進化が止まってしまう</strong>ので、大人の付き合いは必ずしないといけないんじゃないかなあと。まあ、それをどこまで一般のWeb開発者が認識しなければいけないというのはありますし、別の話ではあるんですが。</p>

<p>ブラウザベンダーの人は、WHATWGの仕様を見ているんすよね。逐次アップデートされていくので、APIなんかの仕様はWHATWGのほうが安定度合いが高いと見ている。特許の部分てそこら辺に関わることが多いでしょうから、そこがちゃんと特許ポリシーで守られるべきだし、そうなるとW3C側の仕様でAPIの乖離が起こるのはよくない。そこはなんとかする仕組みがあればなあと思います。</p>

<p><img src="/wp-content/uploads/2017/01/7a0a3ddd1f8a78e72ed9a8464381cb77.jpg" alt="" width="640" height="425" class="aligncenter size-full wp-image-22037" srcset="/wp-content/uploads/2017/01/7a0a3ddd1f8a78e72ed9a8464381cb77.jpg 640w, /wp-content/uploads/2017/01/7a0a3ddd1f8a78e72ed9a8464381cb77-300x199.jpg 300w, /wp-content/uploads/2017/01/7a0a3ddd1f8a78e72ed9a8464381cb77-207x137.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>で、API部分の乖離というのは、ただWHATWG HTMLのほうが更新されてるだけで、話がこじれたからというものってかなり少ないんじゃないかなと思うんですよね。ちゃんと調べたわけではないですが、大体マークアップのところに多いような気がします。マークアップのところでは、仕様を読む限りはW3Cのほうが筋がいいと感じるところも少なからずあって、例えばルビのマークアップとかでしょうか。WHATWGのやつだとあんまり嬉しくないようなものが確か残ったままだったような気がしています。</p>

<p>ただ、マークアップは、あっちの仕様でこう書いてあるけどこっちの仕様ではこう書いてあるからどっちを選ぶというのよりも、それも踏まえてどう使うかを自分で判断するってところが大事じゃないのかいと思うんですよね。結局、CSSとかJavaScript APIとかだって開発するときに「これはこのブラウザで対応してないからどうする」とか、ブラウザの対応状況を見て決めているわけじゃないですか。それと同じことをマークアップでやればいいんじゃないかなと思います。都合が悪い仕様ならそれは突っ込むべきなんですが、グループの政治的なところを、仕様を選ぶ理由にすべきじゃない。そんなのただただナンセンスなだけですよね。</p>

<h1>普段Webを開発している人のフィードバックを得る仕組みが必要</h1>

<p><b class="speaker">白石</b>
マークアップで問題になっているところって、rubyとかh1とか、hgroupとか。timeとかもいろいろ問題ありましたね。</p>

<p><b class="speaker">矢倉</b>
そうですね。あ、で、マークアップの仕様について言うと、まだ仕様がこなれてないんじゃないかと思うことがしばしばなんですよね。Hixieは基本的にかなり合理主義なところがあって、例えばブラウザのリバースエンジニアリングをして、その当時ブラウザが実装していたものを仕様に落とし込むってことをやっています。HTMLパーサなどが最たる例でしょうか。</p>

<p>でも、マークアップに関していうとかなり理想主義で、だいぶ厳格な考えを持つ人という印象があります。それがアウトラインアルゴリズムだったりとかに現れてるんですよね。HTML 4.01にはStrictという、タグセットを絞った厳格な定義がありますが、HTML5のはそれよりもさらに厳格なマークアップを要求しているように思います。もちろん、HTML5の策定当時にもそこらにあるHTMLのマークアップをまとめて、それをもとに要素を追加してたんですが、ちょっと理想が強すぎて、世の中のマークアップに対応できずに進んできたのかなあと。</p>

<p>で、HixieのHTMLがどれぐらい「Strict以上」かというと、ひとつの例としては、もう仕様からは10年前ぐらいに消えたんですけど<a href="https://github.com/whatwg/html/commit/cb6b5fbce258293cb5d15e3a5dcd62c9bbef648f#diff-36cd38f49b9afa08222c0dc9ebfe35ebL5023" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">predefined classses</a>っていって、class名の値を特定の値だけに限定してそれ以外のclassを使ったらnon-conformingにするっていう仕様があったぐらいなんですよね。さすがに消えましたけど、それくらいドラスティックな変更を仕様に盛り込んだりしてたんです。rel属性の値とか、メタタグの名前も似たように限定してて、それは今でも残ってたりはしますね。</p>

<p>もちろんこれも、あとから解釈を広げた結果ふんわりしすぎちゃったってことにならないようにという意図があったとは思うんですが、フィードバックがなかったから使いづらい仕様のままになってしまってるケースってあるような気がするんですよね。</p>

<p>ブラウザの実装に係わるアルゴリズムやAPIの部分に関しては、数多くフィードバックが寄せられたので今のいい仕様があるわけですけど、<strong>マークアップのところはそういう仕様のフィードバックサイクルがまわらなかった</strong>のかなと。これは、普段WebサイトやWebアプリを開発している人のフィードバックが少なかったていうのもひとつあると思うんですよね。フィードバックを送って、それを適切に処理して反映させるっていうことができないと、作られるWebサイトやアプリのマークアップまわりがちょっと窮屈になって、結果としてユーザーの不利益になるかもしれない。もう起こってるかもしれないので、それを避けるように動かないといけないのかなあと。</p>

<p><img src="/wp-content/uploads/2017/01/b6a4d8e30f423ce41f77e50a13164af1.jpg" alt="" width="631" height="398" class="aligncenter size-full wp-image-22039" srcset="/wp-content/uploads/2017/01/b6a4d8e30f423ce41f77e50a13164af1.jpg 631w, /wp-content/uploads/2017/01/b6a4d8e30f423ce41f77e50a13164af1-300x189.jpg 300w, /wp-content/uploads/2017/01/b6a4d8e30f423ce41f77e50a13164af1-207x131.jpg 207w" sizes="(max-width: 631px) 100vw, 631px" /></p>

<h1>Microsoftはどちらの仕様を参照するか、というよりもデファクトを重視</h1>

<p><b class="speaker">白石</b>
それでは、さきほどの話を踏まえて、じゃあそれに対してブラウザベンダーの方々がどう標準を考えているのかみたいなところも聞きないとなと思います。そもそもブラウザベンダーの方々がみんなWHATWGのほうを参照しているっていうのは本当なんですか？</p>

<p><b class="speaker">物江</b>
うち（Microsoft）の最近の流れだと、<strong>相互運用性を非常に重視している</strong>ので、WHATWGにあるかどうかわからないことでも他のブラウザがやるのであれば対応しようっていうのがあります。結局のところ<strong>WHATWGかW3Cかっていうよりは、デファクトがどうか</strong>っていうところですね。</p>

<p><b class="speaker">白石</b>
なるほど。デファクトという話だと、パターンとしては2つあって、みんなで一緒に始めるか、それとも誰かに始めてもらってそのあとを続くかになりますね。</p>

<p><b class="speaker">矢倉</b>
デファクトが重要というのは確かにそうですね。能動的であるか、受動的であるか、残念ながらやるみたいな。MozillaとかOperaとかはそういうポジションになってるんじゃないですか（一同笑）。</p>

<p><b class="speaker">物江</b>
例えば、WebRTCだと、最初WebRTCを包括するORTCという仕様を提案して進めていたんですが、結局相互運用性の問題で従来のWebRTC 1.0を後から実装する形になりました。突っ張っちゃったけど、しょうがないねっていう（笑）。</p>

<p><b class="speaker">白石</b>
例えばWebAssemblyなんかはみんなで一緒にやりましょうって始まって、すごくいい感じになってますね。</p>

<p><b class="speaker">矢倉</b>
デファクトっていうと、XMLHttpRequestとかも元々IEが持っていたものをMozillaが組み込んで、Geckoがたしか最初だと思うんですけど、確かその後WebKitが追従したんじゃないかなと思います、そういう<strong>プロプラエタリなものでも、取り込んでいく</strong>。</p>

<p><b class="speaker">浅井</b>
サービス側での利用が広がっちゃうとそれはもうしょうがないですね。そういう意味ではMozillaも例えば、<strong><a href="https://www.mozilla.jp/blog/entry/10559/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">WebKitのプリフィックスがついた機能をFirefoxでもサポートする</a></strong>ということもやっています。</p>

<p><img src="/wp-content/uploads/2017/01/5ccd09d56b11a9bb4247268d20e432f1.jpg" alt="" width="640" height="417" class="aligncenter size-full wp-image-22041" srcset="/wp-content/uploads/2017/01/5ccd09d56b11a9bb4247268d20e432f1.jpg 640w, /wp-content/uploads/2017/01/5ccd09d56b11a9bb4247268d20e432f1-300x195.jpg 300w, /wp-content/uploads/2017/01/5ccd09d56b11a9bb4247268d20e432f1-207x135.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker">矢倉</b>
そうですね、仕方なしにやるのか、便利だからやろうっていうのはわからないですが、そういうことをやってるというのはあんまり昔と変わっていないのかなと。WebKitプリフィックスの話だと、その上にっていう名前がついちゃってプロプラエタリ感が満載だから心理的な抵抗があるってだけで、やってることに関してはたしかに同じですね。</p>

<p><b class="speaker">浅井</b>
プロプラエタリ感が満載っていうよりも、せっかく標準化されたのに古い構文が残っていて、それを捨てられずにいるってのは、やっぱりもう一つの抵抗の理由だと思う。でも残念ながらサイトが対応してくれない状況が続くんだったら、まぁしょうがないよねっていう。</p>

<p><b class="speaker">物江</b>
ベンダープリフィックスって、Mozillaが一回はずしたんですけど、またサポートしたんですよね。</p>

<p><b class="speaker">浅井</b>
そうですね。-moz-プレフィックスは外している一方で-webkit-プレフィックスのサポートを追加した状況です。</p>

<h1>Mozillaが日本のトップモバイルサイト100を調査して、修正依頼？</h1>

<p><b class="speaker">浅井</b>
実は、MozillaがWebKitプリフィックスをサポートする判断をした背景には日本市場の影響も結構あります。Mozillaには<a href="https://webcompat.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Compatibilityチーム</a>という、Firefoxに限らずWebサイトが誰にでも使えるようにするために取り組む部隊がいて、どのプレフィックスがどの程度ユーザの多いサイトで使われているかをこのチームで広く調査した上で、FirefoxでのWebKitプレフィックスの一部サポートを決断しました。</p>

<p>最初、中国とかアジアのサイトを見 ると酷かった。標準準拠コードを書いていないから、全然動かない。北米とかは最新標準仕様のコードを書くサイトが多いんですけど、中国のサイトはあまりにもひどいかった。</p>

<p>日本についても、<strong>日本のトップモバイルサイト100以上を片っ端から調査しました。動かないサイトがあったら原因が何かって徹底追求</strong>して、動かない原因と直すべきコードも全て調べた上で、各社にメールや電話をしまくり、Webのフォームやコンタクト先がなければ知り合いを通じて教えてもらうなどしてWeb担当者にFirefoxはもちろんIEなどでも意図通り動くコードへの修正をお願いしました。</p>

<p>その結果例えば、日経新聞とか、サントリーさんとか、ガールズチャンネルさんとかは直してくれたんですね。反応が面白かったのは、ガールズチャンネルさんなど、直し方わからなかったんです、ありがとうございますって即座に直してました（笑）。</p>

<p><b class="speaker">矢倉</b>
こうやったら直るっていうのまで伝えたんですね。</p>

<p><b class="speaker">浅井</b>
そうです。コードも全部、こうするだけで終わりですってところまで教えるんですね。例えば、ミクシィさんともこんな感じで直していただけますかって打ち合わせをしたのですが、彼らの場合 <a href="http://alpha.mixi.co.jp/entries/2015/12/20" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">5万行以上のCSSファイルがあったりするので、なかなかすぐには難しいとお断りされました</a>。いや、こういうツールを使うとプレフィックスがあるコードを自動変換できるやつもあるんですよってご紹介などもしたのですが、マネージャーレベルでは対応いただけなかったのです。</p>

<p>でもしばらくして、その打ち合わせに参加してくれていた現場のエンジニアの方が、次に携わるサービスでは提案してくれたツールを導入して対応しますとこっそり教えてくれました。その後それがmixi全体に広がりましたが、現場から変えてくれた彼には感謝しています。
最初から全体は直せなくても少しずつ直したりツールを用意したり教育をしたり、息の長い取り組みをしています。ただ、あまりにも日本やアジアのサイトはダメなところが多く、修正も時間がかかることが多くてユーザが不利益を被ってしまうため、非標準の標準化をしようっていったのが<a href="https://compat.spec.whatwg.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">あの仕様 (Compatibility Standard)</a>になります。</p>

<p>意外に思うかも知れませんが、<strong>日本のトップのIT企業が対応してくれないことが結構ありました。</strong> 社名は伏せさせてください(笑) 。当初は中国の特定サイトだけとか、日本の特定サイトだけブラックリストに入れて対応する案もあったのですが(実装もしていました)、トップ企業でも対応してくれない事例が多くあり、全サイトを対象とすることになりました。</p>

<p>ちなみに、他にも日本での調査を機に互換性対応で実装を変えた問題として、UA (UserAgent 名)があります。Mozillaとしては、ユーザのプライバシー確保とトラッキング対策のため、ユーザの絞り込みに繋がる情報は最小限とする方針であるため、主要ブラウザでも最もシンプルなUAとしており、AndroidのOSバージョンも含めていませんでした。</p>

<p>でも、日本のモバイルトップサイトを確認するとAndroidバージョンを入れると壊れるサイトと、入れないと壊れるサイトの両方があり、<strong>Androidバージョンを入れたときのほうが直るサイトの割合が遙かに高かったです</strong>。それである意味仕方なく、OSバージョンを入れることになりました。この話なんかもWeb標準仕様と同じように、実態に合わせつつ、あるいは他のブラウザの挙動に合わせつつ実装をしていっている事例の一つでしょう。</p>

<p><img src="/wp-content/uploads/2017/01/91cc91fe0a287c94e4e91d6e074e542b.jpg" alt="" width="640" height="427" class="aligncenter size-full wp-image-22042" srcset="/wp-content/uploads/2017/01/91cc91fe0a287c94e4e91d6e074e542b.jpg 640w, /wp-content/uploads/2017/01/91cc91fe0a287c94e4e91d6e074e542b-300x200.jpg 300w, /wp-content/uploads/2017/01/91cc91fe0a287c94e4e91d6e074e542b-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker">白石</b>
ちなみに、その非標準の標準化っていうのは本当に標準化するんですか、つまりW3Cのプロセスにのせたりとかするつもりがあるということですか？</p>

<p><b class="speaker">浅井</b>
WHATWGでは[Compatibility Standard]（https://compat.spec.whatwg.org/）という仕様として書いていますが、W3Cでやるかっていうとそれはわからないですね。あんまそういう動きはないと思います。</p>

<p><b class="speaker">矢倉</b>
あ、でも一部の機能はCompat Standardみたいなパッチではなくて、標準仕様にとりこまれてます。たとえば、<code>Element.matches()</code>という、ある要素が特定のCSSセレクタにマッチしてるか判別する仕様があるんですけど、それが昔の仕様だと<code>matchesSelector()</code>という名前で、それがWebKitでは<code>webkitMatchesSelector()</code>として実装されていたんですね。で、互換性のために仕様で定義しようって話になったときに、それはもうCompatibility Standardじゃなくて、<a href="https://dom.spec.whatwg.org/#dom-element-webkitmatchesselector" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">DOMの仕様の中で定義した</a>んですよね。そういうのもあります。</p>

<p><b class="speaker">浅井</b>
<a href="https://developer.mozilla.org/ja/docs/Web/API/Node/innerText" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">innerText</a>とかもそうですね。<strong>標準のtextContentしかサポートしないって僕らは言い張ってたんですけど、僕らだけサポートしないっていってても日本などのサイトは直らないから仕方がないということでinnerTextでも動くようになりました</strong>。<a href="https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">標準にも反映されています</a>。</p>

<h1>新しい取り組みである「Origin Trial」とは？</h1>

<p><b class="speaker">えーじ</b>
ベンダープリフィックスの問題って結構長くあって、それを解決する方法として、Chromeでは基本的にExperimentalな機能をStableに入れないっていうのを始めたんですよね。もうその機能は、Betaまでのバージョンまでしか動きませんっていう状態で、まずは実装をはじめて、最終的にそれをStableにのせるために必ずコンセンサスをとらないといけない。</p>

<p>なのでMLにIntent to Shipっていうメールを出すんですが、それで合意が得られて、実装が2つ以上存在している場合にのみStableにのせるという段階を踏むようになりました。なので、新しい機能については基本的にはある程度、成熟した仕様であり、かつ実装も問題ないという合意が得られたうえでshipしますというような状態になっています。</p>

<p>最近始めたOrigin Trialというのがあって、それは<strong>新しい機能をStableにのせるけど、あらかじめ使いたいと手を挙げたサイトでのみが使える</strong>というもの。それをやるためには、フォームで申請をして、そのトークンをサイトに載せることによってブラウザがホワイトリストでその機能を動かす、そうすると我々としてもどのサイトがそれを実装してるかわかるし、もし仮にそれにひどい変更が入りますってときにもコンタクトをとることができると。</p>

<p><b class="speaker">矢倉</b>
あと、Origin Trialは、一定期間過ぎたら終了するっていうのもありますね。</p>

<p><img src="/wp-content/uploads/2017/01/1f1666875aa1d18f84b6da8b9f69656c.jpg" alt="" width="640" height="417" class="aligncenter size-full wp-image-22044" srcset="/wp-content/uploads/2017/01/1f1666875aa1d18f84b6da8b9f69656c.jpg 640w, /wp-content/uploads/2017/01/1f1666875aa1d18f84b6da8b9f69656c-300x195.jpg 300w, /wp-content/uploads/2017/01/1f1666875aa1d18f84b6da8b9f69656c-207x135.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker">浅井</b>
Origin Trialは、面白いなと思って見ています。その機能が大規模に使われると、サイトのドメインの数が少なくても例えばfacebook.comで使われてしまうと後戻りできなくなるので、ユーザーの数が一定以上を超えたら無効になるっていう仕組みがある。そういうのをちゃんと考えているのが面白いなと思う。</p>

<p>今後、全面的にOrigin Trialになっていくのかどうかとか、例えばBLE（Bluetooth Low Energy）は、Origin Trialに入れながらやって、この時期には標準にするよって宣言しながら実装されてます。それが宣言された時期までに他のブラウザが実装しているかどうかというのは、本当にshipする基準にするのか、それとももう宣言してしまったから実装がなくてもshipするのか、どっちなのかなという点を気にしながら見ています。</p>

<p><b class="speaker">矢倉</b>
Origin Trialは、もともとマイクロソフトの人が提案してたんですよね。<a href="https://www.w3.org/wiki/TPAC2014/SessionIdeas#Beyond_Vendor_Prefixes" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">EdgeチームのJacob RossiがW3CのTPACで提案</a>してて、そこにChromeチームのAlex Russellものっかっていて、もしかしたら二人のアイディアなのかもしれないですけど、最終的にChromeだけでやってはいますけどね。</p>

<p>Origin Trialは、APIのローンチカスタマーを作る意味でも結構良いのかもしれないですね。手厚くフィードバックも得られるし、カジュアルに試して見たよっていうよりもこういう業界的なニーズがあるから使いたいということでOrigin Trialに申請するといったら、ChromeのDevRelのひとも反応しやくすくなるのかなっていう気がします。</p>

<p><b class="speaker">白石</b>
たしかに。ニーズがあるかわからない機能が入ってくるとかもありますしね。</p>

<p><b class="speaker">矢倉</b>
そして不幸になるっていうのはHTML5でいくつか経験してますからね。</p>

<p><b class="speaker">浅井</b>
Extensible Webのときからそうだというイメージありますが、やっぱり<strong>ブラウザベンダーと標準化団体だけで作っていたらもうダメだ</strong>っていうのがよくわかっていて、いかにデベロッパーの声を集めて標準化に反映するかが大事です。Origin Trialはそれを実現する手段を具体化した手段の一つだと思うので、非常に面白いと思って見ています。</p>

<h1>GoogleはWebが目指すべきところに必要な機能があればどんどん進めていく</h1>

<p><b class="speaker">白石</b>
ちょっとえーじさんに聞いてみたいなと思ったのは、さっきEdgeはデファクトを追いかけますって話だったので、だとすると、まず最初に実装するベンダーとかが必要になってくるじゃないですか、デファクトを作る人たちが必要なので。それって、ここでいうとGoogleとか、Mozillaとか動きが早そうだなと。そうすると、どの仕様を実装するかを決めるのってどういう基準でやってるのかなというところを聞きたいなと。</p>

<p><b class="speaker">えーじ</b>
社内的にはやっぱり、<strong>Webが目指すべきものっていうのをざっくり持っていて、その中でじゃあそのピースを埋めるために必要なのはどの機能なのかっていう判断をして、なければ作る</strong>しっていう感じで進めちゃいますね。他がやるのを待ってるっていうスタンスではないです。</p>

<p><img src="/wp-content/uploads/2017/01/c1854feee5c205321b919f7fd72f394e.jpg" alt="" width="640" height="423" class="aligncenter size-full wp-image-22043" srcset="/wp-content/uploads/2017/01/c1854feee5c205321b919f7fd72f394e.jpg 640w, /wp-content/uploads/2017/01/c1854feee5c205321b919f7fd72f394e-300x198.jpg 300w, /wp-content/uploads/2017/01/c1854feee5c205321b919f7fd72f394e-207x137.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker">白石</b>
なるほど。具体的いうと、例えばService Workerとかなんですかね？</p>

<p><b class="speaker">えーじ</b>
そうですね。ひとことで言っちゃえばProgressive Web Appsっていう話になるかと思います。以前より一言ですむんでだいぶ言いやすくなりましたね（笑）。今までは、一生懸命Service WorkerとAdd to Homescreenと〜、とか説明しなきゃいけなかったのが一言で済むので個人的にはありがたいですけど。所詮マーケティング用語みたい感じの部分もあって、結構揶揄されたりしますが、一言で表せるという意味ではモバイルに対するWebの回答と考えるとわかりやすくて良いのかなと思います。</p>

<p>ここ最近は、Webが割と盛り返してきた感じを受けてるんですけど、去年までの2〜3年ぐらいの間ってやっぱり日本の各社もWebチーム解散してAndroidにリソース注ぎ込むとか、ざらにあったりとかしてWebがだいぶ負けてきているっていうのはすごく思っていたんですけど、Service WorkerとかPWAの流れがでてきて、だいぶ盛り返してきた感じがあります。</p>

<h1>Progressive Web AppsはモバイルWebをいかによくするかのムーブメント</h1>

<p><b class="speaker">えーじ</b>
PWAに対する反応もすごくいいんですよね。なので、そういう意味では<strong>モバイルでのWebをいかによくしていくかっていうムーブメント</strong>として僕はPWAを捉えている。技術的には細かい話はいっぱいありますけど、そのピースをどう組み合わせていくかっていうのは各ブラウザベンダーの判断もあるでしょうし、思惑もあるでしょうが、最近は足並みが揃ってるという感じがしています。</p>

<p><b class="speaker">物江</b>
EdgeでもPWA周りの仕様は、開発中のステータスになっているので、近いうちにEdgeでも使えるようになる可能性がありますね。</p>

<p><b class="speaker">矢倉</b>
EdgeチームのJacob Rossiが<a href="https://medium.com/web-on-the-edge/progressive-web-apps-on-windows-8d8eb68d524e" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Mediumに投稿</a>していて、WindowsでPWAを考えるとブラウザの中だけにとどめておくってことはしないで、WindowsストアだとかBingの検索結果に乗せるだとか、PWAをインストールしたら、それがスタートメニューやランチャーに乗るとかも検討しているらしいですね。</p>

<p><b class="speaker">物江</b>
Chrome Appsみたいになるらしいです（笑）。</p>

<p><b class="speaker">えーじ</b>
話をややこしくした（笑）。</p>

<p><b class="speaker">白石</b>
Chrome Appsは、サポート終了するのに（笑）。</p>

<p><b class="speaker">えーじ</b>
ある意味それは正しくて、Chrome Appsを終了する理由って、Webの標準を盛り上げていかないといけないのにChrome Appsというプロプラエタリなものに注力し続けるよりは、<strong>Webの標準からネイティブ的なアプリが作れるようになるべき</strong>であるという感じです。</p>

<p><b class="speaker">白石</b>
じゃあ、Chrome Appsに実装されていたBluetooth APIやUSB API、Socket APIとかは。</p>

<p><b class="speaker">矢倉</b>
USB APIはOrigin Trialになってますね。</p>

<p><b class="speaker">えーじ</b>
Socket APIは、入っていないですね。それをやるかどうかも決まっていないと思います。要望があれば受け付けますというフォームもあるので、その辺はデベロッパーのユースケース次第という感じですかね。</p>

<p><b class="speaker">白石</b>
なるほど。少なくてもそれらを標準化にのせていこうという意図は、持っているということですかね？</p>

<p><b class="speaker">えーじ</b>
モチベーションがある人がいればやるって感じですね。社内でそれを是非やりたいという人がいれば仕様も書くだろうし、実装もすると思います。いい例でいえば、PaymentRequest APIとかCredential Management APIとか、最近はここら辺を担当しているんですが、やっぱり担当のチームがきちんとあります。Paymentsに関してはMozillaさんやMicrosoftさんと並行して実装も進めていると思います。</p>

<p><b class="speaker">物江</b>
Paymentsは、Edgeでも開発中なので、近いうちに。</p>

<p>（<a href="https://html5experts.jp/yoshikawa_t/22014/" data-wpel-link="internal">後編</a>へ続く）</p>
]]></content:encoded>
		
		<series:name><![CDATA[Webの未来を語ろう 2017]]></series:name>
	</item>
		<item>
		<title>プログレッシブウェブアプリ詳解 ─ 過去・現在・未来</title>
		<link>/agektmr/20527/</link>
		<pubDate>Wed, 14 Sep 2016 00:00:03 +0000</pubDate>
		<dc:creator><![CDATA[えーじ]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[システム開発]]></category>
		<category><![CDATA[Progressive Web Apps]]></category>
		<category><![CDATA[Service Worker]]></category>

		<guid isPermaLink="false">/?p=20527</guid>
		<description><![CDATA[連載： Web技術でアプリ開発2016 (5)Web技術でアプリ開発2016特集・第5弾は、プログレッシブウェブアプリ (Progressive Web Apps)をご紹介させていただきます。 はじめに プログレッシブウ...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/web-based-apps-2016/" class="series-391" title="Web技術でアプリ開発2016" data-wpel-link="internal">Web技術でアプリ開発2016</a> (5)</div><p>Web技術でアプリ開発2016特集・第5弾は、プログレッシブウェブアプリ (Progressive Web Apps)をご紹介させていただきます。</p>

<p><style>
.youtube {
    height: 0;
    position: relative;
    padding-bottom: 56.25%;
    overflow: hidden;
    margin-bottom: 24px;
}
.youtube > iframe {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
}
</style></p>

<h2>はじめに</h2>

<p>プログレッシブウェブアプリ(Progressive Web Apps)という言葉が初めて登場したのは2015年8月のAlex Russellによる記事<a href="https://medium.com/@slightlylate/progressive-apps-escaping-tabs-without-losing-our-soul-3b93a8561955" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Progressive Web Apps: Escaping Tabs Without Losing Our Soul</a>です。当時オフラインやプッシュ通知など、モバイルウェブを飛躍的に進化させる画期的な機能が次々と追加されていた状況において、このムーブメントを呼称するための言葉が求められていました。Google社内でいくつもの候補が挙げられましたが、Service Workerの発案者としてAlex Russellが推したのが、この「プログレッシブウェブアプリ」でした。</p>

<p>また、当初Googleで始まったプログレッシブウェブアプリの動きではありましたが、先日の<a href="https://www.youtube.com/playlist?list=PLNYkxOF6rcIAWWNR_Q6eLPhsyx6VvYjVb" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Progressive Web App Dev Summit</a>ではMicrosoft、Mozilla、Opera、Samsungの代表者も登壇するなど、各ブラウザベンダーとも足並みが揃いつつあります。これはもはやウェブ全体の動きと言うことができます。</p>

<p>若干古い情報になりますが、以降この (長い) 記事を読む以外に手早く情報を得るための方法として、下記を挙げておきます。</p>

<h3>スマートフォン体験を一歩先へ &#8211; プログレッシブウェブアプリの作り方</h3>

<div class="youtube">

<!-- iframe plugin v.4.3 wordpress.org/plugins/iframe/ -->
<iframe style="width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;" src="https://www.youtube.com/embed/VHN2wJWi0WE?controls=2&amp;modestbranding=1&amp;showinfo=0&amp;utm-source=crdev-wf" class="devsite-embedded-youtube-video" allowfullscreen data-video-id="hmqZxP6iTpo" data-autohide="1" data-modestbranding="1" data-controls="2" data-utm-source="crdev-wf" data-showinfo="0" frameborder="0" width="100%" height="500" scrolling="yes"></iframe>

</div>

<p><a href="https://www.youtube.com/watch?v=VHN2wJWi0WE" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">講演動画</a></p>

<div class="youtube">

<!-- iframe plugin v.4.3 wordpress.org/plugins/iframe/ -->
<iframe src="https://docs.google.com/presentation/d/1VcXsKDaCUpf2SS35WNcrKslkK6PcXxWsnhcKiLfWCXs/embed?start=false&amp;loop=false" width="100%" height="500" scrolling="yes" class="iframe-class" frameborder="0"></iframe>

</div>

<p><a href="https://docs.google.com/presentation/d/1VcXsKDaCUpf2SS35WNcrKslkK6PcXxWsnhcKiLfWCXs/pub?start=false&amp;loop=false&amp;delayms=3000" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">プレゼン資料</a></p>

<h2>プログレッシブウェブアプリとは</h2>

<p>プログレッシブウェブアプリとは、最新の標準ウェブ技術を用いることで、オフラインやプッシュ通知といったこれまでよりも一次元上のユーザー体験をもたらすウェブアプリのことです。必ずしもデスクトップのウェブアプリや、ページ遷移を使ったサーバーサイドでレンダリングされるアプリを除外するものではありません。</p>

<p>理屈で説明するよりも、実際に体験した方が早いかと思います。いくつか具体例を挙げましょう。</p>

<ul>
<li><a href="https://www.flipkart.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Flipkart</a></li>
<li><a href="http://www.washingtonpost.com/pwa/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Washington Post</a></li>
<li><a href="https://m.aliexpress.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">AliExpress</a></li>
<li><a href="http://smp.suumo.jp/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">suumo</a></li>
</ul>

<p>※ 他にも様々なプログレッシブウェブアプリが既に存在していますが、<a href="https://pwa.rocks/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">pwa.rocks</a>というサイトにいくつかまとまっていますので、ぜひご覧頂下さい。</p>

<p>実際に使ってみるとわかりますが、これらのアプリケーションにおいてこれまでにない特徴的な点がいくつかあります。</p>

<ul>
<li>ホーム画面に追加してワンタップで起動</li>
<li>キャッシュを使ってオフライン、もしくは高速に動作</li>
<li>プッシュ通知を送信</li>
<li>自動でログイン</li>
</ul>

<h2>プログレッシブとは何か</h2>

<p>「プログレッシブ」という言葉自体は直訳すると「進歩的な」といった意味がありますが、ピンとこない方は多いと思います。</p>

<p>プログレッシブウェブアプリの「プログレッシブ」のひとつの意味は、ウェブページとして使い始めたサービスが、ホーム画面に追加し、オフラインで動作し、プッシュ通知を送り始めるといった流れの中で、「徐々にアプリへと変化していく」様を指しています。</p>

<p>もう一つ意味があります。</p>

<p>フロントエンドエンジニアであれば、プログレッシブ・エンハンスメントという言葉を聞いたことがあると思います。プログレッシブ・エンハンスメントとは、HTML5 時代に続々と新しい機能が登場する中で、最新の標準技術をまだ盛り込んでいないブラウザでも、情報を届けるといった目的をゴールに、必要最低限の機能をベースとして、可能であれば最新技術を使うことでよりリッチな体験を提供する、という設計コンセプトのことを言いました。(逆に、リッチな体験を提供できるブラウザをベースに、最新の技術が使えないブラウザでも最低限の目的は達成できるように設計する手法をグレースフル・デグラデーションと呼びました)</p>

<p>プログレッシブウェブアプリも同様に捉えることができます。つまり、必要最低限の機能を提供できる状態をベースとし、オフラインやプッシュ通知などをプログレッシブな (進歩的な) 機能として提供する、というものです。</p>

<p>これは言い方を変えれば、対応していないブラウザがあるからといって対応を待つべきではなく、それを前提としてウェブを前に進めていこう、というメッセージでもあるのです。実際、プログレッシブウェブアプリ対応への副作用として、複数の機能に未対応のブラウザでも<a href="https://developers.google.com/web/showcase/2016/aliexpress" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">コンバージョンレートが改善したという事例</a>も出ています。</p>

<h2>アプリとウェブのギャップ</h2>

<p>Web2.0の時代を経てコンピューターの世界はネイティブアプリケーションからウェブアプリケーションの時代へと変化を遂げました。地図アプリケーションを思い出して下さい。その昔CD-ROMからせっせとインストールする必要のあった地図が、URLひとつでブラウザから見られるようになったのです。他にも例を挙げればキリがありません。</p>

<p>ウェブはその後もHTML5やその周辺技術の発展により大きく進化していきました。しかしその恩恵を満足の行く形で受けられたのはデスクトップでの話。モバイル・スマートフォンの時代となり、ユースケースが変化していく中で、スマートフォン上で快適に目的を達成するためには、ウェブブラウザは力不足と言われるようになってしまいました。その象徴的な出来事の一つがFacebookのCEOマーク・ザッカーバーグによるこの発言でした。</p>

<p><a href="http://jp.techcrunch.com/2012/09/14/20120911mark-zuckerberg-our-biggest-mistake-with-mobile-was-betting-too-much-on-html5/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Disrupt：ザッカーバーグ、「HTML5を過大評価したのは、われわれ最大の失敗」と認める | TechCrunch Japan</a></p>

<p>これはひとえに標準化を必要とするウェブという環境の特性ゆえと言わざるを得ません。標準化を進めつつ実装し、浸透を待たなければならなかったウェブと異なり、ネイティブアプリはモバイルに最適化した仕様や機能を次々と取り込み、技術革新を起こしていきました。</p>

<p>しかしウェブには、ネイティブアプリでは実現できない特性も持ち合わせています。それが<strong>SLICE</strong>と呼ばれるものです。</p>

<ul>
<li>Secure (安全)</li>
<li>Linkable (リンク可能)</li>
<li>Indexable (インデックス可能)</li>
<li>Composable (再構成可能)</li>
<li>Ephemeral (一時的な利用)</li>
</ul>

<p>ウェブもネイティブも、お互いの短所を埋める進化を遂げていく中で、ウェブが着実に前進していることの現れが、プログレッシブウェブアプリと言えるでしょう。一度はHTML5化を断念したFacebookがプッシュ通知を採用したのはその最たる例です。</p>

<p><a href="http://jp.techcrunch.com/2015/09/15/20150914facechrome/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Facebook、Googleと協力してモバイルウェブユーザーにプッシュ通知を送信</a></p>

<p>プログレッシブウェブアプリはWeb 2.0、HTML5と続いてきた大きな流れの、次の一歩と捉えて間違いありません。</p>

<h2>プログレッシブウェブアプリを構成する機能</h2>

<p>プログレッシブウェブアプリはそれ自体が機能を表しているわけではなく、様々な先進的機能をまとめたひとつのムーブメントです。具体的にどんな機能があるのか、ひとつひとつ見ていきましょう。</p>

<ul>
<li><a href="#pw-https" data-wpel-link="internal">HTTPS</a></li>
<li><a href="#pw-manifest" data-wpel-link="internal">Web App Manifest</a></li>
<li><a href="#pw-sw" data-wpel-link="internal">Service Worker</a></li>
<li><a href="#pw-cache" data-wpel-link="internal">Cache API</a></li>
<li><a href="#pw-push" data-wpel-link="internal">Web Push / Push Notifications</a></li>
<li><a href="#pw-bg" data-wpel-link="internal">Background Sync</a></li>
<li><a href="#pw-budget" data-wpel-link="internal">Web Budget API</a></li>
<li><a href="#pw-credential" data-wpel-link="internal">Credential Management API</a></li>
<li><a href="#pw-payment" data-wpel-link="internal">Payment Request API</a></li>
</ul>

<h3 id="pw-https">HTTPS</h3>

<p>プログレッシブウェブアプリに対応する上で大前提になるのがサイトの完全なHTTPS対応です。ログイン画面や商品購入画面だけではなく、すべてのページをHTTPS化する必要があります。</p>

<p>一般的に、HTTPSに対応することでウェブサイトは</p>

<ul>
<li>ウェブサイトの一意性を守るアイデンティティ(Identity)</li>
<li>サーバー・ブラウザ間の通信を秘匿するコンフィデンシャリティ(Confidentiality)</li>
<li>送受信されるデータを改ざんさせないインテグリティ(Integrity)</li>
</ul>

<p>の3つを手に入れることができます。</p>

<p>プログレッシブウェブアプリ対応において重要なのが、以下でご紹介する機能のほとんどがHTTPS上でのみ動作 (<a href="https://www.w3.org/TR/secure-contexts/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">セキュアコンテキスト</a>)するという点です。こういった機能はPowerful Features と呼ばれ、以前はHTTP上でも動作したgetUserMediaやgeolocationといったAPIもそこに加えられ、最近HTTPSのみで動作する変更が加えられました。</p>

<p>HTTPSに対応することなしにプログレッシブウェブアプリを実現することは不可能ですので、対応を検討する方はここからスタートして下さい。(ちなみにChromeでは、localhostとfile://もセキュアコンテキストに含まれますので、開発時は少し役に立つかもしれません)</p>

<div class="youtube">

<!-- iframe plugin v.4.3 wordpress.org/plugins/iframe/ -->
<iframe src="https://www.youtube.com/embed/YMfW1bfyGSY" frameborder="0" 0="allowfullscreen" width="100%" height="500" scrolling="yes" class="iframe-class"></iframe>

</div>

<h3 id="pw-manifest">Web App Manifest</h3>

<p>ネイティブアプリとウェブサイトを比較した時に、最も大きく異なるのがアクセスのしやすさです。もちろん、アプリのようにインストールしなくても、リンクを踏むだけでアクセスできるという意味で、ウェブは手に届きやすい存在です。しかしスマートフォンの場合、デスクトップのようにキーボードで手軽に検索ができるわけではありません。ホーム画面からタップひとつで起動できるだけで、ユーザーにとっての身近さは大きく改善します。</p>

<p><img src="/wp-content/uploads/2016/09/Screenshot_20160901-153533-169x300.png" alt="screenshot_20160901-153533" style="width: 169px; height: 300px;" class="aligncenter size-medium wp-image-20903" /></p>

<p>そこで登場するのがWeb App Manifestです。Web App Manifestを使うことで、該当ページに関する様々な情報を定義することができます。</p>

<p><a href="https://developer.mozilla.org/ja/docs/Web/Manifest" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web App Manifest | MDN</a></p>

<p>最近は<code>lang</code>や<code>scope</code>、<code>screenshots</code>といった項目も新しく追加されていますので、その辺りも注目して下さい。</p>

<p>これらの情報を踏まえ、「ホーム画面に追加」をすると、ウェブアプリはホーム画面に鎮座することができるようになります。しかし、この機能がiOSでも古くからある<code>meta</code>タグを使ったものに近いと思われた方もいるかもしれません。</p>

<p>Chromeの場合、このWeb App Manifestといくつかの条件が加わることで、ブラウザが自動的にホーム画面に追加を促してくれる、という点が大きく異なります。詳しくは下記の記事を参照して下さい。</p>

<p><a href="http://qiita.com/horo/items/ff665e4a6613e7684f8f" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web App ManifestでWebアプリをインストール可能に &#8211; Qiita</a></p>

<h3 id="pw-sw">Service Worker</h3>

<p>Service Workerはプログレッシブウェブアプリを構成する機能の中でも、コンセプトを成立させた一番の立役者で、中核を成すものです。</p>

<p>従来のウェブにおいて、ページはサーバーから送られたHTMLとそれに付随するリソースで構成される機能がすべてであり、ページが閉じられると同時に忘れ去られる存在でした。Service Workerは、ページとは独立して動作するスクリプトを、ページを閉じた後でもブラウザ上で動かし続けることができる機能です。このService Workerを活用することで、様々な可能性が開かれます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/serviceworker.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/serviceworker-640x99.png" alt="serviceworker" width="640" height="99" class="alignnone size-large wp-image-20543" srcset="/wp-content/uploads/2016/08/serviceworker.png 640w, /wp-content/uploads/2016/08/serviceworker-300x46.png 300w, /wp-content/uploads/2016/08/serviceworker-207x32.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><strong>オフライン</strong>：Service Workerはページが送信するあらゆるリクエストを横取りすることができます。実質的なローカルプロキシーとなるため、強力なキャッシュを活用すれば、ネットワークに接続していない状態でもレスポンスを返すことができるようになります。詳しくはCache APIの項で説明します。</p>

<p><strong>プッシュ通知</strong>：Service Workerはページが閉じた状態でも、また、ブラウザによっては起動してない状態であっても、イベントを検知することができます。そのため、外部サーバーが送信したプッシュリクエストをイベントとして受け取り、何かしらのアクションを起こすことができるのです。詳しくはWeb Push / Web Notificationsの項で説明します。</p>

<p>それでは、Service Workerの使い方を雰囲気だけ見てみましょう。</p>

<p>Service Workerは独立したJavaScriptとして動作するため、ファイルも分けて記述する必要があります。例えばページ上で動作するスクリプト<code>app.js</code>が、<code>service-worker.js</code>というService Workerを使いたいとします。</p>

<p></p><pre class="crayon-plain-tag">navigator.serviceWorker.register('service-worker.js', {scope: './'});</pre><p></p>

<p>これだけでService Workerが登録されます。簡単ですね。</p>

<p><code>service-worker.js</code>の中身はイベント・ドリブンのスクリプトになります。例えば下記のように記述しておけば、あらゆるリクエストをService Workerが拾い上げて、サーバーにリクエストを転送することなく&#8221;Hello World!&#8221;とレスポンスを返します。</p>

<p></p><pre class="crayon-plain-tag">self.addEventListener('fetch', function(event) {  
  event.respondWith('Hello World!');  
});</pre><p></p>

<p>Service Workerは実際いつ動作を開始するのでしょう？影響範囲はどこまででしょう？こういった細かい話になるとセキュリティへの懸念も出てくるため、若干複雑な内容を理解する必要が出てきます。scopeとライフサイクルについては抑えておきましょう。</p>

<h4>scope</h4>

<p>Service Workerが登録されると、以後半永久的にスクリプトを動かし続けることになります。仮にService Workerがドメインの範囲内すべてに影響をおよぼすことができるとすると、ブログなどのユーザーの権限がパスで区切られたサービスでは、自分の預かり知らないスクリプトが埋め込まれてしまう可能性がでてきます。そこでService Workerでは、scopeという概念を使って影響範囲を制限します。詳しくはこちらの記事が参考になります。</p>

<p><a href="http://qiita.com/nhiroki/items/eb16b802101153352bba" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ServiceWorkerのスコープとページコントロールについて &#8211; Qiita</a></p>

<h4>ライフサイクル</h4>

<p>Service Workerが登録されたあと、スクリプトを手動で更新したい場合もあります。新しいスクリプトはすぐに有効になるのでしょうか？その場合古いスクリプトはどうなってしまうのでしょうか？Service Workerは放っておいたら永久に更新されないのでしょうか？</p>

<p>Service Workerのライフサイクルを正しく理解することはとても重要です。下記の記事をぜひご覧ください。</p>

<ul>
<li><a href="http://www.html5rocks.com/ja/tutorials/service-worker/introduction/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Service Workerの紹介: Service Workerの使い方 &#8211; HTML5 Rocks</a> (一部古い内容が含まれます)  </li>
<li><a href="https://blog.jxck.io/entries/2016-04-24/service-worker-tutorial.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">中級者向け Service Worker Tutorial | blog.jxck.io</a>  </li>
<li><a href="http://blog.nhiroki.jp/2015/07/05/service-worker-registration" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Service WorkerのRegistration</a>  </li>
</ul>

<h4>デバッグ</h4>

<p>Chromeではプログレッシブウェブアプリのデバッグをしやすくするために、最近DevToolsにResourcesパネルの代わりに Applicationパネルが追加されました。Manifestや各種ストレージなどを、ひとつのパネルからまとめて確認することができます。中でもService Worker専用の項目では、現在起動中のスクリプトだけでなく</p>

<ul>
<li>Offline &#8211; オフラインのエミュレーションボタン</li>
<li>Update on reload &#8211; リロードするだけでService Workerを更新</li>
<li>Bypass for network &#8211; ネットワークリクエストの横取りを一時的に停止</li>
</ul>

<p>といったオプションが利用できます。ここからService Workerの単独のDevToolsを開いてデバッグを行ってください。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/devtools.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/devtools-640x238.png" alt="devtools" width="640" height="238" class="alignnone size-large wp-image-20542" srcset="/wp-content/uploads/2016/08/devtools.png 640w, /wp-content/uploads/2016/08/devtools-300x112.png 300w, /wp-content/uploads/2016/08/devtools-207x77.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<h4>少し未来の話</h4>

<p>今後利用可能になるService Worker周辺の重要な機能についても少し触れておきましょう。</p>

<p><strong>Link rel=serviceworker</strong>
Chrome 54からOrigin Trial (特定のドメインに実験的にホワイトリストで機能を提供) ベースでService Workerの登録が linkタグやHTTPヘッダーで行えるようになりました。将来的にこれが利用できるようになれば、JavaScriptを記述することなく、linkタグやHTTPヘッダーのみでService Workerを登録できるようになります。</p>

<p></p><pre class="crayon-plain-tag">&lt;link rel="serviceworker" href="/js/sw.js" scope="/"&gt;</pre><p></p>

<p><a href="https://www.chromestatus.com/feature/5682681044008960" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://www.chromestatus.com/feature/5682681044008960</a></p>

<p><strong>Foreign fetch</strong>
また、Web Fontsのような複数ドメインから共有されるリソースをCDN経由で提供するサーバーのリソースも、現在は利用する側のService Workerがハンドリングすることが可能ですが、これをCDN側のService Workerがハンドリングできれば効率が向上します。これを可能にする機能はForeign Fetchと呼ばれ、Chrome 54からOrigin Trialベースで提供が開始されています。</p>

<p><a href="https://www.chromestatus.com/feature/5684130679357440" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://www.chromestatus.com/feature/5684130679357440</a></p>

<p>その他、Service Workerのさらに詳しい情報はHTML5 Conference 2016で行われたChromeエンジニアの保呂さんのスライドが参考になります。<br />
<a href="https://goo.gl/YxL2L7" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Service Worker Deep Dive</a></p>

<h3 id="pw-cache">Cache API</h3>

<p>先程説明したように、Service Workerを使ってあらゆるリクエストを横取りすることで、オフラインの機能が実現可能になります。そこで強力なキャッシュ機能を提供するのがCache APIです。</p>

<p>Cache APIは取得されたリソースだけでなく、リクエストやレスポンスの内容も含めて保存されます。下記の例では、キャッシュが残っていればキャッシュされていたレスポンスを、なければサーバーにリクエストを送って、返ってきたレスポンスを返します (キャッシュに保存はしません)。</p>

<p></p><pre class="crayon-plain-tag">self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request).then(function(response) {
      return response || fetch(event.request);
    })
  );
});</pre><p></p>

<p>Cache APIを使った実例について、詳しくはこちらの記事が参考になります。</p>

<p><a href="http://qiita.com/horo/items/175c8fd7513138308930" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ServiceWorkerとCache APIを使ってオフラインでも動くWebアプリを作る &#8211; Qiita</a></p>

<p>なお、Cache APIを扱う上で fetch()も避けては通れませんが、ググらビリティの低さから、まとまった資料が見つかりにくいという問題があります。こちらのページがよくまっていたのでリンクしておきます。</p>

<p><a href="http://qiita.com/tomoyukilabs/items/9b464c53450acc0b9574" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">お疲れさまXMLHttpRequest、こんにちはfetch &#8211; Qiita</a></p>

<p>ここまで述べてきたように便利なService Worker + Cache APIですが、多くの人が似たようなコードを書くであろうことは容易に想像ができます。そこで便利なライブラリがいくつかあります。</p>

<h4>sw-toolbox</h4>

<p>リソースをキャッシュする際に必要になるのが、リソースの優先順位の判定です。例えば共通で利用されるJavaScriptファイルは、更新がない限りネットワークにリクエストを送るまでもなく常にキャッシュから読み込むことでスピードを優先したいと思うはずです。逆に例えば、天気アプリであれば、開く度に最新の天気予報を見たいですが、オフラインだった場合はオフラインだと言われるよりは、キャッシュからでもその後の天気予報を見たいと思うはずです。</p>

<p>このように、同じキャッシュを活用するでも、場面によってキャッシュを優先したいのか、ネットワークを優先したいのかが異なってきます。そこで便利なのが<a href="https://github.com/GoogleChrome/sw-toolbox" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">sw-toolbox</a>です。</p>

<p></p><pre class="crayon-plain-tag">toolbox.router.get('/myapp/index.html', toolbox.networkFirst);</pre><p></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/appshell.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/appshell-640x258.png" alt="appshell" width="640" height="258" class="alignnone size-large wp-image-20539" srcset="/wp-content/uploads/2016/08/appshell.png 640w, /wp-content/uploads/2016/08/appshell-300x121.png 300w, /wp-content/uploads/2016/08/appshell-207x83.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>sw-toolboxではネットワークを優先するnetworkFirst、キャッシュを優先するcacheFirstの他にもfastest、networkOnly、cacheOnlyといった様々なオプションが利用可能です。</p>

<p><a href="https://googlechrome.github.io/sw-toolbox/docs/master/index.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://googlechrome.github.io/sw-toolbox/docs/master/index.html</a></p>

<h4>sw-precache</h4>

<p>Service Workerを使ったキャッシュ機能以前にオフラインを実現する機能として登場した<a href="https://developer.mozilla.org/ja/docs/Web/HTML/Using_the_application_cache" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Application Cache</a>は、ページを初めて開いた時点で、予め定義されたリソースをすべてキャッシュするものでした。Service Worker + Cache APIにおいても同様のニーズはあるでしょう。例えばアプリの外枠や必要最低限のCSSやJavaScriptファイルを予めロードしておくことで、コンテンツ部分のみをダイナミックにロードすればよいという<a href="https://github.com/GoogleChrome/application-shell" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Application Shell</a>というアーキテクチャを利用する場合です。</p>

<p>これを実現するのに便利なライブラリが<a href="https://github.com/GoogleChrome/sw-precache" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">sw-precache</a>です。Gulp やGruntといったタスクランナーを使うことで、リストされたリソースを最初のロード時点でキャッシュしてしまうJavaScript のコードを出力してくれます。あとはこれをService Workerとしてロードすればよいだけです。また、リソースの更新もハッシュを使って自動的に管理してくれるので、どのファイルを書き換えたからリストを変更しなければならない、といったようなマニュアル作業が不要になります。</p>

<p></p><pre class="crayon-plain-tag">gulp.task('generate-service-worker', function(callback) {
  var path = require('path');
  var swPrecache = require('sw-precache');
  var rootDir = 'app';

  swPrecache.write(path.join(rootDir, 'service-worker.js'), {
    staticFileGlobs: [rootDir + '/**/*.{js,html,css,png,jpg,gif,svg,eot,ttf,woff}'],
    stripPrefix: rootDir
  }, callback);
});</pre><p></p>

<p>なお、最近追加されたruntimeCachingという機能を使うことで、<a href="https://github.com/GoogleChrome/sw-precache#runtimecaching-arrayobject" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">sw-toolbox の便利な機能を宣言的に記述</a>することもできます。</p>

<h4>sw-appcache-behavior</h4>

<p>もし既にApplication Cacheを使っていて、Service Workerに移行を検討している場合は、<a href="https://github.com/GoogleChrome/sw-helpers" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">sw-helpers</a>ライブラリの一部である<a href="https://github.com/GoogleChrome/sw-helpers/tree/master/projects/sw-appcache-behavior" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">sw-appcache-behavior</a>が便利です。既存の Manifestファイルをそのまま利用してService Workerによるオフラインを実現することができます。</p>

<h4>sw-offline-google-analytics</h4>

<p>オフラインのウェブサイトがうまく作れたとしても、ユーザーがどのアクセスページにアクセスし、どのように利用しているかが分からなければ、本当に役に立っているのかどうかを知ることはできません。これもsw-helpersの一部である<a href="https://developers.google.com/web/updates/2016/07/offline-google-analytics?hl=en" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">sw-offline-google-analytics</a>を使えば、オフライン中のアクセス解析をデータベース上に保存しておいて、オンラインになったタイミングでサーバーに送信してGoogle Analyticsでアクセス解析結果を閲覧することができるようになります。</p>

<h3 id="pw-push">Web Push / Web Notifications</h3>

<p>プッシュ通知は、プログレッシブウェブアプリを語る際、これまでできなかったことの中で、技術者ではなくても効果が理解できるという意味では、最も分かりやすい機能です。実際に既に多くのサービスがこれを利用しています。例えば Facebook です。<a href="http://m.facebook.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">モバイルウェブ版のFacebook</a>にアクセスしてみると、すぐにそのことに気付くでしょう。</p>

<p></p><pre class="crayon-plain-tag">navigator.serviceWorker.ready().then(function(sw) {
  sw.pushManager.subscribe({userVisibleOnly: true})
    .then(function(sub) {
      // パーミッション取得後
      sendSubToServer(sub);  // Send subscription to the server
  });
});</pre><p></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/push1.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/push1-640x130.png" alt="push1" width="640" height="130" class="alignnone size-large wp-image-20540" srcset="/wp-content/uploads/2016/08/push1.png 640w, /wp-content/uploads/2016/08/push1-300x61.png 300w, /wp-content/uploads/2016/08/push1-207x42.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p></p><pre class="crayon-plain-tag">self.addEventListener('push', function(event) {
  event.waitUntil(
    self.registration.showNotification(title, {
      body: body, icon: icon, tag: tag,
      actions: [{action: 'remindMe', title: 'REMIND ME'}]
    }
  });
});</pre><p></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/push2.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/push2-640x122.png" alt="push2" width="640" height="122" class="alignnone size-large wp-image-20541" srcset="/wp-content/uploads/2016/08/push2.png 640w, /wp-content/uploads/2016/08/push2-300x57.png 300w, /wp-content/uploads/2016/08/push2-207x39.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>具体的な実装方法は若干複雑ですので、サードパーティーのサービスを使うのも手かもしれません。自分で実装する場合は、こちらのドキュメントがよくまとまっています。</p>

<p><a href="http://qiita.com/tomoyukilabs/items/217915676603fda73b0a" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Pushでブラウザにプッシュ通知を送ってみる &#8211; Qiita</a><br />
<a href="http://qiita.com/tomoyukilabs/items/c7268aa29447a1d0a3fb" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Firefox (Developer Edition)でW3C Push APIを使ってみる &#8211; Qiita</a></p>

<p>Chromeの場合、以前はGCM (Google Cloud Messaging、もしくはFirebase Cloud Messaging)が必須でしたが、現在は<a href="https://tools.ietf.org/html/draft-ietf-webpush-protocol-08" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">標準の Web Push</a>が利用できます。詳しくは下記をご覧下さい。</p>

<p><a href="http://qiita.com/tomoyukilabs/items/8fffb4280c1914b6aa3d" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ChromeでW3C Push APIを使ってみた &#8211; Qiita</a></p>

<p>Web Pushについては、<a href="https://github.com/web-push-libs/web-push" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">node.js 向けのライブラリ</a>も提供されています。</p>

<h3 id="pw-bg">Background Sync</h3>

<p>妙なタイミングでネットワークがオフラインになってしまったために、リクエストが送れなかったという経験は誰しもあると思います。そんな時にリクエストをキューしておいて、オンラインになったタイミングで送ってくれるとありがたいですよね。それを実現してくれるのが、Background Syncです。</p>

<p><a href="http://qiita.com/horo/items/28bc624b8a26ffa09621" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ServiceWorkerのBackground Syncでオンライン復帰時にデータ送信 &#8211; Qiita</a></p>

<h3 id="pw-budget">Web Budget API</h3>

<p>現状Service Workerはプッシュを受信すると、通知を出さなければなりません。これはブラウザリソースの無駄遣いを防ぐためです。しかし、例えばバックグラウンドで購読しているフィードを更新するといったユースケースは容易に思いつきます。</p>

<p>そこで検討されているのが<a href="https://beverloo.github.io/budget-api/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Budget API</a>という機能です。これを使うことで、ページは与えられたバジェットを適切に配分してバックグラウンドでの処理を行うことが可能になりますので、リソースの無駄遣いを防ぎつつ必要な機能を実現できるようになるはずです。</p>

<p><a href="https://www.chromestatus.com/features/5691190548627456" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://www.chromestatus.com/features/5691190548627456</a></p>

<h3 id="pw-credential">Credential Management API</h3>

<p>Credential Management APIはユーザーのクレデンシャル (認証情報) を制御するためのAPIです。</p>

<div class="youtube">

<!-- iframe plugin v.4.3 wordpress.org/plugins/iframe/ -->
<iframe src="https://www.youtube.com/embed/O3mBdKYMsMY" frameborder="0" 0="allowfullscreen" width="100%" height="500" scrolling="yes" class="iframe-class"></iframe>

</div>

<p>これを使うことにより</p>

<ul>
<li>id / passwordをブラウザに覚えさせる</li>
<li>ソーシャルログインの選択肢をブラウザに覚えさせる</li>
<li>ログイン時にアカウント選択ダイアログを提供する</li>
<li>ユーザーを自動的にログインさせる</li>
</ul>

<p>といったことが可能になります。</p>

<p>典型的なユースケースとしては、ニュースサイトやコマースサイトといった、必ずしもログインしなくてもよい、しかし提供者側としてはログインしてもらいたいサービスにおいて役立ちます。実際に利用されている例としては<a href="https://m.aliexpress.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">AliExpress</a>の実装が非常によくできていますので、是非一度お試し下さい。</p>

<p>実装は基本的にフロントエンド側だけですので、比較的気軽に導入することができます。</p>

<ul>
<li><a href="https://credential-management-sample.appspot.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">デモアプリ</a> (<a href="https://github.com/GoogleChrome/credential-management-sample" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ソースコード</a>)</li>
<li><a href="https://developers.google.com/web/updates/2016/04/credential-management-api" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">翻訳済みのドキュメント</a></li>
<li><a href="http://g.co/codelabs/cmapi" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">実際に実装を体験できるコードラボ</a></li>
<li><a href="http://w3c.github.io/webappsec-credential-management/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">仕様</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Credential_Management_API" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">MDN リファレンス</a></li>
</ul>

<h3 id="pw-payment">Payment Request API</h3>

<p>Payment Request APIは支払い時のチェックアウトに必要なフォームを置き換えるUIを提供します。Chromeではバージョン 53から利用できるようになる予定です。</p>

<div class="youtube">

<!-- iframe plugin v.4.3 wordpress.org/plugins/iframe/ -->
<iframe src="https://www.youtube.com/embed/hmqZxP6iTpo" frameborder="0" 0="allowfullscreen" width="100%" height="500" scrolling="yes" class="iframe-class"></iframe>

</div>

<p>Payment Request APIが提供するのは、ユーザーインターフェースです。ブラウザのAutofill機能を活用することで、クレジットカードの情報や住所などを、すばやく簡単に入力できるようになります。</p>

<p>支払い方法は現状クレジットカードのみですが、まもなくAndroid Payも利用可能 (残念ながら当初日本は対象外) になる予定です。将来的には、さらに様々な支払い方法をオープンかつ柔軟に組み込めるようになっていく予定です。</p>

<ul>
<li><a href="https://developers.google.com/web/updates/2016/07/payment-request" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">アナウンス・概要</a></li>
<li><a href="https://developers.google.com/web/fundamentals/primers/payment-request/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">実装ガイド</a></li>
<li><a href="https://developers.google.com/web/fundamentals/primers/payment-request/android-pay" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Android Pay 実装ガイド</a></li>
<li><a href="https://www.w3.org/TR/payment-request/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">仕様</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Payment_Request_API" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">MDN リファレンス</a></li>
</ul>

<h3>その他の機能</h3>

<p>プログレッシブウェブアプリを語る上で数えるべき機能や考え方は他にもいくつかありますが、キリがありませんのでこの辺にしておきましょう。</p>

<ul>
<li>Web Bluetooth</li>
<li>Web MIDI</li>
<li>Web Animation</li>
</ul>

<p>興味のある方は、この辺りもぜひ抑えておいていただければと思います。</p>

<h2>Lighthouse</h2>

<p>あるウェブアプリを指してそれがプログレッシブウェブアプリかどうかを議論するのはあまり意味のないことですが、それを示す指標を得ることはできます。それが<a href="https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Lighthouse</a>というChrome拡張機能です。ウェブサイトを開いた状態でこの拡張を起動すると、プログレッシブウェブアプリの対応度合いをスコアで示してくれます。</p>

<p><img src="https://lh3.googleusercontent.com/69AN0502kzahk9AmzmLGzRvsVy_6zq2gUnPB8ZH2NIVKMF8DSf9qw44bIh2v9CDVy1FQHFMq1r1US9dey9mjUjA7jg_lLnLcXseLHMVGDDyjGVGetdVCJFu4YlZmQPW18jAcgdg-" alt="" /></p>

<p>Chrome拡張機能としてだけではなく、node moduleとしても利用が可能です。</p>

<p><a href="https://github.com/GoogleChrome/lighthouse" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://github.com/GoogleChrome/lighthouse</a></p>

<p>Lighthouseはまだアルファ版の段階のため、評価できない機能が多数ありますが、今後対応していく予定です。</p>

<h2>リソース</h2>

<p>プログレッシブウェブアプリに興味を持たれた方で、最新情報を追いかけたいという方は下記のページをご覧下さい。RSSフィードも配信しています。</p>

<p><a href="https://developers.google.com/web/updates/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://developers.google.com/web/updates/</a></p>

<p>資料が英語で読めない？英語が分かる人はぜひ、<a href="http://qiita.com/yoichiro6642/items/3afc2f01706398a5a458" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">翻訳にご協力下さい</a>。</p>

<h2>最後に</h2>

<p>プログレッシブウェブアプリについて長々と書いてきましたが、重要なのは決してこれらの機能すべてに対応することではありません。自分が提供するサービスがユーザーに最大の価値を提供するために必要であれば、ネイティブアプリを提供するべき場合もあるでしょう。オフライン機能だけが必要な場合もあるかもしれません。これらの機能をうまく組み合わせて、ユーザーが本当に求めている価値を提供できるアプリを開発していただければと思います。</p>
]]></content:encoded>
		
		<series:name><![CDATA[Web技術でアプリ開発2016]]></series:name>
	</item>
		<item>
		<title>モダンWeb：たった今と、ほんの少し未来のはなし～「de:code 2016」セッションレポート～</title>
		<link>/albatrosary/19092/</link>
		<pubDate>Wed, 25 May 2016 07:48:45 +0000</pubDate>
		<dc:creator><![CDATA[佐川 夫美雄]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Progressive Web Apps]]></category>
		<category><![CDATA[SPA]]></category>
		<category><![CDATA[Web Components]]></category>
		<category><![CDATA[de:code]]></category>

		<guid isPermaLink="false">/?p=19092</guid>
		<description><![CDATA[連載： de:code 2016 特集 (3)この記事は、「de:code2016」のセッションレポート、日本マイクロソフトエバンジェリスト物江修氏による「モダンWeb:たった今と、ほんの少し未来のはなし」です。講演内容...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/ms-decode2016/" class="series-371" title="de:code 2016 特集" data-wpel-link="internal">de:code 2016 特集</a> (3)</div><p>この記事は、「<a href="https://www.microsoft.com/ja-jp/events/decode/2016/default.aspx" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">de:code2016</a>」のセッションレポート、日本マイクロソフトエバンジェリスト物江修氏による「モダンWeb:たった今と、ほんの少し未来のはなし」です。講演内容を再現していますが、ニュアンス等伝えきれない場合があるかもしれません。ご了承ください。</p>

<h1>モダンWebとは</h1>

<p>昨今、様々なところで「モダンWeb」という言葉を聞くが、その定義は曖昧で意味するところの範囲が広範囲に及んでいるためではないかと考える。多くの場合、「モダンWeb」という文脈で語られている内容は次の４つの事柄で語られている。</p>

<ul>
<li>モダンなWebシステム</li>
<li>モダンな開発手法</li>
<li>モダンな標準機能</li>
<li>モダンなアプリケーション</li>
</ul>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/05/DSC03848.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/05/DSC03848-640x480.jpg" alt="DSC03848" width="640" height="480" class="alignnone size-large wp-image-19104" srcset="/wp-content/uploads/2016/05/DSC03848.jpg 640w, /wp-content/uploads/2016/05/DSC03848-300x225.jpg 300w, /wp-content/uploads/2016/05/DSC03848-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>単にモダンWebアプリケーションと言った場合にはこれらいろいろな意味に捉えることが多いが、このように四つに分けることができる。このセッションでは、アプリケーションを開発するのに必要な「モダンなWeb標準の機能」、「モダンなWebアプリケーション」に関して触れる。</p>

<h1>なぜ「モダンWeb」が話題になっているのか</h1>

<p>第一に挙げられることは「時代の要求」。具体的には以下の3つが挙げられる。</p>

<ul>
<li>Web技術の進化</li>
<li>コンテンツのリッチ化</li>
<li>クライアントの多様化</li>
</ul>

<p>Web技術で作るリッチなUIは昔から存在していたが、以前はFlashなどのプラグインを利用したいわゆるRIA(Rich Internet Applications)のほうが優勢だった。その後、Ajaxでデータを取得し、そのデータを使って部分的なUIの更新が可能になり、jQuery UIなどのUIライブラリによる開発生産性の向上、そしてHTML5の登場によって、プラグインで行っていたことがWebの標準技術だけで作ることが可能になった。これがWeb技術の進化である。</p>

<p>そしてスマートフォンから始まったFlashの衰退が進み、今までFlashで行っていたような要求をWebコンテンツ側にやってくるようになり、コンテンツのリッチ化が始まった。</p>

<p>スマートフォンを始め、PCブラウザー以外の様々なものがインターネットに繋がり、クライアントが多様化した。</p>

<p>この「クライアントの多様化」はサーバーサイドの形態にも影響を与え、その影響が、Webブラウザー上で動くアプリケーションにも影響を与えたという状況になっている。具体的にどういうことなのか。</p>

<p>黎明期のWebアプリケーションは、リクエストされたページを単純にレスポンスするというもの。ちなみに一番最初のWebサーバーはティム・バーナーズ・リーが作った「CERN Httpd」で、1991年にニュースグループで公開されたが、翌年に作られた「NCSA Httpd」ではCGIがサポートされ、動的ページが作れるようになった。ご存知の通り、このサーバーサイドで処理をして、処理結果をページで返すWebアプリケーションは広く使われている。</p>

<p>さらに、新しいクライアントとして携帯電話が現れる。NTT Docomoから始まった携帯電話は、それまでWebのクライアントというと、PCブラウザかゲーム機くらいで、いずれも机に座って使うようなものだった。</p>

<p>しかし、携帯電話は持ち歩き、行動に必要な情報を得るためのツールとして機能するモビリティという考え方が生まれた。</p>

<p>今までとは利用用途が異なる、サーバーではデバイスに応じた専用のコンテンツを作る必要があるなどコンテンツを作っていくには困難な状況だった。</p>

<p>やがて、スマートフォンに代表されるスマートデバイスが現れます。これらは、PCブラウザー用のコンテンツを同じ様に処理することができたので、わざわざ専用のコンテンツを用意しなくても済む。問題は、画面サイズに応じて表示を切り替える必要があり、同時期に出てきたHTML5関連技術であるCSS3を使ったレスポンシブWebデザインで、こうした技術を吸収することができた。</p>

<p>さらにスマートフォンは、サーバーサイドの処理にさらに大きな変化をもたらした。</p>

<p>Webアプリケーションの登場です。サーバにリクエストを投げるが、必要とするのはページではなくデータでした。この影響を受け、Webサーバーに必要な技術は、データを返す「API」が重要になった。</p>

<p>現在では、クライアントデバイスの性能とWebブラウザーの機能も数段上がり、処理性能ではネイティブで作られたアプリケーションと同等なことができるようになった。</p>

<h1>SPA(Single-page Application)</h1>

<p>単一ページによるWebアプリケーションであるSPAの特徴は、以下が挙げられる。</p>

<ul>
<li>画面遷移はDOM操作</li>
<li>ページのリフレッシュは不要</li>
<li>リッチなエクスペリエンス</li>
</ul>

<p>SPAにするメリットもいくつかある。例えば、サーバーサイドを「サービス化」することによって、多様化していくクライアントにも対応できるようになる。つまり、サービスをどこにでも提供できポータビリティを上げることができる。</p>

<p>現在のようにクライアント技術の進化が劇的に早い（言い換えると、陳腐化する速度も早い）状況下でもSPAは有効だ。クライアントとサーバーのロジックを物理的に別けることで保守性を上げることができるから。さらに分業においては、サーバーサイドを開発する人間、クライアントサイドを開発する人間で、やるべきことに集中できるということが挙げられる。</p>

<h1>プログラミングスタイルの変化</h1>

<p>SPAの登場によつてプログラミングのスタイルも少なからず変化している。Ajaxなどの非同期処理を行う場合、処理の単位はサーバーサイドの動作と必ずしも一致せず、処理の順番やタイミングもまちまちになる。それらを適切にハンドリングして画面に描画する必要がある。</p>

<p>さらに、ユーザーアクションの開始が、いわゆるPull型（サーバにリクエストするという意味で）だったが、WebRTCやWebSocketsの登場にによって、突発的に開始されるPush型（サーバからクライアントに通知する）可能性もある。</p>

<p>非同期処理の完了であるが JavaScriptではイベント通知で行われる。また、今まではサーバーロジックで行われていた処理をクライアントで行うケースも出てくるので、1つの完結する処理を行う場合、複数回サーバーとやり取りする必要がある。よく「コールバック地獄」ということに陥る。</p>

<p>不規則に発生するイベントを適切にルーティングしつつ、状態を把握し、かつ処理全体を制御する仕組みが必要で、こういった制御を行うために、JavaScriptのライブラリやフレームワークが様々な機能を実装し提供している。</p>

<p>そして、最新のモダンブラウザーがサポートしつつあるECMA Script2015や2016にも、こうした機能が標準で用意されようとしている。つまりイベントのフロー制御方法は</p>

<ul>
<li>Promise(ES2015)</li>
<li>async/await(ES2016)</li>
<li>Generator/yield(ES2015)</li>
</ul>

<p>Promiseは非同期処理を抽象化したオブジェクトでPromiseパターンで非同期処理を行う。async/awaitは、Promise とGeneratorの糖衣構文で、そのGenerator/yieldは、反復子 (イテレータ )の生成元で、実行環境を維持したま中断・再開が可能となる。</p>

<p>SPAでは画面のレンダリングも従来のサーバーサイドの処理をメインしたものとは異なる。</p>

<p>SPA以前のサーバーサイドでページが生成されるタイプのWebアプリケーションでは、画面データの成形もサーバーサイドで行われていましたが、SPAではその部分をクライアントサイドで行うことになる。</p>

<p>素直に書くなら、エレメント一つひとつのインスタンスを取得して、各々データをセットする所謂「Glue code」を書く（&#8221;グルー&#8221;とは糊のこと）ことになる。だが、これだとエレメント変更に関わるUI仕様があるたびにコードまで修正する必要がありメンテナンスが大変だし、いちいちデータを入れるためだけのコードを書くということ自体が非効率。</p>

<h2>データバインディング</h2>

<p>そこで出てきたのがUIへのデータバインドです。
マークアップにUIとデータの関係を記述しておくと、JavaScriptフレームワークがよしなにデータをセットしてくれるという仕組みです。
こうすることで、データと画面、いわゆる ModelとViewの関係を1:1に紐づけ、構造的には明確に分け部品化することが可能になった。</p>

<p>&#8220;バインド&#8221;とあるように、ModelとViewの関係を保持します。つまり、モデルもしくはビューに変更が発生した場合、その変更が一方向、あるいは双方向に反映されます。Modelの変更のみかViewに反映されるのが1Wayバインドで、双方向に変更が伝わるのが2Wayバインドです。</p>

<p>まとめるとモダンなWebアプリケーションとは</p>

<ul>
<li>SPA</li>
<li>リアクティブな動作</li>
<li>M-V-Whatever</li>
</ul>

<h1>少し先のWebアプリケーションの技術的コンセプト</h1>

<p>ここからは、ここ数年提唱されているWebアプリケーションの技術的コンセプトについて紹介します。</p>

<ul>
<li>Web Components</li>
<li>Progressive Web Apps</li>
<li>WebAssembly</li>
</ul>

<h2>Web Components</h2>

<p>まずは「Web Components」です。これはWebをコンポーネント化する仕組みで、2013年のGoogle I/Oで紹介された。実は、Webをコンポーネント化するという仕組みは、これが最初ではなく、マイクロソフトも1998年にHTMLコンポーネントというものを提案したし、Mozillaも2001年にXBLと2007年にXBL2というのを提案した。</p>

<p>このコンポーネント化のメリット、目的について</p>

<p>Webのアプリケーションは、他のソフトウェア・アプリケーションと同様に複雑になり、今ではリリース製品の開発に大勢が協力して取り組むことは珍しくなくなった。少しでも効率化を図るには、関係者やシステム間の重複が最小限になるように開発作業を分割する正しい方法を見つけることが重要になる。そのための方法としてコンポーネント化がある。複雑なシステムでも、機能を分割していけば、単純化することができる。全体をある程度の機能単位に分割する、つまりはコンポーネント化だ。</p>

<p>Web Componentsの目標は、HTML、CSS、JavaScriptの関連グループを分離し、単一ページのコンテキスト “内” で共通関数を実行することで、複雑さを軽減することだ。</p>

<p>この Web Components は、複数の API を組み合わせるか、それ単独を使用して実現する。
しかし、すべての Web ブラウザーがその API をサポートしているわけではないので、Polyfill 用のライブラリーが用意されています。</p>

<p>そしてこちらがWeb Componentsを構成する要素です。</p>

<ul>
<li>HTML Templates</li>
<li>Shadow DOM</li>
<li>Custom Elements</li>
<li>HTML Imports</li>
</ul>

<p>現在のサポートの状況はこのようになっています。</p>

<table>
<thead>
<tr>
  <th>Web Components</th>
  <th>Edge 13</th>
  <th>Chrome 50</th>
  <th>Firefox 45</th>
  <th>Safari 9.1</th>
</tr>
</thead>
<tbody>
<tr>
  <td>HTML Templates</td>
  <td>○</td>
  <td>○</td>
  <td>○</td>
  <td>×</td>
</tr>
<tr>
  <td>Shadow DOM</td>
  <td>× Medium</td>
  <td>○</td>
  <td>△※</td>
  <td>×</td>
</tr>
<tr>
  <td>Custom Elements</td>
  <td>× High</td>
  <td>○</td>
  <td>△※</td>
  <td>×</td>
</tr>
<tr>
  <td>HTML Imports</td>
  <td>× Low</td>
  <td>○</td>
  <td>△※</td>
  <td>×</td>
</tr>
</tbody>
</table>

<p>※ 既定では動作しない</p>

<h2>Progressive Web Apps</h2>

<p>これはモバイル Web アプリ向けのコンセプトで、具体的には、高性能のモバイルWebブラウザー向けにネイティブアプリケーションのようなUXを提供しようというも。去年の「Chrome Dev Summit」のキーノートで発表され話題になったものだ。今年の４月に行われた「Google Developers Summit Tokyo 2016」でも2日のテーマになっていたくらい力を入れている。</p>

<p>Progressive Web Appsに求められる体験をまとめると次の様なもの</p>

<ul>
<li>ネイティブアプリケーションのようなUX

<ul>
<li>オフラインサポート: Service Worker</li>
<li>プッシュ通知: Web Notifications/Push API</li>
<li>ホームスクリーンにアイコンの追加: Web App Manifest</li>
<li>バックグラウンド: Service Worker</li>
<li>高速でなめらかなインターフェース: CSS3 Animation</li>
</ul></li>
</ul>

<p>Service Workerは、JavaScriptで実装されているローカルのプロキシ、あるいはApplication Cacheの改良版として利用できる。
いままで Web ブラウザーからサーバーにコンテンツをリクエストする場合、サーバーになげてそれを返していたのが、その間にカスタマイズ可能な Service Worker というのが入って
バックグラウンドで動いているので、タブを閉じてもブラウザを終了しても動作しているので、プッシュ通知もうけとれるとこと。httpsでしか動作しない。</p>

<p>Progressive Web Appsを実現する技術のサポート状況は</p>

<table>
<thead>
<tr>
  <th>Edge</th>
  <th>Chrome</th>
  <th>Firefox</th>
  <th>Safari</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Internal build</td>
  <td>Canary 51.0.2677.0</td>
  <td>Nightly</td>
  <td>&#8211;</td>
</tr>
</tbody>
</table>

<h3>WebAssenbly</h3>

<p>WebAssenblyは、コンパイル済みのバイナリをWebブラウザ上で直接動作させる仕組で、Microsoft、Google、Mozilla、Webkitプロジェクトのメンバーで共同開発されていて足並みが揃っている。</p>

<p>JavaScriptよりもポータブルでロード時間や実行に対するパフォーマンスに優れたアプリケーションを作ることが可能だ。asm.jsの次のステップとしている。</p>

<p>2016/3/14〜16の間にMicrosoft、Google、Mozillaの3社が3Dゲーム<a href="http://webassembly.github.io/demo/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Angry bot</a>での検証結果を各ブログで公開している。</p>

<p>WebAssemblyの実装状況は</p>

<table>
<thead>
<tr>
  <th>WebAssembly</th>
  <th>Edge 13</th>
  <th>Chrome 50</th>
  <th>Firefox 45</th>
  <th>Safari 9.1</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Service Workers</td>
  <td>× High</td>
  <td>○</td>
  <td>○</td>
  <td>×</td>
</tr>
<tr>
  <td>Fatch API</td>
  <td>△ Preview</td>
  <td>○</td>
  <td>○</td>
  <td>×</td>
</tr>
<tr>
  <td>Web Notifications</td>
  <td>△ Preview</td>
  <td>○</td>
  <td>○</td>
  <td>×</td>
</tr>
<tr>
  <td>Push API</td>
  <td>× High</td>
  <td>○</td>
  <td>○</td>
  <td>×</td>
</tr>
<tr>
  <td>Web Application Manifest</td>
  <td>検討中</td>
  <td>○</td>
  <td>○</td>
  <td>×</td>
</tr>
</tbody>
</table>

<h2>ハイブリッドアプリケーションとしての利用</h2>

<p>Webアプリケーションが苦手とするところは</p>

<ul>
<li>ストアのエコシステムを利用しない</li>
<li>Webブラウザからはどうしてもアクセスできないハードウェアリソース</li>
</ul>

<p>そしてこれらの Web アプリケーションのは、ハイブリットアプリとしてパッケージすることにより、ターゲットとなるプラットフォームのリソースや、ブラウザーからはアクセスできないハードウェアの機能を使用できるようになる。
また、アプリストアのエコシステムを利用することができる。</p>

<h2>Webフロントエンドの開発リソース</h2>

<p>インタラクティブなコンテンツを作ることができるようになったので、開発は非常に大変なものになった。</p>

<ul>
<li>JavaScript

<ul>
<li>ライブラリ</li>
<li>フレームワーク</li>
<li>エンジンテンプレート</li>
<li>altJS</li>
</ul></li>
<li>CSS

<ul>
<li>フレームワーク</li>
<li>プリプロセッサー</li>
</ul></li>
<li>HTML

<ul>
<li>軽量マークアップ</li>
</ul></li>
<li>パッケージマネージャ</li>
<li>タスクランナー</li>
<li>モジュール管理</li>
</ul>

<p>Richになったことで多くのライブラリが提供された結果「Chaos」になったのか？と思いがち。そして、ライブラリ/フレームワークの選定として考える必要がある。</p>

<ul>
<li>ブラウザサポート</li>
<li>ベンダーサポート</li>
<li>情報

<ul>
<li>ドキュメント</li>
<li>書籍類</li>
</ul></li>
<li>学習コスト</li>
<li>開発生産性</li>
<li>機能範囲</li>
<li>ロックイン</li>
<li>運用コスト</li>
</ul>

<p>特にこの中のロックインですが、ロックインは決して悪いものではなく、優秀なベンダーと一緒になってやっていくこと、コミュニティの力を借りることでむしろ良い状況も作れる。運用コストに関しては、便利なんだけどお金がかかるというものについては考えもの。</p>

<h2>標準技術は不変</h2>

<p>結局、Webブラウザで動作するのは、HTML、CSS、JavaScriptであり、ブラウザがサポートしていない機能は動かない。技術はあくまでも「手段」でり、そうした技術に対する勉強は大事だが、手段であって目的ではない。目的は、ユーザに対して良いプロダクトを提供すること。たとえば、YouTubeはFlashで作られていたが、HTML5に変わったことに気づいた人はいない、そういうものが良い。</p>

<p>そして、WebはApplicationのプラットフォームになる。どんどん低レベルなAPIを実装することになる。結果、デスクトップと同じ様なアプリケーションを作っていける。こうした変貌は「変化」ではなく「拡張」である。</p>
]]></content:encoded>
		
		<series:name><![CDATA[de:code 2016 特集]]></series:name>
	</item>
	</channel>
</rss>
