<?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>PWA &#8211; HTML5Experts.jp</title>
	<atom:link href="/tag/pwa/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>メルカリのフロントエンドチームが、どんな開発体制で技術選定しているのか聞いてきた！</title>
		<link>/miyuki-baba/25378/</link>
		<pubDate>Thu, 28 Jun 2018 02:00:09 +0000</pubDate>
		<dc:creator><![CDATA[馬場 美由紀]]></dc:creator>
				<category><![CDATA[システム開発]]></category>
		<category><![CDATA[サイト制作]]></category>
		<category><![CDATA[PWA]]></category>
		<category><![CDATA[ReactNative]]></category>
		<category><![CDATA[WebView]]></category>
		<category><![CDATA[フロントエンド]]></category>
		<category><![CDATA[メルカリ]]></category>

		<guid isPermaLink="false">/?p=25378</guid>
		<description><![CDATA[日米通算1億ダウンロードで日本最大フリマアプリ「メルカリ」。今回はメルカリの小嶋仁司さん、坂本結衣さんにメルカリのフロントエンドエンジニアたちがどんな技術や体制で開発しているのか、HTML5 Experts.jp白石俊平...]]></description>
				<content:encoded><![CDATA[<p>日米通算1億ダウンロードで日本最大フリマアプリ「メルカリ」。今回はメルカリの小嶋仁司さん、坂本結衣さんにメルカリのフロントエンドエンジニアたちがどんな技術や体制で開発しているのか、HTML5 Experts.jp白石俊平編集長が直撃インタビューしてきました！</p>

<p><img src="/wp-content/uploads/2018/05/DSC00519-03.jpg" alt="" width="640" height="411" class="alignnone size-full wp-image-25623" srcset="/wp-content/uploads/2018/05/DSC00519-03.jpg 640w, /wp-content/uploads/2018/05/DSC00519-03-300x193.jpg 300w, /wp-content/uploads/2018/05/DSC00519-03-207x133.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>メルカリで重要な役割を果たしているWebView</h2>

<p><strong>白石</strong>：お二人は、メルカリでどんなお仕事をされているんですか？</p>

<p><strong>小嶋</strong>：私は2015年10月に入社して、アプリケーション内のWebViewページの開発を担当してきました。具体的には大規模なトラフィックがある取引画面や、配送サービス「メルカリ便」に新たな運送会社を追加したり、「大型らくらくメルカリ便」の配送機能を拡大したり、集荷サービスなどの開発も行いました。</p>

<p><strong>白石</strong>：ビジネス的に重要な部分を作っていらしたんですね。</p>

<p><strong>小嶋</strong>：技術としてはいわゆるHTML5、CSS3、JavaScriptを使ったフロントエンドで、WebView内からお客様の取引状況に合わせて、Web画面を出す部分を担当してきました。最近はメルカリのJP Web版（日本向けWebサイト）の開発を進めています。機能開発というよりは流入施策ですね。</p>

<p><img src="/wp-content/uploads/2018/05/DSC00469.jpg" alt="" width="640" height="427" class="alignnone size-full wp-image-25641" srcset="/wp-content/uploads/2018/05/DSC00469.jpg 640w, /wp-content/uploads/2018/05/DSC00469-300x200.jpg 300w, /wp-content/uploads/2018/05/DSC00469-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /><br><span style="font-size: 80%;">▲<strong>株式会社メルカリ エンジニアリングマネージャー 小嶋 仁司氏</strong><br>メルカリ エンジニアリングマネージャー / Frontend。大手Webメディアで働いた後、Flash の表現力に感嘆しフリーランスで Flash Developerとして働く。その後、Flashの衰退とともにHTML/JS/CSSにスイッチし、ゲームの受託開発などを行う。2015年にメルカリに入社。Web/WebView開発に従事。今はPWAに興味津々。</span></p>

<p><strong>坂本</strong>：エンジニアの坂本です。Engineering Operations Teamというチームで、エンジニア全体の組織作りや制度、採用にコミットしています。現在3名（取材当時）いますが、全員エンジニアです。私は特に中途エンジニアの採用や技術広報、そして技術ブランディングを担当しています。もともとサーバーサイドエンジニアで、2014年に入社して去年の12月まではプロダクトに関わっていました。</p>

<p><img src="/wp-content/uploads/2018/05/DSC00511.jpg" alt="" width="640" height="413" class="alignnone size-full wp-image-25647" srcset="/wp-content/uploads/2018/05/DSC00511.jpg 640w, /wp-content/uploads/2018/05/DSC00511-300x194.jpg 300w, /wp-content/uploads/2018/05/DSC00511-207x134.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /><br><span style="font-size: 80%;">▲<strong>株式会社メルカリ Engineering Operations Team　ソフトウェアエンジニア 坂本結衣さん</strong><br>大学卒業後、流通業で営業職や店舗運営を経験し、Web制作会社に転職。PHPを用いたシステムの実装から、要件定義や設計、またDevOpsによる環境構築、Jenkinsサーバー構築等の開発基盤の構築・管理等を担当。2014年にメルカリに入社。Engineer Operation Teamという、エンジニア組織作り・採用・制度・技術ブランディングを行う部署のメンバーとして活躍中。</p>

<p><strong>白石</strong>：メルカリはWebViewをかなり使っているんですか？</p>

<p><strong>小嶋</strong>：最近はReactNativeを使ったりしているので、WebView自体は減っている傾向にあります。ただし、ReactNativeもJavaScriptで書くのでフロントエンドの領域だと思っています。WebViewとして特にコアな機能は取引画面ですね。</p>

<p><strong>白石</strong>：なるほど。ということは、重要な画面はこれまでWebViewで作ってきたんですね。</p>

<p><strong>小嶋</strong>：そうですね。当時からするとホットデプロイできる強みや、Webの技術でデプロイして、クイックに画面が切り替えられるという理由でWebViewが選定されたんだと思います。</p>

<p><strong>白石</strong>：それはサーバーサイドに画面を更新すれば反映されるということですか？</p>

<p><strong>小嶋</strong>：はい。更新性という意味合いでは大分速くなってきたんですけど、ネイティブはどうしてもiOSで申請があったり、ネイティブのアップデートがあるので…。例えば取引画面で使用している外部の配送サービスが急に一時期使えなくなったときに、ネイティブで何ができるかというとメンテナンスと出すしかなく、お客様はアップデートを待つしかありません。それであれば、Web上だけでクイックに開発できる方が良いという選択だったと思います。例えば、招待ページはWebViewで作られていましたね。</p>

<p>WebViewの全体量としては減っていますが、Web文脈でいうと注目度はかなり高まっています。例えばPWAとか。技術選定の根底にあるのは、お客様の体験だと思っているので、その時その時の状況に適した技術選定ができていればいいと思っています。WebViewをなくしていこうとか、PWA（Progressive Web Apps）だけにしていこうとかではなく、その都度リーチできるものを選べばいいかなと。</p>

<p><strong>白石</strong>：パフォーマンスの速さとユーザー体験を重視しているわけですね。</p>

<p><strong>小嶋</strong>：会社全体としてもテックカンパニーという点を重視しているので、いち早く最新技術を取り入れるという目的もあると思います。</p>

<p><img src="/wp-content/uploads/2018/05/DSC00493.jpg" alt="" width="640" height="403" class="alignnone size-full wp-image-25663" srcset="/wp-content/uploads/2018/05/DSC00493.jpg 640w, /wp-content/uploads/2018/05/DSC00493-300x189.jpg 300w, /wp-content/uploads/2018/05/DSC00493-207x130.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>開発速度を優先すべく、コードベースをリージョンで分割</h2>

<p><strong>白石</strong>：小嶋さんご自身は、ReactNativeの開発をしているんですか？</p>

<p><strong>小嶋</strong>：僕自身は以前はUSプロダクトもやっていましたが、現在はJPプロダクトの担当なので、ReactNativeのプロダクト導入経験はないです。</p>

<p><strong>白石</strong>：ちなみに、USプロダクトということは、JPプロダクトとは別にアプリを作っているんですか？</p>

<p><strong>小嶋</strong>：はい。コードベースの話をすると、去年の秋くらいに現地での開発速度を優先するという目的で、JPとUSとUKのAPI含め、リージョンを分割したんですね。というのも、日本で開発した機能で、一部USで表示がどうしてもおかしくなってしまうこともありました。そういうことを懸念して、現地のことは現地でオーナーシップを持って開発・運営することにして、分割した経緯があります。</p>

<p><strong>白石</strong>：Googleは全世界で一つのコードベースだと言ってますが、御社は分割したほうがいいと判断されているというのは、興味深いですね。</p>

<p><strong>小嶋</strong>：ステークホルダーが同じリージョンにないということは、タイムゾーン分だけコストがかかります。例えばUSである機能をさくっと1日で開発してリリースしたいときも、JPに影響がないかを見るためにはQAなど複雑なリレーションが発生します。なので、現地でやっていることは現地のルールを優先しています。</p>

<p><strong>坂本</strong>：メルカリは会社のミッションとしても、「世界的なマーケットプレイスを創る」ことを目標としています。最終的に世界中でメルカリを使ってもらいたい。ですが、まずは世界を獲りにいくことが最優先。そのために一番いい選択肢は何かと考えたときにリージョンごとに分けるほうが最適だと判断をしました。</p>

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

<p><strong>小嶋</strong>：全リージョンで、完全に共通のコードベースを持つことは大切なんですけど、必ずしも日本のUIが全世界で最適だとは限らない面もあります。民族性や国土の広さなど、様々な違いがあるし、前提として物を売ったり買ったりするマインドの違いもある。そのときに共通のUIベースで勝負するのは難しいという課題もありますね。</p>

<p><strong>白石</strong>：とはいえ、決断にはかなりの覚悟が必要だったんじゃないかと思います。そんなことないですか？</p>

<p><strong>坂本</strong>：メルカリのバリューの一つに「Go Bold（大胆にやろう）」があります。経営陣も迷ったと思いますが、かなりスピーディに進めていたと思います。</p>

<p><strong>白石</strong>：ちなみに、最近GoogleがWeb PaymentsやShippingの機能をブラウザで共有のUIを提供するらしいという話を聞いたのですが、メルカリさんはどう考えますか？</p>

<p><strong>小嶋</strong>：Google Paymentsはかなり親和性はあるんじゃないかと思ってます。Webの可能性という話になるんですけど、決済に関して標準化されたものがあるなら、使っていきたい気持ちはあります。もちろんお客様にとって便利になるかどうかを検討してからになりますが、特にPWAやWebベースでのプラットフォーム化が加速していったときに十分可能性がありますね。</p>

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

<p><strong>白石</strong>：個人的にもPWAにはご興味があるとのことでしたけど、社内ではどうPWAを活用していきたいですか？</p>

<p><strong>小嶋</strong>：去年もサンフランシスコで開催された「Chrome Dev Summit」というカンファレンスに参加させてもらったのですが、現地ではトラフィックに弱いインドなどではかなり可能性があると発表されていました。話を戻すとお客様にとっての体験向上という意味で、正しいプラットフォームは何なのかを考えながら、特に細かくどんどん変わっていくべきだと考えています。</p>

<p>僕の個人的な意見ですが、例えば会社がビジネスを選定するときは、端末の保有台数や通信インフラの整備の高さなどを含めて海外進出を考えていくと思うんです。いわゆるネイティブライクな体験がWebベースでもできるように担保されるのであれば、Push Notificationなどもありなんじゃないかと。PWAを一番最初に導入してユーザー数を3倍に増やしたインドのFlipkartのように、インドという巨大な人口を有する国でも戦えるんじゃないかと期待しています。</p>

<p><strong>白石</strong>：PWAをやるときはWebViewでやってたコードがまた使えるようになるんですか？</p>

<p><strong>小嶋</strong>：それでいうと、PWAのアーキテクチャにも最適解がかなりあって。例えばService Workerのオフラインキャッシュ、ヘッダー部分とかグローバルナビ部分などはきっちりコンテンツ部分とは分けるべきだと思います。</p>

<p>App Shellモデルの概念もあるし、既存のWebで培われているコードべースができるとは思っていないのと、メルカリの課題としてリプレイスとかもあると思っているので、新しいものは新しく作りたいですね。</p>

<h2>メルカリの開発体制や、サービスのリプレイスは？</h2>

<p><strong>白石</strong>：続いては、メルカリの開発体制や、サービスのリプレイスをどう進めていくのかなどについて聞かせてください。</p>

<p><strong>小嶋</strong>：フロントエンドの文脈で言うと、一部リプレイスの必要があって、常に現場から上げるようにしています。今進んでいるプロジェクトとバランスを持って進められるように意識しています。</p>

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

<p><strong>白石</strong>：それはメルカリJP Webの話ですか？</p>

<p><strong>小嶋</strong>：そこもやりたいのですが、もっと優先度が高いところもあります。なぜ今そこをやるのかというのを説明した上でやるようにしています。Webだけではないかなと思っています。</p>

<p><strong>白石</strong>：御社でいうフロントエンドというのは、もうWebに限らない？</p>

<p><strong>小嶋</strong>：そうですね。フロントエンドはアプリのWebViewの開発をしている人もいるし、Webの開発をしている人もいるし、USはJavaScriptエンジニアが開発しています。Node.jsなども使われています。領域は広がっています。</p>

<p><strong>白石</strong>：小嶋さんがフロントエンドだからあまり話に出てこないのかもしれないのですが、思いっきりネイティブで書かれているところも結構あるんですか？</p>

<p><strong>小嶋</strong>：かなりあります。うちは優秀なiOSエンジニア、Androidエンジニアが相当数いるので、ロイヤルティ高くお客様の体験向上のために寄与しています。フロントエンドは現状では更新性の高いところを担当していますね。</p>

<p><strong>白石</strong>：さらにメルカリの開発の裏側を知りたいと思うんですが、クラウドやデータベースの話から聞かせてもらってもいいでしょうか。</p>

<p><strong>坂本</strong>：サーバーサイドはいろいろな会社のサービスを使っていますね。日本のサーバーサイドがメインで動いているのは、さくらの専用サーバーですし、USではAWSを使っていたり、現在では裏側のドメインごとによるマイクロサービス化の流れがあります。</p>

<p><img src="/wp-content/uploads/2018/05/DSC00483.jpg" alt="" width="640" height="421" class="alignnone size-full wp-image-25676" srcset="/wp-content/uploads/2018/05/DSC00483.jpg 640w, /wp-content/uploads/2018/05/DSC00483-300x197.jpg 300w, /wp-content/uploads/2018/05/DSC00483-207x136.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><strong>白石</strong>：サーバ―サイドは何を使っているんですか？</p>

<p><strong>坂本</strong>：サーバ―サイドで最初からコードべースで一番使っているのは、PHPです。</p>

<p><strong>白石</strong>：それ以外の言語も増えているということでしょうか。</p>

<p><strong>坂本</strong>：マイクロサービスの文脈の中で基本的にインターフェイスが定義されていれば、中身はなんでもOKです。その中でもいろいろな利点からGoを使っているケースが多いです。</p>

<h2>チーム体制は3カ月ごとに適したチームを模索</h2>

<p><strong>白石</strong>：続いては、チーム作りや開発体制について聞いていこうと思います。先ほどフロントエンドの定義についてお聞きしましたけど、大まかにいうとフロントエンド、iOS、Android、サーバーサイドエンジニアというかんじなんですか？</p>

<p><strong>小嶋</strong>：開発体制でいうと、さらにプロダクトマネージャーとデザイナーが入ってきます。いわゆるチームプロダクトという大きなくくりで、プロダクトを推進するためのチームになっています。チーム体制についてはクォーター（四半期）制という3カ月ごとに適したチームを模索しています。</p>

<p>僕の経験でいうと、かなりフレキシブルに動いていて、プロジェクトにプロダクトマネージャー、エンジニア、デザイナーと就くこともあれば、僕はJPフロントエンドという横ぐしのチームで動いています。その時にどういうチームが最適なんだろうと結構模索された上でチームを構成します。3カ月後に同じチームがあるとも限らないし、まったく違うチームでやる人もいるし、ずっと同じチームでやる人もいます。</p>

<p><strong>白石</strong>：3カ月ごとに編成されるというのは、大分スピーディですね。ちなみにどう開発しているか、どう開発を進めているかもお聞きしたです。相当UXにはこだわっていると思いますが、事前の調査やテスト、それをどうフィードバックして、どう開発やデザインに反映しているんでしょうか。</p>

<p><strong>小嶋</strong>：UXに関しては1年前くらいからユーザービリティテストをかなり活発にやっています。お客様に使ってもらって、ご意見を聞きながら、UI/UXの改善しています。あとはABテスト基盤があるので、プロダクトマネージャーが数値をもとに10%改善に基づいて、数値を見ながら取り組んでいます。常にPDCAが回っているかんじです。</p>

<p>ターゲットや契約している会社があるわけではなく、社員は参加も自由で公募もされています。行きたい人が行ける。全社的にプロダクト志向が高いですね。エンジニアだからプロダクトに意見を言わないという風土はないですね。</p>

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

<p><strong>白石</strong>：クォーターごとにチームが変わっていくというお話ですけど、タスク管理などはどうされているんですか？</p>

<p><strong>小嶋</strong>：タスク管理に関してはアトラシアンのJIRAを使っていて、全社的にチケット駆動開発で進んでます。情報管理はOSSのコミッターがいるんですが、CrowiというWikiを使っています。チーム移動したからツールが違うというのはないですね。プロジェクトごとに切っているチームもあります。</p>

<h2>開発速度が早いがゆえの課題</h2>

<p><strong>白石</strong>：現在の課題と自慢できること、今後やりたいことについて聞かせてください。</p>

<p><strong>小嶋</strong>：メルカリではクォーターごとにプロジェクトのゴールを設定しているので、開発速度が相当早いんです。さらに新規事業も多い。開発速度が早いとなると、エンジニアとしては、技術的負債を早く返したいと考えます。その辺のバランスを見直そうという動きも出ていますが、開発スピードの早い組織ならではの課題だと考えています。</p>

<p><strong>白石</strong>：技術的負債をどうするかという問題ですね。</p>

<p><strong>小嶋</strong>：スピードも大事ではあるのですが。</p>

<p><strong>白石</strong>：自動テストもきっちり書いているとそれだけで時間がかかったりするから、省略するところもあったりしますよね。</p>

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

<h2>CTOとVo/Eの二頭体制</h2>

<p><strong>白石</strong>：メルカリ開発チームならではの自慢できることは何ですか?</p>

<p><strong>小嶋</strong>：現場が技術選定をある程度任されているところですね。あとは月並みですけど、全社員に開発者端末が支給されるんですね。iOSを使っている人だったらAndroid端末、Androidを使っている人ならiOS端末が入社時に無償で貸与されます。パフォーマンス出せるための備品や、エンジニアが最適だと考えるソフトウェアに対してはかなり優遇されていると思います。</p>

<p><strong>坂本</strong>：メルカリは退職者が圧倒的に少ないですね。エンジニアに限らず、会社が成長を続けているので離れていく人が少ないし、
ネガティブなことを考える必要がない。プロダクトに集中できるし、今の環境をよくすることに注力できます。</p>

<p>またCTOとVP of Engineerがそれぞれ1名いて、技術的なトップと開発チームのマネジメントのトップが分かれているので、バランスがとれていると思います。CTOが開発体制に入り込んでしまうと、技術的な進歩に貢献することに時間がさけなくなってしまう恐れがありますが、そういうことがありません。</p>

<p>圧倒的に会社の技術を引っ張るという意味で、会社全体を先導しているという姿勢を見せてくれている。リアルな開発現場はVP of Engineerがコミットしてくれている体制があるので、エンジニアたちはよけいなことに時間を使わずに本質的なことにフォーカスできる環境だと思います</p>

<p><img src="/wp-content/uploads/2018/05/DSC00505.jpg" alt="" width="640" height="415" class="alignnone size-full wp-image-25681" srcset="/wp-content/uploads/2018/05/DSC00505.jpg 640w, /wp-content/uploads/2018/05/DSC00505-300x195.jpg 300w, /wp-content/uploads/2018/05/DSC00505-207x134.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><strong>白石</strong>：CTOがこうだと言っても、現場が異議を唱えることはないんですか？</p>

<p><strong>小嶋</strong>：トップダウンというより、どちらかといえば方向性を提示した上でテック寄りな人たちでデスカッションしている。距離が近いので、導入するにしてもしないにしても議論が頻繁に行われています。</p>

<p><strong>白石</strong>：現場とトップの距離が近いとのことですが、CTOとのコミュニケーションもフラットにできるということですか？</p>

<p><strong>小嶋</strong>：そうですね。かなりオープンな文化なので、CTOと1on1したいときも自由に設定できます。「必ずマネージャーを通すように」などの文化はないです。それから、メルカリでは3カ月に一回、Be Professional Dayという、普段はできないことをやろうという取り組みがあり、誰が何を開発してもいいことになっています。</p>

<p>前回はオートメーションというテーマを設けて箱根で開発合宿をしたのですが、CTOも来てくれて、いろいろアドバイスしてくれました。関係性としてはフラットなのかなって思います。</p>

<p><strong>白石</strong>：エンジニアにとってはいい開発環境とチーム体制ですね。これからのメルカリにも期待しています！今日はいろいろ面白い話をありがとうございました。</p>

<p><img src="/wp-content/uploads/2018/05/DSC00523.jpg" alt="" width="640" height="425" class="alignnone size-full wp-image-25639" srcset="/wp-content/uploads/2018/05/DSC00523.jpg 640w, /wp-content/uploads/2018/05/DSC00523-300x199.jpg 300w, /wp-content/uploads/2018/05/DSC00523-207x137.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /><br><span style="font-size: 80%;">▲<strong>メルカリのバリュー「Go Bold」グッズがたくさん！</strong></span></p>
]]></content:encoded>
			</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>Webの過去から現在・未来まで！エバンジェリストたちが語る、最先端Web技術の世界</title>
		<link>/yoshikawa_t/25150/</link>
		<pubDate>Fri, 16 Mar 2018 01:00:13 +0000</pubDate>
		<dc:creator><![CDATA[吉川 徹]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[PWA]]></category>
		<category><![CDATA[Web Authentication]]></category>
		<category><![CDATA[Web Payments]]></category>
		<category><![CDATA[Web Share API]]></category>
		<category><![CDATA[WebAssembly]]></category>
		<category><![CDATA[WebVR]]></category>
		<category><![CDATA[WebXR]]></category>

		<guid isPermaLink="false">/?p=25150</guid>
		<description><![CDATA[連載： Webの未来を語ろう 2018 (1)HTML5 Experts.jp 副編集長兼エキスパートの吉川です。昨年好評だった「Webの未来を語ろう」企画を2018年もやります！ 今回はパネルディスカッション形式で、H...]]></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> (1)</div><p>HTML5 Experts.jp 副編集長兼エキスパートの吉川です。昨年好評だった「Webの未来を語ろう」企画を2018年もやります！</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>、 Microsoftのエバンジェリスト<a href="https://html5experts.jp/osamum_ms/" data-wpel-link="internal">物江さん</a>をお迎えして、興味深いお話を多数お聞きしました。</p>

<p>会場も交えたトークは、今後のWeb業界の動向を追いかける上で、重要な内容となっているので、ぜひ読んでみてください！</p>

<p><img src="/wp-content/uploads/2018/02/IMG_5426.jpg" alt="" width="640" height="447" class="alignnone size-full wp-image-25186" srcset="/wp-content/uploads/2018/02/IMG_5426.jpg 640w, /wp-content/uploads/2018/02/IMG_5426-300x210.jpg 300w, /wp-content/uploads/2018/02/IMG_5426-207x145.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>2017年のWebで印象に残ったことは？</h2>

<p><b>白石</b>: まずは簡単な自己紹介と、2017年のWebで印象に残ったことを教えてください。</p>

<p><b>えーじ</b>: えーじです。Googleでデベロッパーアドボケイトをしています。もともとは、Google Chromeのアドボケイトという位置付けでしたが、最近はもっと広くなって、Web全体のアドボケイトを担当しています。
特にChromeだけの話に限らず、Web全般について話をしていますね。これには、我々のチームの理想として、<strong>Webすべてに貢献していこう</strong>という想いがあります。</p>

<p>2017年で印象に残ったことは、<strong>SafariがService WorkerとPayment Requestに対応すると表明したことがすごく意義深い</strong>と思っています。</p>

<p><b>物江</b>: 物江と申します。Microsoftでエバンジェリストをしています。以前はWebに軸足を置いていたんですが、現在はWebだけに限らずISV(Individual Software Vendor)、独立してサービスや製品を提供しているパートナーさん向けに様々な技術の啓発を行なっています。Webについては、個人的なものも含めていろいろ活動しています。</p>

<p>2017年に印象に残ったことは、<strong>WebAssemblyやPWA（Progressive Web Apps）などについて、ブラウザベンダーがきちんと足並みを揃えて、仕様を策定するようになった</strong>ということですね。非常にいい流れになってきていると思います。</p>

<p><img src="/wp-content/uploads/2018/02/IMG_5445.jpg" alt="" width="640" height="447" class="alignnone size-full wp-image-25188" srcset="/wp-content/uploads/2018/02/IMG_5445.jpg 640w, /wp-content/uploads/2018/02/IMG_5445-300x210.jpg 300w, /wp-content/uploads/2018/02/IMG_5445-207x145.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /><br><span style="font-size: 90%;">▲<strong>左から、日本マイクロソフト株式会社 物江修さん、Google デベロッパーアドボケイト えーじさん</strong></span></p>

<p><b>白石</b>: 皆さん、ありがとうございます。ついでに私の2017年で印象に残ったこともお話ししておくと、個人的には<a href="https://dev.to/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">dev.to</a>や日本経済新聞社の<a href="https://www.nikkei.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">日経電子版</a>が爆速だったという、そういう事例が出てきたのは印象的だったなと思います。裏側でHTML5やWebの最先端技術とか、そういったものを使って1段階上のレベルの速さを実現している。</p>

<p>Webプラットフォームベンダーやコミュニティの皆さんの啓蒙活動などもあって、PWAをはじめとしたWeb技術だとかパフォーマンスだとかが、ビジネス上も重要であるというところも浸透してきている。その結果として、Webプラットフォームの機能がフル活用されつつ、パフォーマンスというところに影響がでた良い例かなと。</p>

<p>今回は、Webの過去・現在・そして未来を語るという構成で進めてみたいと思います。</p>

<h2>イントロダクション:HTML5は世界を変えたのか？</h2>

<p><b>白石</b>: 2017年以前のWebを振り返ると、ブラウザ戦争などの分断化があって、そこからHTML5のムーブメントが起こり、Webの様々な仕様が生まれてブラウザに実装されました。</p>

<p>ただ、<strong>それら「HTML5」のムーブメントは世界を変えたんでしょうか？</strong>
これまであまり、そういう振り返りをしたことがなかったので、一度やってみたいなと思っていたんです。お二人はどうお考えですか？</p>

<p><b>物江</b>: そうですね、一般ユーザーの目からすると、確かにあまり変わっていないかもしれません。例えば、YouTubeのプレイヤーは、FlashからHTML5になりましたけど、変わったって気がつく人はあまりいませんよね。普通の人は、きっとまったく意識せずに使っている。HTML5でできたことは、とっくにFlashでもできていたわけで。</p>

<p>でも、開発者にとっては大きな変化がありましたよね。結局、開発者はみなHTML5を使っています。これはなぜかというと、HTML5がシンプルだからこそだと思うんですよ。</p>

<p>エキスパートの<a href="https://html5experts.jp/takehora/" data-wpel-link="internal">竹洞さん</a>がいいことを言っていたんですけど、Webが素晴らしく進化したのはKISSの原則(*1)のおかげといっていました。つまり、誰でも簡単に使えるからこそ普及した。わざわざFlashを使わなくても、Web標準技術だけを使えばいろんなことができるようになった。それによって作り手側の裾野が広がって、以前よりもリッチなコンテンツがたくさん出るようになってきたのかなと思います。</p>

<p>*1 … &#8220;Keep it simple, stupid&#8221; （シンプルにしておけ！この間抜け）、もしくは、&#8221;Keep it short and simple&#8221; （簡潔に単純にしておけ）という経験的な原則の略語。<a href="https://ja.wikipedia.org/wiki/KISS%E3%81%AE%E5%8E%9F%E5%89%87" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Wikipedia</a></p>

<p><img src="/wp-content/uploads/2018/02/IMG_5433.jpg" alt="" width="640" height="422" class="alignnone size-full wp-image-25189" srcset="/wp-content/uploads/2018/02/IMG_5433.jpg 640w, /wp-content/uploads/2018/02/IMG_5433-300x198.jpg 300w, /wp-content/uploads/2018/02/IMG_5433-207x136.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b>えーじ</b>: ぼくも、世界は変わったと思います。やっぱりHTML5でWebを変えようっていうムーブメントがあったこと、それ自体が良かったと思うんですよね。良い意味でのブラウザ間の競争が起きて、どんどん新しい提案がなされて、共通して使えるものがどんどん生まれていった。</p>

<p>ちゃんと数えたことないですが、HTML5の機能でみんな当たり前に使うようになったものっていっぱいあると思うんですよ。例えば、CSS3で角丸を使うっていうのももう当たり前にみんなやっているし、それが動かないブラウザはほぼ、ない。そういうものが当たり前に使えるようになったっていうのは、一昔前からすると全然状況は異なっている。そういう意味では、相当変わったと思います。</p>

<p><b>白石</b>: そういえば、元Mozilla Japanの浅井智也さんに以前教えてもらったんですが、Web関連技術を全部まとめた図があるんです。これ、曼荼羅図みたいな感じなので、「Web曼荼羅」なんて呼ばれているそうです(笑)。</p>

<p>HTML5とその関連技術（<a href="https://dynamis.github.io/webapi.link/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">webapi.link</a>）
<img src="/wp-content/uploads/2018/01/webtechnologies.jpg" alt="" width="640" height="360" class="aligncenter size-full wp-image-25159" srcset="/wp-content/uploads/2018/01/webtechnologies.jpg 640w, /wp-content/uploads/2018/01/webtechnologies-300x169.jpg 300w, /wp-content/uploads/2018/01/webtechnologies-207x116.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>こうして考えると、HTML5のムーブメントはたくさんのものを生み出しましたねえ。一般のユーザーからはあまり変わってないように見えても、「それは時間をかけて変わっているから」という面もありそうですね。</p>

<p><b>えーじ</b>: はい、そして、これだけのものがたくさん生み出された結果、Webはアプリケーションプラットフォームになった。それが、HTML5以前との大きな違いだと思いますね。</p>

<h2>Webは難しすぎる─Webプラットフォームの現状と課題</h2>

<p><b>白石</b>: では、iOSやAndroidといった他のプラットフォームとWebプラットフォームとを比較すると、Webはどういう立ち位置にあるとお考えですか？</p>

<p><b>物江</b>: Webプラットフォームは時間をかけてここまで成熟してきました。機能的な面では、他のプラットフォームにもひけをとらないというところまで来たんじゃないかと思います。</p>

<p>そして今、Progressive Web Apps (PWA)が浸透しつつあることが、今後のWebにとってはすごく意義のあることだと思っています。
<strong>PWAって、ある意味ひとつの理想の到達点だと思う</strong>んですよね。Javaなどが理想に掲げていた「Write Once, Run Anywhere」を、PWAは真の意味で実現するわけです。
これ、次のWindowsの大型アップデートでPWAがデスクトップアプリっぽく動いだり、Windowsストアからインストールできるように<a href="https://blogs.windows.com/msedgedev/2018/02/06/welcoming-progressive-web-apps-edge-windows-10/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">なる</a>から言っているわけじゃないですよ(笑)。</p>

<p><b>白石</b>: そこでいつも言われているのが、Webアプリって動作が遅いんじゃないかってことですよね。</p>

<p><img src="/wp-content/uploads/2018/02/DSC09045.jpg" alt="" width="640" height="408" class="alignnone size-full wp-image-25192" srcset="/wp-content/uploads/2018/02/DSC09045.jpg 640w, /wp-content/uploads/2018/02/DSC09045-300x191.jpg 300w, /wp-content/uploads/2018/02/DSC09045-207x132.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b>物江</b>: ただ、そうした問題についても、Webプラットフォームは長いこと取り組んでいて、もはやあまり問題にならないレベルじゃないかと思います。
ブラウザの実装という面でも、仕様の面でも、絶え間ない改善が続けられてきました。</p>

<p>仕様の面でそうした部分について期待できるのは、やはりWebAssemblyですね（筆者注: ブラウザが高速に実行可能な、ポータブルなバイナリ形式）。
昨年、モダンブラウザが同時にWebAssemblyのサポートを表明するということがありましたが、これでWebの速度はまた一段階アップすることが期待できます。</p>

<p>あとはやはりハードウェアの進歩が解決するものも多いでしょう。ちなみに、今のWeb技術の素晴らしいところは、ハードの性能に縛られた設計をしていないこと、どこでも同じWeb技術が動作することだとも思います。</p>

<p>例えば昔、貧弱だった携帯電話の機能に合わせた仕様で、HDMLやCHTMLというモバイル専門のタグがありましたが、今はもうほとんど残っていません。結局、性能に関わる問題は時間が解決してしまう部分も大きいんです。いま大切なことは、「いかに人間が作りやすいか、使いやすいか」が重要になってくるかなと思います。</p>

<p><b>えーじ</b>: ぼくも、パフォーマンス面は既にあまり課題とは考えていません。それよりぼくが課題だと感じているのは、開発者にとってのWeb技術はかなり複雑になってしまっていることです。</p>

<p>例えば「Extensible Web」というのを聞いたことがある方がいらっしゃると思います。これはWebの技術設計に対する、ここ数年における指針のようなもので、具体的には「標準としては、ユースケースを規定しない低レベル（低レイヤー）なAPIを提供する」というものです。</p>

<p>そうすることで、そうしたAPIを使用したハイレベルなライブラリだとかベストプラクティスが、開発者の手によって作られることを期待する。こうすることで、「ハイレベルだけど使われないAPI」が標準で規定されてしまうという問題を解決しようとしています。</p>

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

<p>ただ今は過渡期なので、低レベルなAPIがどんどん増え、ライブラリも量産されていて、はっきり言って混沌としています。例えばService Workerもすごく低レベルなAPIで、実際に使うとなるとなかなか難しい。</p>

<p>そこにGoogleが<a href="https://workboxjs.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Workbox</a>というライブラリを出していたりするんですが、それを使うと簡単にServiceWorkerを使える一方で、ServiceWorkerもライブラリもどちらも学ばなくてはならない。</p>

<p>これがWeb Componentsなんかだと、仕様そのものがどんどん変わっていて、なかなか安定しない。<a href="https://www.polymer-project.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer</a>というライブラリを使おうにも、Polymerも仕様に合わせてどんどん変わっている。どの時点の仕様が正しいのか、検索したときにどれが最新なのかわかりづらい。そういうところが複雑で、開発者はみな苦労してるんじゃないかなと思います。</p>

<p>個人的には、以前Webpackにやられたことがありまして(笑) 。将来的にはES Modulesが広まれば、そういうビルドプロセスを経なくてもうまく動くようになるんだと思うんですが、今は過渡期として、やっぱりGulpなりWebpackなりRollupなりを使う必要がある。</p>

<p>ビルドツールも次々に生まれるし、フレームワークもそう。フレームワークとビルドツール、様々なライブラリも組み合わせなくちゃならないし、ベストプラクティスが簡単にはわからない。その辺がかなり複雑になっているなと感じています。</p>

<h2>各ブラウザベンダーのこれからの動向は？</h2>

<p><b>白石</b>: 
皆さんご自身の会社の立場からお聞きしたいなと思うんですけど、ブラウザベンダー各社がどういう想いで、どういう方向を向いて実装しているのかをお聞かせください。</p>

<p><b>えーじ</b>: 
会社（Google）としての方向性はもちろんですが、チーム内でWebに関する課題を共有して、その解決策を探ることは普段から行っています。</p>

<p>例えば、先ほど挙がっていたパフォーマンスを例に挙げましょう。</p>

<p>実はJavaScriptのパフォーマンスって、もうあまり問題にならなくなっているんです。むしろ悪いのはレンダリングの部分で、そこを速くするための努力はずっと続けています。</p>

<p>あと、ネットワークの遅延もすごく大きい要因なので、ServiceWorkerみたいな仕様を提供することで、スピードの課題に開発者自身が取り組みやすくする。</p>

<p>さらに、パフォーマンスに関するベストプラクティスを開発者の皆さんと共有するのも重要です。</p>

<p>このように、課題一つとってもたくさんのアプローチがある。こういう活動を、チーム一丸となって同時に取り組んでいるという状態ですね。</p>

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

<p><b>白石</b>: 
なるほど。ちなみにGoogleの中で、「今のWebはこういう課題があるね」みたいな、そういう話し合いっていうのはよくされるんですか？どんな議論がされてるのか興味があります。</p>

<p><b>えーじ</b>: 
はい、常にやってますね。世界中から集ってきた情報を、雑談ベースでやり取りするような感じです。</p>

<p>例えばこれからGoogleがインドでももっと使われるようにするためには、インドの市場を考えなきゃいけない。しかしインドは全然違う世界だと。</p>

<p>例えばネットワークにしても、今われわれが4Gは当たり前に使ってますけど、向こうの世界は2Gなんです。3Gですらない。なのに、何MBっていうファイルをダウンロードしないと見れないサイトっていうのはざらにあるわけですよ。そういったネットワーク環境の悪いところに対して、開発者の皆さんがサービスを提供しようと思った時にどうするのか。そういう課題がインドに進出しようと思っているチームから上がってきたりします。</p>

<p>他には例えば最近は、アクセシビリティにもかなり力を入れていたりもしますね。アクセシビリティに強く関心のある人たちがチームに入ったことで、Webのアクセシビリティをもっと良くするための話し合いや仕様の提案なども活発に行なっています。</p>

<p><b>物江</b>: 
Microsoft Edgeは、相互運用性とセキュリティ、アクセシビリティとパフォーマンスの4つが何においても優先されています。</p>

<p>例えば相互運用性でいうと、 <code>-webkit-text-stroke</code> というベンダープリフィックスがあります。これ、以前はWebKit系のブラウザでしか動かなかったんですが、現在はEdgeでも開発中なんです。多くのサイトで使われているような機能については、全部同じように動くようにするというのを優先的にやっています。</p>

<p>アクセシビリティに関しては、画面に表示されるすべてのテキストについて、スクリーンリーダーのような外部のプログラムを呼び出せるような仕組みが、WindowsにはOSレベルで入っています。それを使って、アクセシビリティを強化するような仕組みがEdgeに入っていたりしますね。</p>

<p>パフォーマンスについては、Chakra（EdgeのJavaScriptエンジン）のパフォーマンスアップを継続的に行っています。特に、こないだのアップデートでようやくブラウザ内部のリファクタリングが終わったようで、Edgeが出た頃からのパフォーマンスでいうと、3～4倍速くなってます。</p>

<p><img src="/wp-content/uploads/2018/02/IMG_5440.jpg" alt="" width="640" height="428" class="alignnone size-full wp-image-25195" srcset="/wp-content/uploads/2018/02/IMG_5440.jpg 640w, /wp-content/uploads/2018/02/IMG_5440-300x201.jpg 300w, /wp-content/uploads/2018/02/IMG_5440-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b>白石</b>: 
リファクタリングっていうのは、Internet Explorerから引きずっているコードがかなりあるのを書き直すって話ですよね。それが行われているって話はだいぶ前に聞いていましたが、ついに終わったんですね。</p>

<p><b>物江</b>: 
はい、ほぼ全部終わったんじゃないかと。もともとEdgeのレンダリングエンジンってTrident（IEのレンダリングエンジン）から派生したものなので、20年以上前のものということで、根っこの部分で仕様が古い部分があったんですよ。その修正がようやく終わったという感じです。これから先は、Edgeの開発はどんどん加速していくんじゃないかと期待しています。</p>

<p>あとは、やはり2000年代と比較すると、ユーザーの意見をより開発に取り入れようという姿勢が顕著になったかと思います。Windowsをお使いの方はわかると思うんですが、<a href="https://www.microsoft.com/ja-jp/store/p/%E3%83%95%E3%82%A3%E3%83%BC%E3%83%89%E3%83%90%E3%83%83%E3%82%AF-hub/9nblggh4r32n" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">フィードバックHub</a>というのがありまして、そこでバグの報告だとか、追加してほしい機能をリクエストできるんですよ。そのリクエストのベット数が多いと優先度があがっていって、対応されるというようになっています。</p>

<p><small></p>

<p>各種ブラウザのステータスが確認できるサイト</p>

<ul>
<li><a href="https://developer.microsoft.com/en-us/microsoft-edge/platform/status/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Microsoft Edge</a></li>
<li><a href="https://www.chromestatus.com/features" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Chrome</a></li>
<li><a href="https://webkit.org/status/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Webkit</a></li>
</ul>

<p></small></p>

<h2>注目のWeb最新技術を一挙に解説！Web Payments、WebVR、AMP、PWA、WebAssembly&#8230;</h2>

<p><b>白石</b>: 
ではここからは、注目のWeb最新技術についていろいろお聞きしたいと思います。Web Payments、WebVR、AMP、PWA、WebAssemblyなどなど、仕様ごとに概要と現状をお話しください。</p>

<h3>Web Payments</h3>

<p><b>えーじ</b>: 
今までWebでお金を払うといったら、フォームを使ってクレジットカード番号を入れたりとか、どこかのサイトに飛んで、そこのサイトにあらかじめ保存してある支払い情報を使うといったことがほとんどだったと思います。Web Paymentsを使うと、ブラウザがネイティブで表示してくれるUIを使って支払いができるようになるというのが大きな特徴ですね。ちょっと見てもらうと、<a href="https://polykart.store/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">PolyCart</a>というWeb Paymentsのデモサイトで確認することができます。</p>

<p><strong>Web Paymentsのデモサイト（PolyCart）</strong>
<img src="/wp-content/uploads/2018/01/a6667251245e38bfbcf2b1aaac09926a.png" alt="" width="640" height="521" class="aligncenter size-full wp-image-25171" srcset="/wp-content/uploads/2018/01/a6667251245e38bfbcf2b1aaac09926a.png 640w, /wp-content/uploads/2018/01/a6667251245e38bfbcf2b1aaac09926a-300x244.png 300w, /wp-content/uploads/2018/01/a6667251245e38bfbcf2b1aaac09926a-207x169.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>ブラウザネイティブのUIを通じてクレジットカードの情報や、配送先、連絡先などの入力を促すことができます。そうして入力された情報はブラウザが記憶してくれるので、次からはクリックするだけで支払い情報を入力することができます。</p>

<p>もっとすごいのは、将来的には支払い方法を追加できるようになるんです。例えば、Apple PayやGoogle Payで支払うのも可能ですし、仮想通貨なども使えるようになるでしょう。</p>

<h3>WebVR</h3>

<p><b>物江</b>: 
以前から、「Web上でVRコンテンツを表示する」っていうのは、Three.jsなどを使って実現が可能でした。ではWebVRは何が違うかというとVRデバイスからのフィードバックを受けることができるんです。これによって、VRデバイスと深く連動したWebサイトを作ることができます。</p>

<p>それにWindows10だと、ネイティブでVRの環境をサポートしていて、WebVRに対応したWebサイトにいくと、自動的にVRゴーグル上で全画面表示してくれるようになっています。VRのビデオもそのまま見ることができるので、真の意味でシームレスにVRのコンテンツが提供できるようになっています。</p>

<p>個人的に楽しみなのは、VRをきっかけとして新しいUIが生まれてくることですね。既存のVRゴーグルを使ったことがある人はわかると思うんですけど、キーボードもマウスも何も使えないんです。そうすると新しいUIを考える必要があって、そこに新しい可能性を感じています。</p>

<p><b>えーじ</b>: 
ちなみに最近は<a href="https://github.com/mozilla/webxr-api" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">WebXR</a>っていうらしいですね。VR、AR、MRをコンセプトに入れた仕様を作ろうとしているという動きもありますね。</p>

<h3>AMP</h3>

<p><b>白石</b>: 
次はAMPですが、これについては既にたくさんの方がご存知でしょうから、簡潔に。主にモバイル環境で、Webページを素早く表示できるようにするための、HTMLのサブセットですね。</p>

<p><b>えーじ</b>: 
AMPの仕様自体もさることながら、AMPが基本的にWeb Componentsでできているのは興味深いです。Web Componentsの仕組みを使って独自のエレメントを定義していて、なおかつパフォーマンスも追求しているので、結果としてパフォーマンスのベストプラクティスの塊をWeb Components化したものになっている。大変面白いと思います。</p>

<h3>Progressive Web Apps</h3>

<p><b>白石</b>:
次は、恐らく今年最大の注目キーワードProgressive Web Appsですね。これは（ずっと啓蒙してきた）えーじさんに語っていただくしかないでしょう。</p>

<p><b>えーじ</b>: 
はい。とはいえPWAという言葉自体は、皆さんに意識してもらいやすくするためのマーケティング用語のようなもので、技術的な観点からはそれ自体意味がないと思っています。実際の中身はService WorkerだったりとかPush Notificationだったりとかそういう具体的な機能やAPIから構成されています。</p>

<p>日本でも、昨年後半くらいからPWAが注目されはじめました。さっきのdev.toとか日経電子版とかも、PWAの構成要素を利用することで高速化が実現できたと。PWAの中のひとつひとつの技術要素をうまく使うとここまで速くできるんだよ、といういい例ができたなと思っています。</p>

<p><img src="/wp-content/uploads/2018/02/DSC09088.jpg" alt="" width="640" height="412" class="alignnone size-full wp-image-25196" srcset="/wp-content/uploads/2018/02/DSC09088.jpg 640w, /wp-content/uploads/2018/02/DSC09088-300x193.jpg 300w, /wp-content/uploads/2018/02/DSC09088-207x133.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b>白石</b>: 
ちなみに、個人的にはPWAっていまいち意味がわからないな、と思ってて。なにが「プログレッシブ」なんでしょうか？プログレッシブって、「だんだん（進化する）」って意味ですよね。</p>

<p><b>えーじ</b>: 
PWAにおける「プログレッシブ」には2つ意味があります。</p>

<p>1つは昔から言われているプログレッシブ・エンハンスメントです。古いブラウザでも見ることができる基本的なWebサイトをまずは作って、そこに、新しいブラウザで使える機能を足していくという考え方。そうすれば、クライアントの環境を最大限活かすことができます。</p>

<p><b>白石</b>: 
では、Service Workerが使えるブラウザだったらオフラインという機能が使えるけど、そういう機能が使えないブラウザにも同等のものを提供する。既存のサイトにあとからその機能を提供することも割と簡単にできますよっていうそういう思いを込めたものということですね。</p>

<p><b>えーじ</b>: そうです。もう1つが、今あるサイトに機能を付け加えていくことで、徐々にPWAに近づけていけるという意味です。PWAのためにサイトを一から作り直すとか、大幅な改修を行う必要はない。既存のサイトを徐々に拡張していけばいいんです。</p>

<p><b>白石</b>: 
なるほど、そういう意味合いだったんですね。ちなみにPWAの中では、Service Workerが代表的なAPIですよね。他には<a href="https://developers.google.com/web/fundamentals/web-app-manifest/?hl=ja" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web App Manifest</a>とか、<a href="https://developers.google.com/web/fundamentals/codelabs/push-notifications/?hl=ja" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Push Notification</a>とかでしょうか。</p>

<p><b>えーじ</b>: 
そうですね。ちなみに、PWAのウリの一つに、OSのホーム画面にアイコンを追加できるというのがあるんですが、以前はただのWebアプリへのショートカットでした。でも今は違います。PWAをホーム画面に置く際、アプリのパッケージを動的に生成してインストールするので、OS上の扱いはネイティブアプリとほとんど変わりないんです。なので、プッシュ通知のオン／オフをアプリごとに設定できたり、ネイティブアプリでしかできなかったことがPWAでも同様に行えます。</p>

<h3>WebAssembly</h3>

<p><b>白石</b>: 
次はWebAssembly、物江さんご説明お願いします。</p>

<p><b>物江</b>: 
WebAssemblyは、Webブラウザ上で非常に高速に動作させることができる、デバイスに依存しないバイナリ形式です。現在は用途がある程度限られていて、DOMを操作することなどはできませんが、CPU依存の計算処理などは極めて高速に動作させることができます。
<a href="https://developer.mozilla.org/ja/docs/Mozilla/Projects/Emscripten" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Emscripten</a>などのツールを使うと、C/C++で作られたものをWebAssemblyに変換できるので、C/C++で書かれたゲームなどをWebAssemblyに移植することも比較的容易です。また現在はまだ開発中ではありますが、MonoがC#からWebAssemblyをコンパイルする<a href="https://github.com/lrz/mono-wasm" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">mono-wasm</a>であったり、マイクロソフトも実験プロジェクトとしてWebAssemblyを介してWebブラウザー上でC#とRazorを走らせるWeb UI framework  <a href="https://blogs.msdn.microsoft.com/webdev/2018/02/06/blazor-experimental-project/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Blazor</a>を開発していたりします。</p>

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

<p>（ここで会場からエキスパートである<a href="https://html5experts.jp/technohippy/" data-wpel-link="internal">あんどうやすしさん</a>から質問）</p>

<p><b>あんどうやすし</b>: 
現在のWebAssemblyって結局計算することしかできないじゃないですか、DOMもいじれないし、JavaScriptのAPI呼び出しも直接は行えない。今後もそれは変わらないんでしょうか。特にデータの渡し方に結構制限があって、使い勝手がいいものにするには難しいなと感じています。SharedArrayBufferという仕組みで一次元配列の共有はありますが、それも使いづらいし…。</p>

<p><b>物江</b>: 
それは、今の段階ではまだなんとも言えないですね。</p>

<p><b>えーじ</b>: 
ちなみにSharedArrayBufferはこないだのメルトダウンとスペクター(*2)の影響で機能が停止になります。</p>

<p><b>白石</b>: 
ありゃ、まさかそんなところにまで影響及ぶとは…(笑)。</p>

<p>*2 … CPUでの投機的実行という高速化プロセスを悪用した脆弱性</p>

<h3>Web Share API</h3>

<p><b>白石</b>: 
他には、注目のAPIとかはありますか？</p>

<p><b>えーじ</b>: 
最近追加されようとしている新しい機能に<a href="https://developers.google.com/web/updates/2016/09/navigator-share" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Share API</a>というのがあります。</p>

<p>Androidのインテントをご存知の方だったらすぐ分かる機能ですが、例えばあるサイトを「FacebookやTwitterでシェアしたい」という場合に、Web Share APIを使うと簡単に外部アプリを呼び出すことができます。</p>

<p>逆に、自身のWebアプリを「シェアする先のアプリ」として使ってもらうようにすることもできます。それが<a href="https://github.com/WICG/web-share-target" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Share Target API</a>というものです。</p>

<p>Web Share APIは既に使えるんですが、Web Share Target APIは、現在限られたサービスにしか開放されていません。このように、Chrome では一部のドメインに先行してWebプラットフォームの機能を試してもらうオリジントライアルというものをやっているのですが、現在TwitterのモバイルサイトがWeb Share Target APIを使えるようになっています。<a href="https://mobile.twitter.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">mobile.twitter.com</a>で実際に試すことができますので、TwitterのPWAをまだ試したことがない方は、AndroidのChrome betaチャネルか、devチャネルを使ってインストールしてみてください。何かシェアしようとしたときに、TwitterのPWAが候補として出てきます。</p>

<h3>Web Authentication</h3>

<p><b>白石</b>: 
Web Authenticationというのもあると聞きました。</p>

<p><b>えーじ</b>: 
Web Authenticationは、実はEdgeでもう使えるんです。仕様がちょっと古いので、APIが全く異なりますが、<a href="https://github.com/MicrosoftEdge/webauthn-polyfill/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polyfill</a>もあります。Web Authenticationをひとことでいうと、セキュリティキーなどを用いた多要素認証を標準技術で扱えるようにするものです。顔認証や指紋認証と組み合わせれば、安全性の高いログインの敷居はぐっと下がると思います。</p>

<p><b>物江</b>: 
<a href="https://fidoalliance.org/?lang=ja" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">FIDO Alliance</a>という標準化団体があるんですけど、そこで生体認証などのもっと広い話をしています。既にWindowsだとWindows Helloという生体認証の仕組みがFIDOの標準で作られていますね。</p>

<p><b>えーじ</b>: 
FIDOのWeb版がWeb Authenticationになるわけです。Web Authenticationの実装はこれからどんどん出てくるでしょう。Mozillaさんもこないだ実装を開始しましたし、Chromeもそろそろ入ってくるのかなと思います。</p>

<p><b>白石</b>: 
そうすると、もしかしたら今年はWebサイトで指紋認証とか顔認証とかが一般的になってくるという可能性があるってことですかね。</p>

<p><b>えーじ</b>: 
そうですね。どの認証方式を使えるようにするかっていうのは、順番に1つずつ入れていくという話らしいので、まずはセキュリティーキーから利用できるようになって、そのうちNFC、指紋認証ができるようになっていくようです。徐々にそういったものが実装されていけば、本当にパスワードを覚えなくてもいい世界っていうのが実現できるかもしれないので、すごく楽しみにしています。</p>

<p>ちなみに、<a href="https://developers.google.com/web/fundamentals/security/credential-management/?hl=ja" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Credential Management API</a>というIDとパスワード、いわゆる共通鍵認証をする仕様があるんですが、それとAPIのネームスペースが同じになるので、共通のAPIを使うことになります。まったく別々だった仕様が一緒になるというのも個人的には面白いと感じています。</p>

<p><img src="/wp-content/uploads/2018/02/IMG_5443.jpg" alt="" width="640" height="413" class="alignnone size-full wp-image-25199" srcset="/wp-content/uploads/2018/02/IMG_5443.jpg 640w, /wp-content/uploads/2018/02/IMG_5443-300x194.jpg 300w, /wp-content/uploads/2018/02/IMG_5443-207x134.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>エキスパートたちが見据えるWebの未来について</h2>

<p><b>白石</b>: 
最後にWebの今後について感じていることをお聞かせください。</p>

<p><b>えーじ</b>: 
ぼくらブラウザベンダーは、「こうなるといいな」というものをいろいろ作ってるんですけど、それはブラウザベンダーが勝手にやってるわけじゃなくて、開発者の皆さんの声とか、こういうWebがいいという声をもとにやっているので、フィードバックをできるだけいただいたほうが、より皆さんの理想としているWebができると思っています。</p>

<p>フィードバック方法にも今はいろいろあって、GitHub上で管理されている仕様にIssueを立てるっていうのも一つの方法ですし、一番簡単な方法です。それすらめんどくさいということであれば、ぼくに直接言っていただくとかでも構いません(笑)。そんな感じで、開発者の皆さんと一緒にWebを盛り上げていけたらいいなと思います。</p>

<p><b>物江</b>: 
個人的な思いとしては、今非常にWebって良い方向に進んでいると思っています。（お互いを傷つけ合うような）ブラウザ戦争は終わりました。今は良い意味でお互いに競争し合ったり、歩調を合わせてWebを良いものにしていこうという動きが主流になりつつ会って、とても好ましく感じています。今後もそれが続いていって、Webのテクノロジーの活用範囲が広がればいいなと思っています。</p>

<p><b>白石</b>: 
皆さん、本日は様々なお話をお聞かせいただき、ありがとうございました！</p>
]]></content:encoded>
		
		<series:name><![CDATA[Webの未来を語ろう 2018]]></series:name>
	</item>
	</channel>
</rss>
