<?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>WebAssembly &#8211; HTML5Experts.jp</title>
	<atom:link href="/tag/webassembly/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の過去から現在・未来まで！エバンジェリストたちが語る、最先端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>
		<item>
		<title>WebAssemblyの基礎から最新動向まで、@chikoskiに聞いてきた！</title>
		<link>/shumpei-shiraishi/24409/</link>
		<pubDate>Wed, 25 Oct 2017 01:00:17 +0000</pubDate>
		<dc:creator><![CDATA[白石 俊平]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[WebAssembly]]></category>
		<category><![CDATA[asm.js]]></category>

		<guid isPermaLink="false">/?p=24409</guid>
		<description><![CDATA[連載： HTML5 Conference 2017特集 (9)こんにちは、編集長の白石です。 この記事は、9月24日に開催されたHTML5 Conference 2017に登壇したエキスパートに、お話されたセッションのト...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/html5-conf2017/" class="series-457" title="HTML5 Conference 2017特集" data-wpel-link="internal">HTML5 Conference 2017特集</a> (9)</div><p>こんにちは、編集長の白石です。</p>

<p>この記事は、9月24日に開催された<a href="http://events.html5j.org/conference/2017/9/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML5 Conference 2017</a>に登壇したエキスパートに、お話されたセッションのトピックを中心に、様々なお話を伺おうというものです。セッションの内容をより深く理解する手助けになるだけでなく、本記事単体でも面白く読んでいただけることを目指しています。</p>

<p>今回お話を伺ったのは、WebAssemblyコミュニティを率いてらっしゃる清水 智公さん（@chikoski）です。清水さんのセッションは「<a href="http://events.html5j.org/conference/2017/9/session/#d5" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">WebAssembly MVPまとめと、今の議論の内容からいくつか</a>」でした。</p>

<p><img src="/wp-content/uploads/2017/10/DSC05255.jpg" alt="" width="640" height="409" class="alignnone size-full wp-image-24599" srcset="/wp-content/uploads/2017/10/DSC05255.jpg 640w, /wp-content/uploads/2017/10/DSC05255-300x192.jpg 300w, /wp-content/uploads/2017/10/DSC05255-207x132.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>※スライド資料は<a href="https://speakerdeck.com/chikoski/20170924-html5conference-wasm" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">こちら</a>で公開されています。</p>

<iframe class="embedly-embed" src="//cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fspeakerdeck.com%2Fplayer%2F847ab70cbf364637b574d6ee1d8382ce&#038;url=https%3A%2F%2Fspeakerdeck.com%2Fchikoski%2F20170924-html5conference-wasm&#038;image=https%3A%2F%2Fspeakerd.s3.amazonaws.com%2Fpresentations%2F847ab70cbf364637b574d6ee1d8382ce%2Fslide_0.jpg&#038;key=internal&#038;type=text%2Fhtml&#038;schema=speakerdeck" width="500" height="416" scrolling="no" frameborder="0" allowfullscreen></iframe>

<p><br></p>

<h2>WebAssemblyとは何か？</h2>

<p><b class="speaker siraisi">白石:</b> 今日はよろしくお願いします。まずは自己紹介をお願いできますか？</p>

<p><b class="speaker simizu">清水:</b> WebAssemblyのコミュニティを運営している清水です。<a href="https://twitter.com/ikkou" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">@ikko</a>さんと一緒に、「<a href="https://emsn.connpass.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">emcscripten night !!</a>」というイベントを四半期に一回くらいのペースで開催しています。</p>

<p><b class="speaker siraisi">白石:</b> では早速ですが、<strong>WebAssembly（WASM）とは何なんでしょうか？</strong></p>

<p><b class="speaker simizu">清水:</b> 一言で言うと、<strong>Webブラウザ上で実行できる、ポータブルなバイナリ形式</strong>です。現在、「MVP（Minimul Viable Product: 最小限有用な機能を備えたプロダクト）」の実装が完了し、ほぼすべてのメジャーブラウザで利用できるという状態です。</p>

<p><b class="speaker siraisi">白石:</b> ポータブルというと、ブラウザにも、OSにも、デバイスにも依存しないということですね。</p>

<p><b class="speaker simizu">清水:</b> その通りです。Javaをご存じの方であれば、classファイル形式を思い浮かべていただくと理解は早いと思います。</p>

<p><b class="speaker siraisi">白石:</b> なるほど。なぜそうしたバイナリ形式が必要とされたんでしょうか？</p>

<p><b class="speaker simizu">清水:</b> これまでWebページで動作するプログラミング言語といえば当然JavaScriptだったわけですが、<strong>JavaScriptは遅い</strong>という問題がありました。asm.jsでスピードの面は大分改善されたのですが、今度はサイズが大きくなってしまうという問題も生まれました。それで早く動かせて、サイズもasm.jsよりは小さいものとして、WebAssemblyが生まれたんです。</p>

<p>遅さの原因の一つは、JavaScriptは変数の型が動的だということです。例えばJavaScriptで足し算を行うコードがあるとしたら、いろんな可能性を考慮しなくちゃいけないんですよね。</p>

<p>値が整数かもしれないし、浮動小数点かもしれない。文字列かもしれないし、<code>valueOf()</code>を持つオブジェクトかもしれない。こういう可能性を踏まえると、単なる足し算といえども最適化は容易じゃないわけです。</p>

<p>ですがWebAssemblyの場合は、コンパイル時に変数の型が決まるので、最適化が容易なんです。今では、<strong>ネイティブに比べて2/3くらいの速度</strong>というところまで改善されています。</p>

<p><b class="speaker siraisi">白石:</b> なるほど。サイズが小さくなるという点についてはいかがでしょう。</p>

<p><b class="speaker simizu">清水:</b> JavaScriptは当然テキスト形式ですが、テキストってやはり冗長なんですよね。例えば、とあるゲームのコードを全部JavaScriptに変換したところ、40メガバイトを超えるサイズになってしまったことがあります。</p>

<p>これでは、JavaScriptのソースコードをダウンロードするだけでかなりの時間がかかってしまうし、実行にかかるコストも半端ではありません。</p>

<p>WebAssemblyは、サイズを小さくすることを最初から念頭に置いたバイナリ形式ですので、確実にサイズは縮まります。元のJavaScriptファイルにもよりますが、ミニファイして圧縮した場合に比べても小さくなるのは確実。場合によっては半分以下のサイズになることもあります。</p>

<p><b class="speaker siraisi">白石:</b> それほど素晴らしいのであれば、将来的にはJavaScriptを置き換えていくような存在になるのでしょうか？</p>

<p><b class="speaker simizu">清水:</b> いえ、WASMはJavaScriptの置き換えは目指しておらず、あくまで補完する存在という位置付けです。例えば、WASMはDOMに直接アクセスすることができませんからね。</p>

<h2>WASMへの対応状況</h2>

<p><b class="speaker siraisi">白石:</b> では改めて、ブラウザのWASMへの対応状況を教えていただけますか？</p>

<p><b class="speaker simizu">清水:</b> 先ほども申し上げたとおり、ほとんどのメジャーブラウザで使えます（参考: <a href="http://caniuse.com/#feat=wasm" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Can I Use</a>）。Safariが11から対応するようになったのは大きいですね。iOSでも使えるようになったということなので。
Edgeも先日のCreator’s updateでデフォルトでWebAssemblyを利用できるようになりました。また、Node.jsでもWebAssemblyは動作します。</p>

<p><b class="speaker siraisi">白石:</b> Nodeでも動くんですか！知りませんでした。WASMにコンパイル可能な言語には、どのようなものがありますか？</p>

<p><b class="speaker simizu">清水:</b> 様々なコンパイラで利用されている、<a href="https://ja.wikipedia.org/wiki/LLVM" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">LLVM</a>という中間言語があるんですが、LLVMに変換される言語だったらだいたい大丈夫です。<a href="https://github.com/kripken/emscripten" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Emscripten</a>というツールを使うと、LLVMからWASMに変換できるのです。</p>

<p>LLVMにコンパイルできる言語というと、C/C++/Objective-Cなどが挙げられます。また、<a href="https://www.rust-lang.org/ja-JP/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Rust</a>もWebAssemblyに対応しています。</p>

<p>あとUnity限定になってしまうのですが、C#にも対応しています。他には<a href="https://github.com/AssemblyScript/assemblyscript" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">AssemblyScript</a>といって、WebAssemblyを出力できるTypeScriptのサブセット言語も存在します。</p>

<p><b class="speaker siraisi">白石:</b> C#やTypeScriptもあるんですね！WebAssemblyにはガベージコレクタがないと聞いていたので、それらの言語が使えるというのは驚きです。</p>

<p>ちなみに、WASMを出力できる言語や動作する環境がたくさんあるのはわかったのですが、実際どれくらい実用的なんでしょうか？</p>

<p><b class="speaker simizu">清水:</b> 今は、<strong>ざっくり言ってC言語のコードをコンパイルして動かす能力は備えている</strong>というところです。
C++への対応は完全じゃありません。C++の例外をまだうまく扱えないんですよね。</p>

<p><b class="speaker siraisi">白石:</b> Cと言えば、メモリを直接操作するようなコードを直接書けると思うのですが、それがWebAssembly上だとどのように動作するのでしょうか？</p>

<p><b class="speaker simizu">清水:</b> WebAssemblyのコードには専用のメモリ空間が割り当てられるんです。C言語におけるメモリ操作などは、そのメモリ空間に対して行われます。そのメモリ空間は、JavaScriptコードからも<code>ArrayBuffer</code>オブジェクトとして参照できます。</p>

<p>ちなみに、WebAssemblyの仕様上は64ビットのメモリ空間を扱えるのですが、現在の実装上では32ビットに制限されていますね。</p>

<h2>WASMを使う</h2>

<p><b class="speaker siraisi">白石:</b> WASMを使うコードはどういうふうになりますか？</p>

<p><b class="speaker simizu">清水:</b> まず、WASMのバイナリが必要です。拡張子は<code>.wasm</code>です。そのファイルを<code>fetch()</code>でも<code>XMLHttpRequest</code>でも何でもいいので読み込んで、バイナリコードを<code>ArrayBuffer</code>化し、<code>WebAssembly.instanciate()</code>というメソッドに渡します。</p>

<p>すると、WebAssemblyコードの実行結果が<code>Promise</code>の戻り値として返ってくるので、そこにエクスポートされている関数をJavaScript側から呼び出すことが可能です。</p>

<p></p><pre class="crayon-plain-tag">// MDNのサンプルを引用
// https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate

// WASMファイルを読み込み
fetch('sample.wasm').then(response =&gt;
  // ArrayBuffer化
  response.arrayBuffer()
).then(bytes =&gt;
  // インスタンスを生成
  WebAssembly.instantiate(bytes)
).then(result =&gt;
  // 生成されたインスタンスのエキスポートされた関数を呼び出し
  result.instance.exports.exported_func()
);</pre><p></p>

<p><b class="speaker siraisi">白石:</b> なるほど、使うのはそれほど難しくなさそうですね。JavaScriptからシームレスに関数の呼び出しを行えるのが素晴らしい。</p>

<p><b class="speaker simizu">清水:</b> はい、それにWASMのコード内から、外部JavaScriptのコードを呼び出すことも簡単にできます。<code>WebAssembly.instantiate()</code>の第二引数で、WASMコードがインポートするメンバーを指定できるんです。</p>

<p></p><pre class="crayon-plain-tag">// MDNのサンプルを引用
// https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate

// WASMがインポートして使用するオブジェクト
var importObject = {
  imports: {
    imported_func: function(arg) {
      console.log(arg);
    }
  }
};
fetch('simple.wasm').then(response =&gt;
  response.arrayBuffer()
).then(bytes =&gt;
  // インポートするオブジェクトを指定
  WebAssembly.instantiate(bytes, importObject)
).then(result =&gt;
  result.instance.exports.exported_func()
);</pre><p></p>

<p><b class="speaker siraisi">白石:</b> なるほど、ダイナミックリンクが可能なんですね。WASMがJavaScriptをどう補完するのか、よくわかりました。</p>

<h2>WASMはどう使われていくか</h2>

<p><b class="speaker siraisi">白石:</b> WASMが登場したことで、具体的に何が変わっていくと思いますか？</p>

<p><b class="speaker simizu">清水:</b> まずはやはり、C/C++で書かれたコードをWASMに変換して使うのが一番最初に思いつくユースケースです。
コンシューマー向けのサービスでいうと、やはりゲーム系がすぐに思いつきますね。</p>

<p>例えば新たなゲームタイトルをスマホ向けにネイティブで開発しつつ、WASMでコンパイルしてWeb版も同時に開発するということができます。
UnityはWebAssemblyに対応しているので、そういう開発を行うのは比較的簡単です。</p>

<p><b class="speaker siraisi">白石:</b> なるほど、スマホ版だけじゃなくてWeb版も同時に開発して公開できれば、ユーザーへのリーチが拡大しそうですね。</p>

<p><b class="speaker simizu">清水:</b> 実際、とあるベンダーさんが、Android用のゲームをWebブラウザでも動作するようにしたところ、ユーザー数はかなり増えたと聞いています。</p>

<p><b class="speaker siraisi">白石:</b> では、<strong>まずはネイティブとWebのクロスプラットフォーム開発でWASMは活躍しそう</strong>だと。
<strong>他にはC言語で書かれた資産とかもWeb上で使えそう</strong>ですよね。例えばgzipのライブラリとか。</p>

<p><b class="speaker simizu">清水:</b> そう、圧縮や暗号系、画像処理などの、Cで書かれたライブラリをWeb上に移植するのにも向いていますね。
CPUに依存する処理を高速化するのには、すごく向いています。</p>

<p>Cで書かれたコードの移植といえば、<a href="https://github.com/vvanders/wasm_lua" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">lua</a>もWASMにコンパイルできたそうです。</p>

<p><b class="speaker siraisi">白石:</b> おお、言語処理系まで！そうか、よく考えたら、現在のWASMにガベージコレクタがなくとも、ガベージコレクタを備えた処理系ごとコンパイルしちゃえばいいんですね。</p>

<h2>WASMのこれから</h2>

<p><b class="speaker simizu">清水:</b> はい、ちょうどガベージコレクタの話が出たので、WASMのこれからという話をしたいと思います。WASMの次のターゲットとして、<a href="https://github.com/WebAssembly/gc/blob/master/proposals/gc/Overview.md" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ガベージコレクタが提案されています</a>。</p>

<p>こちらはおそらく、「ガベージコレクタを使いたい場合は使える」という設計になると予想されています。</p>

<p><b class="speaker siraisi">白石:</b> ガベージコレクタが使えるようになったら、WASMをターゲットにした言語処理系とかが作りやすくなりそうですね。WASMで提案されている仕様は他にもありますか？</p>

<p><b class="speaker simizu">清水:</b> まず、<a href="https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">スレッドを使えるようにする</a>という提案があります。
やはり、pthread (POSIXスレッド: C言語で使用できるマルチスレッドAPI)を使いたいという要望が多いんですね。
複数のWeb Workers（Web環境でマルチスレッディングが可能なAPI）で共有できる Shared ArrayBuffer は既に利用可能ですが、複数のスレッドを待ち合わせる<code>wait</code>や<code>wake</code>と言った命令も使えるようにすることを見据えています。</p>

<p>他には、先ほども申し上げたように<a href="https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">例外</a>を扱えるようにして、C++コードもWASMに正しくコンパイルできるようにすること。WASMのモジュールとECMA Scriptモジュールの整合性を取る…と言った提案も行われています。</p>

<p><b class="speaker siraisi">白石:</b> WASMの未来、楽しみですねー。最後にお聞きしたいのですが、現時点でWASMを試すのにおすすめの言語はありますか？C/C++で書くのはなかなかしんどいなあ、と…</p>

<p><b class="speaker simizu">清水:</b> HTML5 Experts.jpの読者に向けてという話であれば、TypeScript（のサブセット）をWASMにコンパイルできる、<a href="https://github.com/AssemblyScript/assemblyscript" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">AssemblyScript</a>を使うのはおすすめです。Web技術者が軽く試してみるという用途には最適だと思います。</p>

<p><b class="speaker siraisi">白石:</b> 本日は、WebAssemblyについて基礎から最新情報まで教えていただき、ありがとうございました。</p>
]]></content:encoded>
		
		<series:name><![CDATA[HTML5 Conference 2017特集]]></series:name>
	</item>
		<item>
		<title>Webブラウザで高速な演算を可能にする低水準言語asm.jsと、WebAssembly詳解ーasm.jsを高速に動作させる新しいコンパイラーターゲットWASMとは？</title>
		<link>/chikoski/22523/</link>
		<pubDate>Tue, 28 Mar 2017 02:00:49 +0000</pubDate>
		<dc:creator><![CDATA[清水智公]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[WebAssembly]]></category>
		<category><![CDATA[asm.js]]></category>

		<guid isPermaLink="false">/?p=22523</guid>
		<description><![CDATA[連載： 低水準言語asm.jsとWebAssembly詳解 (4)低水準言語asm.jsとWebAssembly詳解の第4回目です。前回までで、asm.jsの必要とされる理由と、その仕様、そしてasm.jsを生成するツー...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/asmjs/" class="series-384" title="低水準言語asm.jsとWebAssembly詳解" data-wpel-link="internal">低水準言語asm.jsとWebAssembly詳解</a> (4)</div><p><a href="https://html5experts.jp/series/asmjs/" data-wpel-link="internal">低水準言語asm.jsとWebAssembly詳解</a>の第4回目です。前回までで、asm.jsの必要とされる理由と、その仕様、そしてasm.jsを生成するツールであるEmscriptenを紹介しました。CやC++で書かれたソースコードから「低水準」なJavaScriptコードが出力され、それが高速に動作する理由について述べてきました。</p>

<p>前回の最後で述べた通り、Emscriptenで出力されたasm.jsのファイルはサイズが大きくなりがちでした。ファイルのサイズが大きくなるとダウンロードに時間がかかるのはもちろん、ネイティブコードへのコンパイルにも大きく時間がかかってしまいます。つまり高速に動作するのは良いが、起動に時間がかかるサイトができてしまうことになります。</p>

<p>この問題を解決するために登場するのがWebAssembly(WASM)です。これはプログラミング言語ではなく、ファイルフォーマットの一種です。
同じプログラムをasm.jsとして出力したものと、WASMとして出力したものを比較すると、WASMの方がぐっと小さくなっていることがわかります。</p>

<table>
<thead>
<tr>
  <th>プログラム</th>
  <th>コードのサイズ（asm.js）</th>
  <th>コードのサイズ（WebAssembly）</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Hello World</td>
  <td>301KiB</td>
  <td>204KiB</td>
</tr>
<tr>
  <td>AngryBots</td>
  <td>19MiB</td>
  <td>6MiB</td>
</tr>
<tr>
  <td>StandardAssets</td>
  <td>25.7MiB</td>
  <td>13.4MiB</td>
</tr>
<tr>
  <td>UnityChan-CRS</td>
  <td>21.3MiB</td>
  <td>11.4MiB</td>
</tr>
</tbody>
</table>

<p>現在はその仕様策定が固まり、ブラウザへの実装も済み、リリースを待つばかりです。またコンパイラへの実装も進んでいます。特にBinaryen（後述します）への最適化処理の実装のおかげで、asm.jsより高速に実行できるようになりました。</p>

<p>下記のグラフ（<a href="https://hacks.mozilla.org/2016/10/webassembly-browser-preview/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">MozillaのHacksブログ</a>より引用）はasm.jsとWASMの速度を比較したものです。値はネイティブの実行スピードに対する相対的な速度を表していて、1に近づけは近づくほどネイティブに近いスピードで動いていることを表しています。Bulletを除く全てのベンチマークでasm.jsより高速に動いています。これはコンパイラの行う最適化処理のおかげです。</p>

<p><img src="/wp-content/uploads/2017/03/asmjs-wasm-comparison-updated-300x199.png" alt="asm.jsとWebAssemblyの速度比較" width="300" height="195" class="aligncenter size-medium wp-image-22524" /></p>

<p>この評価は2016年10月末の時点に、Intel Core i7-2600 @ 3.40GHzで動作するLinux版 64-bit Firefox 52 (Nightly)で計測されました。現在は最適化処理の更なる修正によって、Bulletでもasm.jsを上回るパフォーマンスが出るようになっています。</p>

<p>連載の最後は、リリースが間近のWASMについて、コンパイル方法、仕様、そしてJavaScript APIについてご紹介します。</p>

<h2>WebAssemblyとは</h2>

<p>WebAssemblyとはプログラムを表すファイルフォーマットの一種で、拡張子には<code>.wasm</code>を利用することが一般的です。
Webで扱うファイルの大半はテキスト形式ですが、WASMはバイナリ形式でプログラムを表現します。
バイナリエディタを用いてWASMファイルを作成することも、もちろん可能ですが、Emscriptenに代表されるコンパイラを使って出力することが一般的です。</p>

<p>仕様は<a href="https://www.w3.org/community/webassembly/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">W3Cのコミュニティグループ</a>のメーリングリストや<a href="https://www.github.com/WebAssembly" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">GitHub</a>で議論が行われています。議論の指針は次の4つです。</p>

<ul>
<li>高速で効率的に実行できつつも、ポータブルであること</li>
<li>ソースを表示できること</li>
<li>安全であること</li>
<li>Webを破壊しないこと。つまり他のWeb技術と組み合わせることができること</li>
</ul>

<p>このコミュニティグループには、Google、Microsoft、Apple、そしてMozillaの各ブラウザベンダが参加しています。実装もそれぞれに進んでおり、Firefoxでは　52で、Chromeでは57でそれぞれ標準サポートされました。EdgeとWebkitは開発の途中です。<a href="https://blogs.windows.com/msedgedev/2016/03/15/previewing-webassembly-experiments/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Edgeの開発版でAngryBotsが動作している様子は、こちらの動画で確認できます</a>し、<a href="https://webkit.org/status/#specification-webassembly" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Webkitの状況はこちらで確認できます</a>。</p>

<h2>WASMの想定される利用例は？</h2>

<p>現在のところ想定されているWASMの利用方法は次の3パターンです：</p>

<ol>
<li>アプリ全てをWASMで実装する：C/C++で書かれたアプリをWebに移植するための手段</li>
<li>WASMでほとんどを実装し、UIなどをWeb技術で実装する</li>
<li>Webアプリケーションのうち、速度が必要な部分をWASMで実装する</li>
</ol>

<p>1はWebを新しいアーキテクチャとみなし、C/C++のソースコードをクロスコンパイルする、というイメージです。この典型例はゲームでしょう。iOSやAndroid、PS4、Xbox One、PCなど様々あるゲームプラットフォームにWebが加わり、いくつかのプラットフォームへゲームをリリースするのと同じようにWeb向けにゲームをリリースする、というイメージです。</p>

<p>2は既に持っているCやC++の資産を活かしつつ、リッチなUI/UXを提供するといった使い方です。例えば画像認識エンジンや、動画像処理エンジンをすでに持っていて、これらをサービス化したい、といった場合です。それらのエンジンをWASMに変換した上で、UXやUIはWebの技術や開発手法を利用して提供することで、お互いの良いところを取ることが可能です。</p>

<p>3は暗号や圧縮・展開、画像処理といった重たい処理の高速化にWASMを利用する、といった使い方です。asm.jsがよく使われてきた用法でもあります。サーバサイドであれば、Rubyが遅くなってきたのでRustで書き換える、Pythonでは辛いからGoで、といったことがよく行われてきました。フロントエンドではそのようなことは難しかったのですが、WASMを使うことで、アルゴリズムの改良などへ踏み込まずに高速化を行えるようになります。</p>

<h2>EmscriptenでWebAssemblyを出力するには</h2>

<p>テキスト形式のプログラムからWebAssemblyを変換して出力する方法は、概ね次の3つになります：</p>

<ol>
<li>C/C++で書かれたソースコードをEmscripntenで処理して出力する</li>
<li>Rustで書かれたソースコードをコンパイルして出力する</li>
<li>WAST（WASMのテキスト形式）で書き、それを変換して出力する</li>
</ol>

<p>現在のところは1が最も事例の多い変換方法でしょう。Emscripten自身のインストール方法は前回の記事をご覧いただくとして、ここではWASMを出力できるように設定を行い、Hello,Worldをコンパイルするところまでを説明します。</p>

<p>EmscripntenでWASMを出力するためには、開発版とBinaryenというツールが必要です。どちらもemsdkを利用してインストールできます。</p>

<p></p><pre class="crayon-plain-tag">$ emsdk install sdk-incoming-64bit emscripten-incoming-64bit clang-incoming-64bit
$ emsdk activate sdk-incoming-64bit emscripten-incoming-64bit clang-incoming-64bit</pre><p></p>

<p>アクティベート後は忘れずに環境変数を更新しておきます：</p>

<p></p><pre class="crayon-plain-tag">$ source ./emsdk_evn.sh</pre><p></p>

<p>では次のHello,WorldをWASMに出力します。
まず次のようなC言語で書かれたソースコードを用意します。</p>

<p></p><pre class="crayon-plain-tag">#include &lt;stdio.h&gt;

int main(int argc, char **argv){
  printf("Hello, World!\n");
}</pre><p></p>

<p>このコードをEmscriptenを使ってコンパイルします。</p>

<p></p><pre class="crayon-plain-tag">$ emcc -o hello-world.html -s WASM=1 hello-world.c</pre><p></p>

<ul>
<li><code>-o</code>オプションでHTMLファイルを出力すること</li>
<li><code>-s WASM=1</code>を指定すること</li>
</ul>

<p>この 2 つがポイントです。特に<code>-s WASM=1</code>をつけないと、asm.jsが出力される点にご注意ください。</p>

<p>出力されたWASMファイルが動作しているかどうかは、出力されたHTMLファイルをブラウザで表示させることで確認できます。asm.jsなどはファイルを直接開いて実行を確認できましたが、WASMでは行えません。これはWASMの実行時にはクロスオリジン要求が必要で、それがfileスキームには実装されていないためです。そのため簡易なWebサーバを起動する必要があります。任意のものをお使いいただけますが、Emscriptenに同梱されている<code>emrun</code>コマンドを利用すると設定やインストールをしなくても簡易なWebサーバを起動できます。</p>

<p></p><pre class="crayon-plain-tag">$ emrun emrun --no_browser --port 8080 .</pre><p></p>

<p>上記のコマンドを実行すると、コマンドを実行したフォルダをドキュメントルートとしたWebサーバが、8080番ポートで実行されます。こちらへアクセスすることで、動作を確認できます。</p>

<h2>WASMモジュールの構造</h2>

<p>実はWASMのMVP(Minimal Viable Product/最低限の目標)はasm.jsとの互換機能の提供でした。つまりWASMはasm.jsでできることはできると思っておくと、概ね間違いはありません。例えばasm.jsファイルはソフトウェアモジュールを定義していましたが、同様にWASMファイルもソフトウェアのモジュールを定義します。</p>

<p>とはいえディテールは大きく異なります。asm.jsは（低水準とはいえ）JavaScriptとして処理できる形式でモジュールとその関数本体を定義していたのに対し、WASMは仮想的なハードウェアで動く低水準な命令の集まりとしてモジュールを定義します。WASMはその仕様で型付けされた<a href="https://ja.wikipedia.org/wiki/%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF%E3%83%9E%E3%82%B7%E3%83%B3" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">スタックマシン</a>を定義しており、WASMファイルにはそのスタックマシンで動作するモジュールの抽象構文木（AST：Abstruct Syntax Tree）が定義されています。
抽象構文木がバイナリ形式で与えられているおかげで、ネイティブコードを出力するために必要な処理の中で重たい字句解析の全てと、構文解析の大半を省くことができます。</p>

<p>さてWASMファイルはプリアンブルと、モジュール定義の2つの部分から成っています。プリアンブルはWASMファイルであることを表すマジックナンバー（32bit）と、バージョン番号（32bit）の2つのフィールドで構成されます。モジュール定義は次の7種類のセクションを持ち得ます。依存関係はありますが、これらの全てを省略することもできます。</p>

<table>
<thead>
<tr>
  <th>セクション名</th>
  <th>説明</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Type</td>
  <td>関数のシグネチャ</td>
</tr>
<tr>
  <td>Import</td>
  <td>インポートするシンボルの定義</td>
</tr>
<tr>
  <td>Function</td>
  <td>関数とそのシグネチャの対応付け</td>
</tr>
<tr>
  <td>Table</td>
  <td>関数表など</td>
</tr>
<tr>
  <td>Memory</td>
  <td>メモリ領域に関する設定</td>
</tr>
<tr>
  <td>Global</td>
  <td>グローバル変数</td>
</tr>
<tr>
  <td>Export</td>
  <td>エキスポートするシンボル</td>
</tr>
<tr>
  <td>Start</td>
  <td>処理を始める関数（エントリーポイント）の定義</td>
</tr>
<tr>
  <td>Element</td>
  <td>表の要素</td>
</tr>
<tr>
  <td>Code</td>
  <td>コードセグメント。関数本体</td>
</tr>
<tr>
  <td>Data</td>
  <td>データセグメント</td>
</tr>
</tbody>
</table>

<p>asm.js同様、WASMでも関数は全て型付けされます。その型が列挙されているのがtypeセクションです。関数の型は引数の型と返り値の型を組み合わせて定義します。例えば次のような足し算を行う関数は<code>(i32, i32) -&amp;gt; i32</code>のように型付けされます。</p>

<p></p><pre class="crayon-plain-tag">int add(int a, int b){
  return a + b;
}</pre><p></p>

<p>このような関数の型のことを「シグネチャ」と呼びます。シグネチャには、それぞれidが割り振られます。このidを用いて、個々の関数を型付けしていきます。個々の関数と、その関数のシグネチャの対応づけが行われるのがfunctionセクションです。上記の<code>(i32, i32) -&amp;gt; i32</code>というシグネチャのidが0の時、次の2つの関数は0番目の関数（addのこと）のシグネチャは0、1番目の関数（subのこと）のシグネチャは1、というようにfunctionセクションへ記述されます。</p>

<p></p><pre class="crayon-plain-tag">int add(int a, int b){
  return a + b;
}
int sub(int a, int b){
  return a - b;
}</pre><p></p>

<p>それぞれの関数の本体、つまり関数定義の<code>{</code>と<code>}</code>に挟まれた部分は、codeセクションに記述されます。このセクションに記述される内容については節を分けて説明します。</p>

<p>上述したように、WASMはモジュールを定義します。つまりWASM内で定義された関数のうちいくつかは外部へと露出します。逆に外部で定義された関数を読み込んで関数を定義することもあります。露出する関数や読み込まれる関数は、それぞれexportとimportのセクションに記述されます。</p>

<p>Memoryセクションには、このモジュールで利用するヒープ領域の初期サイズが設定されます。WASMのメモリは後述しますが線形で、最大4GiBまで利用できます。このセクションで定義されるメモリサイズはあくまで初期化時に割り当てられるもので、<code>grow_memory</code>命令でより多くのメモリを確保できます。</p>

<p>これら以外のセクションもモジュールの定義に必要とされることがありますが、今回は説明を割愛します。詳しくは<a href="http://webassembly.org/docs/modules/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">こちらのデザイン文書</a>をご覧ください。</p>

<h2>WASMで定義される抽象構文木</h2>

<p>ここまで述べてきたWASMの特徴をまとめると、次の3点になるでしょう。</p>

<ul>
<li>バイナリフォーマット</li>
<li>モジュールの定義</li>
<li>型付けされたスタックマシンで動作する抽象構文木を表している</li>
</ul>

<p>ここからはより詳しくWASMの構造と、それが表す抽象構文木について見ていきます。</p>

<p>そのために　WASMのテキスト表現であるWASTを利用します。このWASTは現在仕様が議論中のため、将来的に記法が変わる可能性があることにご注意ください。</p>

<p>さて<code>a = 1 + 2 * 3;</code>という式は、WASTでは次のように表現されます。</p>

<p></p><pre class="crayon-plain-tag">(set_local $a
  (i32.add
     (i32.const 1)
     (i32.mul
        (i32.const 1)
        (i32.const 2)
     )
  )
)</pre><p></p>

<p>このようにとても括弧が多いのがWASTの特徴です。この記法は<a href="https://ja.wikipedia.org/wiki/S%E5%BC%8F" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">S式</a>と呼ばれるもので、<a href="https://ja.wikipedia.org/wiki/LISP" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">LISP</a>というプログラミング言語でよく用いられるもので、木やリストの形式的な記法です。<code>(</code>と<code>)</code>で囲まれたものがノードとなり、その間に挟まれた別のノードは子ノードとなります。先ほどのWASTは次の図のような木構造を表しています。</p>

<p><img src="/wp-content/uploads/2017/02/ast-wasm-300x66.png" alt="a = 1 + 2 * 3 の抽象構文木" width="300" height="66" class="aligncenter size-medium wp-image-22525" srcset="/wp-content/uploads/2017/02/ast-wasm-300x66.png 300w, /wp-content/uploads/2017/02/ast-wasm.png 640w, /wp-content/uploads/2017/02/ast-wasm-207x45.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p><code>set_local</code>、<code>i32.add</code>、<code>i32.mul</code>、<code>i32.const</code>というのが、WASMの仕様でで定義されているスタックマシンの命令です。それぞれローカル変数への代入、加算、乗算、即値の定義を行います。四則演算や速値の定義を行う演算子は、扱うデータ型によって異なるものが用意されています。関数本体はこのように記述され、codeセクションに格納されます。</p>

<p>先ほどのWASTを使って、引数に1+2*3の結果を足す関数は次のように記述できます。詳しくは説明しませんが、なんとなく雰囲気は伝わってくるかと思います。</p>

<p></p><pre class="crayon-plain-tag">(module
  (func $addSome (param i32) (result i32)
    (local $a i32)
    (set_local $a
       (i32.add
          (i32.const 1)
          (i32.mul
            (i32.const 1)
            (i32.const 2))))
    (get_local 0)
    (get_local $a)
    (i32.add))
  (export "addSome" (func $addSome))
)</pre><p></p>

<p>なお、このWASTはスタックマシンの性質をうまく使えていません。その特徴をうまく使うと、次のようになります。</p>

<p></p><pre class="crayon-plain-tag">(module
  (type (;0;) (func (param i32) (result i32)))
  (func (;0;) (type 0) (param i32) (result i32)
    (local i32)
    i32.const 1
    i32.const 1
    i32.const 2
    i32.mul
    i32.add
    set_local 1
    get_local 0
    get_local 1
    i32.add)
  (export "addSome" (func 0)))</pre><p></p>

<p>またコンパイラで最適化処理を行うと、次のように単純化されます。1+2*3の結果をコンパイル時に計算を済ませてしまって定数とすることで、不必要な計算を省いています。</p>

<p></p><pre class="crayon-plain-tag">(module
  (type (;0;) (func (param i32) (result i32)))
  (func (;0;) (type 0) (param i32) (result i32)
    get_local 0
    i32.const 7
    i32.add)
  (export "addSome" (func 0)))</pre><p></p>

<p>WASMの構造を把握するには、<a href="https://mbebenita.github.io/WasmExplorer/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">The WASM Explorer</a>というサイトを利用されるといいでしょう。
このサイトでは、C/C++のプログラムとWASM、Firefoxによって変換されるx86のアセンブラとを比較できます。
Emscriptenで出力されたものと比べると、標準ライブラリで定義されるシンボルや関数が含まれないためコンパクトで、理解しやすいものが出力されます。</p>

<h2>WASMで扱えるデータ型</h2>

<p>WASMで扱えるデータ型は次の4つです。</p>

<table>
<thead>
<tr>
  <th>型名</th>
  <th>意味</th>
  <th>サイズ</th>
  <th>符号化方式</th>
</tr>
</thead>
<tbody>
<tr>
  <td>i32</td>
  <td>整数型</td>
  <td>32bit</td>
  <td>2の補数</td>
</tr>
<tr>
  <td>i64</td>
  <td>整数型</td>
  <td>64bit</td>
  <td>2の補数</td>
</tr>
<tr>
  <td>f32</td>
  <td>浮動小数点型</td>
  <td>32bit</td>
  <td>IEEE 754-2008</td>
</tr>
<tr>
  <td>f64</td>
  <td>浮動小数点型</td>
  <td>64bit</td>
  <td>IEEE 754-2008</td>
</tr>
</tbody>
</table>

<p>整数型と浮動小数点型とを区別して扱える点が、通常のJavaScriptとは異なります。また64bitの整数が扱える点もJavaScriptやasm.jsとも異なっています。</p>

<p>それぞれのデータ型に対して、四則演算、比較演算、即値、データのロードとストアなどの演算子が用意されています。また整数型に対してはビット演算子が、浮動小数型に対しては切り捨て、切り上げなどの演算子が用意されています。</p>

<p>また型間のデータ変換のための演算子も用意されています。32bitから64bitへの変換だけでなく、64bitから32bitへの変換も行えます。もちろん整数から小数へ、小数から整数への変換も行えます。</p>

<h3>線形メモリ</h3>

<p>WASMの命令セットはスタックマシン型として設計されていますが、メモリに対するアクセスも行えます。WASMのメモリモデルには次の特徴があります：</p>

<ul>
<li>線形</li>
<li>バイト単位でアクセス可能</li>
<li>ページ(64KiB)を単位としたメモリの増加</li>
<li>コード領域はない</li>
<li>リトルエンディアン</li>
<li>最大4GiB</li>
</ul>

<p>メモリスタックへのデータの読み込みは各データ型の持つload演算を使って行います。WASMはC/C++コードから生成されることを念頭に置いているため、load演算には、<code>i32.load_8_s</code>や<code>i32.load_16_u</code>のようなWASMにはない8bitや16bitの<code>int</code>をロードするものがあります。これらの命令はメモリ上では8bitや16bitの大きさを持つ値を、自動的に32bitへと拡張します。</p>

<p>同様にメモリへのデータ書き込みは<code>i32.store</code>のようなストア演算で行います。ストア演算も各データ型ごとに用意されており、整数型に対しては<code>i32.store8</code>や<code>i32.store16</code>のように一部分だけを保存する演算も用意されています。</p>

<p>上述したようにWASMのメモリは線形で、0から順にアドレスが付いています。ロード演算やストア演算はアドレスを使って、読み書きするメモリ上の位置を指定します。現在のところアドレスは32bitの符号なし整数で表現されます。そのため利用できるメモリの大きさは4GiBに制限されます（この制限はのちに解消される予定です）。</p>

<p>メモリは常に4GiB確保されるわけではありません。初期化時に確保される量はモジュールで定義します。プログラムの中で<code>grow_memory</code>演算を行うことで、このサイズを増やせます。また現在のメモリサイズは<code>current_memory</code>演算で取得できます。これら2つの演算はメモリをバイト単位ではなく、ページ単位で扱います。ページサイズは64KiBのため、実際のサイズはページ数に65536(16 &times; 1024)をかけた値になります。</p>

<h2>JavaScript API</h2>

<p>ここまでWASM自体について説明してきましたが、最後にJavaScriptとの連携について説明します。今の所、WASMはJavaScript APIを利用して、明示的にコンパイルし、インスタンス化する必要があります。手順としては次の通りになります：</p>

<ol>
<li>WASMファイルをダウンロードし、TypedArrayに変換</li>
<li>WASMモジュールがインポートする関数を用意する</li>
<li>1と2を利用して、WASMモジュールをインスタンス化する</li>
</ol>

<p>この手順をコード化すると次のようになります。下記の例では、上述した<code>sample.wasm</code>をインスタンス化し、そのモジュールに定義されている<code>addSome</code>を呼び出しています。</p>

<p></p><pre class="crayon-plain-tag">const importObject = {
  hello: () =&gt; console.log("Hello"),
  world: () =&gt; console.log("world")
};

fetch("sample.wasm").then(response =&gt; response.arrayBuffer())
  .then(buffer =&gt; WebAssembly.instantiate(buffer, importObject))
  .then(({module, instance}) =&gt; console.log(instance.exports.addSome(1)));</pre><p></p>

<p><code>WebAssembly.instantiate</code>が、モジュールのインスタンス化を行う関数になります。第1引数にWASMファイルがロードされたArrayBuffer演算を、第2引数にはモジュールがインポートする関数や値をまとめたオブジェクトを指定します。上の例では<code>hello</code>と<code>world</code>という2つの関数がsample.wasm内にインポートされます（実際にインポートされるかどうかは、importセクションの記述によります）。</p>

<p>インスタンス化されたされたWASMモジュールは、JavaScriptのモジュールのように扱えます。変数へ代入することもできますが、属性を追加することはできません。モジュールインスタンスは<code>exports</code>という名前の属性を持っており、その値のオブジェクトのメンバーとしてエキスポートされた関数を参照できます。</p>

<p>なお<code>WebAssembly.instantiate</code>の呼び出し時には、ダウンロードしたWASMモジュールの妥当性や、ファイルフォーマットの検証が行われます。これらに失敗した場合は、<code>WebAssembly.CompileError</code>が送出されます。これをcatchすることでコンパイルエラーを検出できます。</p>

<h2>まとめ</h2>

<p>これまで4回にわたってポータビリティや後方互換性との両立を図りつつ、ネイティブに近いスピードでの動作を実現するために行わている様々な工夫の一端を見てきました。</p>

<p>asm.jsとWebAssemblyによってネイティブに近い動作スピードは実現されつつあり、それを作成するツールもEmscriptenを筆頭に充実しつつあります。いずれフロント部分のほとんどがCやC++で実装されたWebアプリも登場するでしょう。</p>

<p>ではJavaScriptの役割は終わってしまったのでしょうか。</p>

<p>そんなことはありません。まずWebアプリの大半はasm.js/WebAssemblyで提供される計算性能を必要としていません。必要したとしても、大半のコードの価値はスピードよりもUXによって提供されるでしょう。JavaScriptの大きな特徴は、その生産性の高さです。高速に動作することよりも、高速に開発のイテレーションをまわ回して行く方が重要とされる局面は多くあるでしょう。そんな時にJavaScriptの生産性の高さが生きるでしょう。</p>

<p>ただasm.js/WASMがWebに大きな可能性を加えるものになるのは確かです。既存のWeb開発では難しかったインタラクションの多い3Dグラフィクスを扱うアプリも、UnityやUnrealEngine、Stingrayといったasm.js/WebAssemblyに対応したゲームエンジンを利用することで、効率的に開発できるようになります。工数の関係で諦めていたような表現やアプリの提案も、これらのツールを採用することで可能になる場合もあるでしょう。この連載で扱ってきた技術が、みなさまのWeb開発の選択肢に加わり、その結果Webが豊かになれば幸いです。</p>
]]></content:encoded>
		
		<series:name><![CDATA[低水準言語asm.jsとWebAssembly詳解]]></series:name>
	</item>
		<item>
		<title>WebAssembly、CPU Throttling、Custom Elementsの最新情報を解説──2016年10月のブラウザ関連ニュース</title>
		<link>/myakura/21567/</link>
		<pubDate>Fri, 04 Nov 2016 00:00:17 +0000</pubDate>
		<dc:creator><![CDATA[矢倉 眞隆]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Custom Elements]]></category>
		<category><![CDATA[DevTools]]></category>
		<category><![CDATA[Google Chrome]]></category>
		<category><![CDATA[WebAssembly]]></category>
		<category><![CDATA[ブラウザ]]></category>

		<guid isPermaLink="false">/?p=21567</guid>
		<description><![CDATA[連載： WEB標準化動向 (18)2016年10月のブラウザ関連ニュースは、10月12日にリリースされたChrome 54の追加機能からCustom Elements v1、DevToolsのCPU Throttling...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/webstandards-news/" class="series-156" title="WEB標準化動向" data-wpel-link="internal">WEB標準化動向</a> (18)</div><p>2016年10月のブラウザ関連ニュースは、10月12日にリリースされたChrome 54の追加機能からCustom Elements v1、DevToolsのCPU Throttling、WebAssemblyについて紹介します。</p>

<h2>Chrome 54リリース</h2>

<p>10月12日に、Chrome 54がリリースされました。追加された機能のまとめは、ベータ版時点で公開されたポストが詳しいです。</p>

<ul>
<li><a href="https://googledevjp.blogspot.jp/2016/10/chrome-54-beta-custom-elements-v1.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google Developers Japan: Chrome 54 ベータ版：Custom Elements V1、BroadcastChannel、メディア プラットフォームの強化</a></li>
</ul>

<p>以下、気になったものを取り上げます。</p>

<h3>Custom Elements v1</h3>

<p>54で実装された大きな機能としては、Custom Elements v1でしょう。<a href="https://html5experts.jp/myakura/21074/" data-wpel-link="internal">Shadow DOM v1のとき</a>と同じように、Custom Elements仕様もベンダー間の合意をとりつけ前進した新しい仕様を「v1」と呼んでいます。現在Safariも実装を進めており、近くリリースされる新しいTechnology Previewで有効になるはずです。</p>

<p>Custom Elements v1での大きな変更点は、ES 2015のクラス構文を使いカスタム要素を定義するようになったことです。たとえば、<code>hx-element</code> というカスタム要素を定義する際には以下のようなコードで要素のコンストラクタを定義し、そのコンストラクタをもとに <code>hx-element</code> という要素名に登録します。</p>

<p></p><pre class="crayon-plain-tag">// カスタム要素のコンストラクタ
class HXElementCtor extends HTMLElement {
  // 要素が作成された段階に実行されるコールバック
  constructor () {
    super()
    // ...
  }
  // 要素がドキュメントに突っ込まれたとき
  connectedCallback () {
    // ...
  }
  // ...
}
// hx-element という名前でカスタム要素を登録
window.customElements.define('hx-element', HXElementCtor)</pre><p></p>

<p>カスタム要素のコンストラクタには、「要素が作成された」「要素がドキュメントに追加された」「属性が変更された」などの状態に応じてコードを実行するためのライフサイクルコールバックと呼ばれる関数を記述します。くわしくはチュートリアルがWeb Fundamentalsで公開されているので、そちらをどうぞ。</p>

<ul>
<li><a href="https://developers.google.com/web/fundamentals/getting-started/primers/customelements" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Custom Elements v1: Reusable Web Components</a></li>
</ul>

<h3>DevToolsのCPU Throttling</h3>

<p>DevToolsでは、CPU Throttlingがサポートされました。CPUの速度を制限し、スマートフォンなどのパワフルでない環境での処理を模した状態でタイムラインを取得できます。</p>

<p>HTML5 Experts.jpのトップページで、タイムラインを録って比較してみました。</p>

<div id="attachment_21642" style="width: 578px" class="wp-caption aligncenter"><img src="/wp-content/uploads/2016/10/Screen-Shot-2016-10-31-at-17.11.30-copy.png" width="568" height="94" class="size-full wp-image-21642" srcset="/wp-content/uploads/2016/10/Screen-Shot-2016-10-31-at-17.11.30-copy.png 568w, /wp-content/uploads/2016/10/Screen-Shot-2016-10-31-at-17.11.30-copy-300x50.png 300w, /wp-content/uploads/2016/10/Screen-Shot-2016-10-31-at-17.11.30-copy-207x34.png 207w" sizes="(max-width: 568px) 100vw, 568px" /><p class="wp-caption-text">CPU Throttlingなしのオーバービュー</p></div>

<p>通常状態では、レイアウト関連処理（紫色）が3回、JavaScript関連処理（黄色）が3回、描画関連処理が1回、チャートの上端に達しています。この状態でもCPUをけっこう専有しているようです。</p>

<div id="attachment_21643" style="width: 580px" class="wp-caption aligncenter"><img src="/wp-content/uploads/2016/10/Screen-Shot-2016-10-31-at-17.11.33-copy.png" width="570" height="94" class="size-full wp-image-21643" srcset="/wp-content/uploads/2016/10/Screen-Shot-2016-10-31-at-17.11.33-copy.png 570w, /wp-content/uploads/2016/10/Screen-Shot-2016-10-31-at-17.11.33-copy-300x49.png 300w, /wp-content/uploads/2016/10/Screen-Shot-2016-10-31-at-17.11.33-copy-207x34.png 207w" sizes="(max-width: 570px) 100vw, 570px" /><p class="wp-caption-text">“5x slowdown”を指定し制限し読み込んだもの</p></div>

<p>CPU Throttolingで5分の1に制限したものではまず、ページ読み込みに倍近くの時間がかかっています。また、レイアウト関連処理やJavaScriptの処理時間が大幅に伸びており、別れていた山がくっついてしまっています。</p>

<p>と、このような感じでCPUの性能がレンダリングに及ぼす影響を確かめられます。気をつけないといけないのが、“2x slowdown”といったように使っているコンピューターのCPUをもとにした制限になってることです。ですので特定のプロセッサをエミュレートできるわけではありません。Network Throttlingよりも「あくまで目安」度合いが高そうです。</p>

<h2>WebAssemblyがさらに進捗、ブラウザプレビュー段階に</h2>

<p>10月31日に、<a href="http://webassembly.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">WebAssembly</a>がブラウザプレビュー段階に入ったと、Mozilla, Google, Microsoftが発表しました。</p>

<ul>
<li><a href="https://hacks.mozilla.org/2016/10/webassembly-browser-preview/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">WebAssembly Browser Preview ★ Mozilla Hacks – the Web developer blog</a></li>
<li><a href="http://v8project.blogspot.jp/2016/10/webassembly-browser-preview.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">V8 JavaScript Engine: WebAssembly Browser Preview</a></li>
<li><a href="https://blogs.windows.com/msedgedev/2016/10/31/webassembly-browser-preview/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">A peek into the WebAssembly Browser Preview | Microsoft Edge Dev Blog</a></li>
</ul>

<p>WebAssemblyは<a href="https://html5experts.jp/myakura/18768/" data-wpel-link="internal">3月に各ブラウザで試験実装が入った</a>のですが、今回はWebAssemblyのバイナリフォーマットがリリース候補段階になったこと、それにSpiderMonkeyとV8のナイトリービルド、Chakraの開発版が互換性のある形で対応した旨が発表されました。バイナリフォーマットがほぼ固まったため、このブラウザプレビュー段階では幅広いフィードバックを集めたいとのことです。</p>

<p>今後のWebAssemblyですが、<a href="http://webassembly.org/roadmap/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">公開されているロードマップ</a>によると、解決に時間のかかる問題が見つからなければ2017年第1四半期にはバイナリフォーマットの初期バージョンが策定完了するとのこと。そしてその時点で、ブラウザの実装をデフォルトで有効にするようです。Firefoxは52での有効化を試みているそうです。</p>

<p>なお、発表には加わっていないものの、WebKitでも<a href="https://bugs.webkit.org/show_bug.cgi?id=159775" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">JavaScriptCoreに実装中</a>です。主要なエンジンすべてで実装されるので、ゲームや計算コストの大きなアプリケーションをWebに持ち込むのがさらに容易になりそうですね。</p>
]]></content:encoded>
		
		<series:name><![CDATA[WEB標準化動向]]></series:name>
	</item>
		<item>
		<title>Webブラウザで高速な演算を可能にする低水準言語asm.jsと、WebAssembly詳解ーJavaScript が動く仕組み</title>
		<link>/chikoski/18964/</link>
		<pubDate>Thu, 07 Jul 2016 01:35:40 +0000</pubDate>
		<dc:creator><![CDATA[清水智公]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[WebAssembly]]></category>
		<category><![CDATA[asm.js]]></category>

		<guid isPermaLink="false">/?p=18964</guid>
		<description><![CDATA[連載： 低水準言語asm.jsとWebAssembly詳解 (1)Webブラウザの上で動作するアプリを書くための言語、といえば何が想起されるでしょうか。Flash、Sliverlight、Java、さまざまな言語が利用さ...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/asmjs/" class="series-384" title="低水準言語asm.jsとWebAssembly詳解" data-wpel-link="internal">低水準言語asm.jsとWebAssembly詳解</a> (1)</div><p>Webブラウザの上で動作するアプリを書くための言語、といえば何が想起されるでしょうか。Flash、Sliverlight、Java、さまざまな言語が利用されてきましたが、やはり今のメインストリームはJavaScriptでしょう。</p>

<p>JavaScriptはさまざまな言語の特徴を併せ持つ動的言語で、Web技術の発展とAPIの整備の結果、Virtual Reality(VR)や画像認識、DAW(Desktop Audio Workstation)といった、少し前まではネイティブでの実装しかありえなかった種類のアプリケーションもWebブラウザをランタイムとするJavaScripで実装されるようになってきました。</p>

<p>そのようなアプリの代表例がゲームでしょう。少し前までのブラウザゲームといえば、リロードを繰り返すタイプのゲームか、Flashゲーム、パズルなどの簡単なものが大半を占めていたように思います。Canvasを利用して実装されたスーパマリオやNESエミュレータなどもありましたが、いずれも実験的なものであり、また20年以上前のハードウェアで快適に動くゲームだったことを考えると、CPU時間を大量に消費する「重厚」なものではありませんでした。</p>

<p>しかし最近は重厚なゲームの開発も行われ始めています。この嚆矢は<a href="http://people.mozilla.org/~vladimir/misc/bench-new/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">BananaBread</a>でしょう。これはMozillaのエンジニアチームが開発した複数同時対戦可能なFPS(First Person Shooting)です。このようなゲームの実現が可能になったのは、WebGL、Web Workers、Web Audio API、Gamepad API、IndexedDBなどに代表されるAPIの充実もありますが、既存のJavaScriptエンジンではなしえなかった高速の演算を可能にする、低水準言語の整備のおかげでもあります。</p>

<p>この連載は4回にわたって、Webブラウザ上で動作する低水準言語であるasm.jsと、（いまのところ）そのバイナリフォーマットであるWebAssemblyについて、その設計と仕様、そして開発環境を紹介します。</p>

<h2>低水準言語asm.js</h2>

<p><a href="https://asmjs.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">asm.js</a>はMozillaが研究開発したJavaScriptのサブセットで、2013年に発表されました。現在はFirefoxとGoogle Chromeによって実装が行われ、EdgeやSafariも対応を表明しています。その特徴はなんといっても動作の高速さです。次のグラフはasm.js発表時に公開されたベンチマークの結果で、棒グラフが短ければ短いほど、処理が高速であることを意味しています。このグラフによると、ベンチマークの種類にも依存しますが、概ねCやC++によるネイティブ実装の半分程度のスピードで動作していることがわかります。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/05/cppbench.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/05/cppbench.png" alt="asm.js のベンチマーク結果。ネイティブの半分程度のスピードで動作している。" class="aligncenter size-medium wp-image-18966" srcset="/wp-content/uploads/2016/05/cppbench.png 640w, /wp-content/uploads/2016/05/cppbench-300x150.png 300w, /wp-content/uploads/2016/05/cppbench-207x104.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a>
<a href="https://kripken.github.io/mloc_emscripten_talk/cppcon.html#/24" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://kripken.github.io/mloc_emscripten_talk/cppcon.html#/24</a>より引用</p>

<p>このような高速に動作を可能にしているのは、事前コンパイルと呼ばれる技術です。AOT(Ahead of Time)とも呼ばれるこの技術を利用すると、プログラムはその実行直前にコンパイルが行われ、ネイティブコードへと変換されます。ブラウザは内蔵するコンパイラでasm.jsで書かれたコードをネイティブコードに変換し、ネイティブコードを実行することで、この高速性能を実現しているのです。</p>

<p>事前コンパイルを可能とするために、asm.jsで書かれたプログラムは以下にあげる特徴を持っています。</p>

<ul>
<li>変数や式、関数の型が静的解析可能である</li>
<li>数値計算に特化している</li>
<li>作成や属性の参照、メソッド呼出といったオブジェクトに関する操作ができない</li>
<li>利用できるコレクション型はTyped Arrayのみである</li>
</ul>

<p>一般のJavaScriptやAngular、RxJSといったモダンなフレームワークの提供するDSL(Domain Specific Language)に
慣れた身からすれば、機能が制限され、「低水準な」印象が拭えません。2013年にもなって、なぜ、このような制約の強い言語が開発されたのでしょうか。もちろんJavaScript発展の文脈に基づく、実用上の要求があるためです。それを理解するに、まずJavaScriptの動作について簡単に（かつ大雑把に）振り返ることとしましょう。</p>

<h2>JavaScriptが動く仕組み</h2>

<p>プログラミング言語は「コンパイラ型」と「インタプリタ型」の2つに分けることができます。C言語やC++は前者の典型で、
後者の典型はPerlやRuby、Pythonでしょう。JavaScriptも後者に分けられます。インタプリタ型の特徴は、あるプログラムの動作に「インタプリタ」と呼ばれる別のプログラムが必要である点です。SpiderMonkey(Firefox)、Chakra(Edge)、V8(Chrome / Node.js)はJavaScript向けのインタプリタとして有名でしょう。</p>

<p>インタプリタは、文字列を解釈してプログラムとしての文法的構造を取得します。この過程を字句解析・構文解析と呼び、
結果得られた文法的な構造のことを抽象構文木(AST: Abstract Sytactic Tree)と呼びます。例えばa=1+2*3;
のASTは次のようになります。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/05/ast.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/05/ast-238x300.png" alt="a = 1 + 2 * 3;の抽象構文木" width="178" height="225" class="aligncenter size-medium wp-image-18968" srcset="/wp-content/uploads/2016/05/ast-238x300.png 238w, /wp-content/uploads/2016/05/ast-164x207.png 164w, /wp-content/uploads/2016/05/ast.png 275w" sizes="(max-width: 178px) 100vw, 178px" /></a></p>

<p>素朴なインタプリタは、この抽象構文木を枝の方から実行していきます。先ほどの例だと、まず2 * 3の計算を行い、
その結果である6で2 * 3に相当する部分木を置き換えます。その後1 + 6を計算し、最後にa = 6を計算します。この場合では、*や+、=といった演算子や標準ライブラリ中の関数などは、インタプリタ中の関数として実装され、それらをASTを解釈する巨大なswitch文の中から呼び出してプログラムは実行されます。そしてこの巨大なswitch文は、プログラムの評価が終わるまで繰り返し実行されます。</p>

<h3>仮想マシンとバイトコード</h3>

<p>このようなインタプリタはシンプルで理解しやすいのですが、変数のスコープや返り値の受け渡しの実現が困難になりがちです。そこで多くのインタプリタはASTをバイトコードに変換して実行します。バイトコードは単なるASTのバイナリ表現ではなく、インタプリタによって実装された仮想的なハードウェア（仮想マシン）を動かすマシンコード、つまり仮想的なネイティブコードとなっています。例えば(a,b,c)=&gt;a+b*cという関数は、SpiderMonkeyによって次のようなバイトコードの列に変換されます。</p>

<p></p><pre class="crayon-plain-tag">getarg 0
getarg 1
getarg 2
mul
add
return
retrval</pre><p></p>

<p>getargやmul、addなどはSpiderMonkeyの実装している仮想マシンの持つ命令です。仮想マシンには計算に使う値をスタックに保存するスタックマシンと、レジスタに配置するレジスタマシンとがありますが、SpiderMonkeyはスタックマシンを採用しており、変数への代入や、実引数の参照はスタックに対する操作として実現されています。</p>

<p>なおSpiderMonkeyの提供するバイトコードは<a href="https://developer.mozilla.org/docs/Mozilla/Projects/SpiderMonkey/Internals/Bytecode" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">こちらのサイト</a>で一覧できます。</p>

<p>バイトコードに変わったとはいえ、実行のモデルは変わりません。バイトコードを1つずつとってきては、バイトコードを解釈する巨大なswitch文を通じて、各命令を実装する関数が呼ばれます。これがプログラムの実行が終了するまで繰り返されます。</p>

<h3>型情報の不足</h3>

<p>どうせネイティブコードを出力するなら、仮想マシンのネイティブコードではなく、実マシンのネイティブコードを出力すればいいのに。そう思われるのも当然ですが、出力しない、もしくはできないのにも理由があります。それらの中で大きなものの1つが、型情報の不足です。</p>

<p></p><pre class="crayon-plain-tag">function wrap(value){
  return {value: value};
}

var b1 = wrap(1);
var b2 = wrap(2);
var result = b1.value + b2.value;</pre><p></p>

<p>resultにはどういう種類のデータが入るでしょうか？数値とすぐわかる方も多いとは思います。ではなぜ数値だとわかったのでしょうか？頭の中で上記のプログラムを実行した結果、b1.valueとb2.valueの値が両方とも数値であることがわかり、
数値同士の加算は数値になることから、resultには数値が代入されると結論づけたのではないでしょうか。</p>

<p>では、このwrapの返り値のvalue属性には常に数値が代入されているでしょうか？wrapの引数は数値でなければならない、とはどこにも書いてありません。そのため、次のような呼び出しも可能です。</p>

<p></p><pre class="crayon-plain-tag">var b3 = wrap("abcd");
var b4 = wrap({id: 1234});
var b5 = wrap(null);
var b6 = wrap(undefined);</pre><p></p>

<p>b3,b4,5,b6それぞれのvalue属性の型も、string,object,null,undefinedと異なる型になっています。
このようにJavaScriptのプログラムは実行するまで変数や演算結果の型がわからないことが多々あります。
これはプログラムの中に型の情報が含まれていないためです。
もし型情報が含まれていれば、実行しなくても変数や演算の結果の型を決められます。
型付けの強い言語の代表例であるRustを使って同様のプログラムを記述すると、次のようになります：</p>

<p></p><pre class="crayon-plain-tag">struct Box&lt;T&gt;{value: T}
fn wrap&lt;T&gt;(value:T) -&gt; Box&lt;T&gt;{
  Box{value: value}
}
fn main() {
  let b1 = wrap(1);
  let b2 = wrap(2);
  let result = b1.value + b2.value;
  println!("result = {}", result);
}</pre><p></p>

<p>このプログラムでは実行しなくても、resultの型はintであることがわかります。resultの宣言からは、型宣言を省略してあります。それでもRustの処理系は他の情報から型を決定して型を決めています。それはBoxとwrapの宣言についている型情報、そしてwrapを呼び出した際の引数から、b1.valueとb2.valueの型が決定できるためです。</p>

<p>さて型がわからないことが、ネイティブコードの出力にどのような影響を与えるのでしょうか。それは端的にいえば、出力するネイティブコードが冗長になるということです。例えばIntelのCPUの場合、加算だけでも20種類以上の命令があります。
これはデータ型と、データの保存場所によって使用する命令が異なるからです。データ型が適切に決定できているなら、使用する命令を1つに絞ることができます。</p>

<p>しかしデータ型を適切に決定できない場合、その可能性を1つずつチェックし、そのチェックした結果に合わせて使用する命令を決めるといったようなコードを出力せざるをえません。その結果コード全体は冗長になり、スピードもあまりでなくなってしまいます。ネイティブコードの出力にも時間がかかるため、その時間に見合った効果が得にくくなってしまいます。</p>

<h3>JITコンパイル</h3>

<p>ネイティブコードを出力したいが、ソースコードには型に関する情報がない。この状況を打破するために利用されている技術がJIT(Just in Time)コンパイルです。これはJavaScriptをいきなり高速に動かすためのネイティブコードに変換せず、しばらくインタプリタなどで動作させます。変数に代入される値を観察して、その型に関する統計情報を集めます。</p>

<p>この統計情報と、1つの変数には同じ種類のデータが代入される傾向にある、というヒューリスティックを利用してその変数の型を推定していきます。推定がある程度できた時点で、該当するコードからネイティブコードを出力します。このようにプログラムを動かしながら、必要に応じてネイティブコードへと出力するのがJITです。</p>

<p>SpiderMonkeyではJITは2段階に分かれています。まずはnullチェックなどを含んだ冗長なコードを出力するベースラインJIT を行います。その状態でしばらく動作させ、型情報の統計を取得します。ある程度の型情報が集まったところで、その情報を元により効率の良いコンパイルを行います。</p>

<p>図中のIon compileがそれです。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/05/jit-diagram.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/05/jit-diagram.png" alt="SpiderMonkeyにおけるJITコンパイルの流れ。" class="aligncenter size-medium wp-image-18969" srcset="/wp-content/uploads/2016/05/jit-diagram.png 640w, /wp-content/uploads/2016/05/jit-diagram-300x77.png 300w, /wp-content/uploads/2016/05/jit-diagram-207x53.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a>
<a href="https://blog.mozilla.org/luke/2014/01/14/asm-js-aot-compilation-and-startup-performance" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">asm.js AOT compilation and startup performance</a>より引用</p>

<p>型情報が集まったかどうかは実行回数によって決まっているようです。コードをざっと眺めた限り、10回程度繰り返し実行されるかどうかが、コンパイルを行うかどうかの判断の目安になっているようです。</p>

<p>上図のように、コンパイルされたコードは常に維持されるわけではありません。ときにはbail、つまりコンパイル結果を捨てて、もう一度型の推定からやり直します。これはJavaScriptの関数呼び出しに型による制約がかけられず、推定がヒューリスティックによるもののため、仕方がないことです。例えば、次のような呼び出しが行われた場合twiceのコンパイル結果は捨てられてしまいます。</p>

<p></p><pre class="crayon-plain-tag">function twice(a){
  return a + a;
}
var array = [0, 1, 2, 3, ... , 100000].map(twice);
var str = twice("こんにちは");</pre><p></p>

<p>map関数からの呼び出しによってtwiceは10000回実行されます。この途中で（正確には、行われるかどうかは処理系に依存するのですが）、twiceはnumberを引数にとり、numberを返す関数としてJITコンパイルされます。しかし次の行の引数に文字列が与えられた呼び出しによって、その結果は捨てられてしまいます。捨てないとこの処理が行えないためです。</p>

<p>TypeScriptのような型制約があればこのようなことが起きないのですが、残念ながらJavaScriptにはそれがありません。
そのため時には時間をかけて行ったコンパイル結果を捨て、低速に動くことを余儀なくされてしまいます。</p>

<h2>まとめ</h2>

<p>JITを利用することで、よく利用されるコードを高速に動作させられるようになりました。
それでも次のような問題が残っています。</p>

<ol>
<li>よく使うコードしかネイティブコードにならない</li>
<li>高速に動作するようになるまでにはリードタイムが必要</li>
<li>型の推定には失敗することがある</li>
</ol>

<p>重厚なゲームのようなアプリケーションの場合、2や3の問題は致命的なものとなりえます。</p>

<p>FPS(First Person Shooting)で対戦している場合を想像してみてください。対戦の最初はコンパイルがすんでいないため、ゲームはもっさりと動作しています。これではゲームになりません。しばらくは自分の陣地でゆっくりしてコンパイルが終わるのを待ちましょう。コンパイルが終わってFPS(Frame Per Second)が出てきました。ようやく本当のゲーム開始です。</p>

<p>そこで相手の攻撃を読み、侵攻して、草むらに潜み、相手がくるの待ち受けます。いざ相手へ攻撃をかけようとした瞬間、3に起因するコードの再コンパイルが発生し、画面がプチフリーズ。ゲームに復帰したら、目の前には銃を構える敵が…</p>

<p>こういう状況を避けるためにも、上述したような問題に対する回避策が求められました。それがAOTとasm.jsでした。AOTによって1,2の問題を回避し、その実現と3の回避のために型情報のふくまれたasm.jsが導入されることとなりました。</p>

<p>次回はasm.jsがどのように型情報を与えていくのか、型アノテーションを中心に解説します。</p>
]]></content:encoded>
		
		<series:name><![CDATA[低水準言語asm.jsとWebAssembly詳解]]></series:name>
	</item>
		<item>
		<title>WebAssembly実装プレビュー、Chrome 49新機能など─2016年3月のブラウザ関連ニュース振り返り</title>
		<link>/myakura/18768/</link>
		<pubDate>Mon, 18 Apr 2016 00:00:26 +0000</pubDate>
		<dc:creator><![CDATA[矢倉 眞隆]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[Edge]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Safari]]></category>
		<category><![CDATA[WebAssembly]]></category>
		<category><![CDATA[ブラウザ]]></category>

		<guid isPermaLink="false">/?p=18768</guid>
		<description><![CDATA[連載： WEB標準化動向 (11)2016年3月のブラウザニュースは、Chrome 49の新機能、Firefox 45とinnerText、WebAssembly実装のプレビュー、Edgeの拡張機能、Safari 9.1...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/webstandards-news/" class="series-156" title="WEB標準化動向" data-wpel-link="internal">WEB標準化動向</a> (11)</div><p>2016年3月のブラウザニュースは、Chrome 49の新機能、Firefox 45とinnerText、WebAssembly実装のプレビュー、Edgeの拡張機能、Safari 9.1リリースなどについて紹介します。</p>

<h2>Chrome 49でCSS Variablesサポート</h2>

<p>3月2日に、<a href="http://googlechromereleases.blogspot.jp/2016/03/stable-channel-update.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Chrome 49がリリース</a>されました。新機能はベータ版がリリースされた際にまとめられています。また、同じエンジンを搭載するOpera 36のリリース記事でも紹介されています。</p>

<ul>
<li><a href="http://googledevjp.blogspot.jp/2016/02/chrome-49-css-custom.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google Developers Japan: Chrome 49 ベータ版: CSS Custom Properties、Background Sync、ES2015 の新機能など</a></li>
<li><a href="https://dev.opera.com/blog/opera-36/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Dev.Opera — What’s new in Chromium 49 and Opera 36</a></li>
</ul>

<p>注目はCSS Custom Properties（通称Variables）でしょうか。プリプロセッサやポストプロセッサが持つ変数とちがい、ちゃんと継承されるというのが特徴です。これを利用し、Jake Archibaldが、<code>display</code> の値をカスタムプロパティで定義し、外部CSSが読み込まれた際に <code>block</code> に書きかえさせ段階的にCSSを読み込ませるというアイデアを披露しています。</p>

<ul>
<li><a href="https://jakearchibald.com/2016/css-loading-with-custom-props/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Control CSS loading with custom properties &#8211; JakeArchibald.com</a></li>
</ul>

<p>V8も更新され、ES2015のdestructuringとdefault parametersが使えるようになりました。また、Promiseのrejectionを検知する <a href="https://googlechrome.github.io/samples/promise-rejection-events/index.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>unhandledrejection</code> イベントおよび <code>rejectionhandled</code> イベント</a>もサポートされました。</p>

<h2>Firefox 45と innerText</h2>

<p>3月8日に、Firefox 45がリリースされました。</p>

<ul>
<li><a href="https://www.mozilla.jp/firefox/45.0/releasenotes/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Firefox 45.0 リリースノート</a></li>
</ul>

<p>ES 2015のClass構文が有効にされています。うれしいですね。</p>

<p>他には、他ブラウザとの互換性のため <a href="https://developer.mozilla.org/ja/docs/Web/API/Node/innerText" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>innerText</code> プロパティ</a>がサポートされました。要素内の「レンダリングされたテキスト」を取得するプロパティです。</p>

<p>この「レンダリング」というのが曲者です。要素内の文字列を取得するには <code>textContent</code> プロパティがありますが、こちらは「DOM要素内のテキスト」なので <code>display: none</code> などが指定された要素内のテキストももちろん返ります。いっぽう、 <code>innerText</code> はレンダリング結果を考慮するため <code>display: none</code> な要素内のテキストは結果に入りません。</p>

<p><code>innerText</code> はブラウザ拡張などで外部サイトをいじったりするときには便利だったりしますが、レイアウトを行うため<a href="http://kellegous.com/j/2013/02/27/innertext-vs-textcontent/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">パフォーマンスに影響</a>があります。単純に要素のテキストを取得したい場合は <code>textContent</code> を使いましょう。</p>

<h2>WebAssembly実装のプレビュー</h2>

<p>3月15日に、Mozilla、Google、Microsoftが、WebAssemblyの実験的なサポート状況について公開しました。WebAssemblyの試験実装は昨年から進められていますが、3ブラウザで相互運用可能な状態になったとのことです。</p>

<ul>
<li><a href="https://www.mozilla.jp/blog/entry/10539/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">WebAssembly が 1 つのマイルストーンを達成しました： 複数ブラウザによる実験的なサポートがはじまりました | Mozilla Japan ブログ</a></li>
<li><a href="http://googledevjp.blogspot.jp/2016/03/v8-webassembly.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google Developers Japan: V8 で WebAssembly を試験運用開始</a></li>
<li><a href="https://blogs.windows.com/msedgedev/2016/03/15/previewing-webassembly-experiments/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Previewing WebAssembly experiments in Microsoft Edge | Microsoft Edge Dev Blog</a></li>
</ul>

<p>FirefoxとChromeについては、NightlyやCanaryでフラグを有効にすると試せます。</p>

<p>WebAssemblyについては、中心人物のひとり、MozillaのLuke Wagner氏へのインタビューが面白いです（インタビューの場に混ぜていただきました）。インタビューが行われたMozillaのView Source Conferenceでのセッション資料も参考になります。</p>

<ul>
<li><a href="http://codezine.jp/article/detail/9072" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ハイパフォーマンスなWebを実現するasm.js／WebAssemblyとは――Mozillaのルーク・ワグナー氏に聞く：CodeZine（コードジン）</a></li>
<li><a href="http://people.mozilla.org/~lwagner/wasm-view-source/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">WebAssembly</a></li>
</ul>

<p>また、先日ポッドキャストでのインタビューも行われています。こちらもあわせてどうぞ。</p>

<ul>
<li><a href="http://chariotsolutions.com/podcast/techcast-94-luke-wagner-webassembly/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TechCast #94 &#8211; Luke Wagner on WebAssembly</a></li>
</ul>

<h2>Edgeの拡張がプレビュー版に</h2>

<p>Microsoft Edgeの拡張機能が、ついにプレビュー版に入りました。</p>

<ul>
<li><a href="https://blogs.windows.com/msedgedev/2016/03/17/preview-extensions/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Microsoft Edge extensions now available to preview | Microsoft Edge Dev Blog</a></li>
</ul>

<p>拡張は正式リリース時にはWindows Storeから追加できるようになるそうです。</p>

<p>拡張の構造はChrome拡張互換のAPIですが、現時点では本家やMozillaの<a href="https://developer.mozilla.org/ja/Add-ons/WebExtensions" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">WebExtensions</a>と少し違い、<code>chrome</code> オブジェクトが <code>browser</code> オブジェクトに変わっているそうです。ちょっと面倒ですね。</p>

<ul>
<li><a href="http://www.misuzilla.org/Blog/2016/03/21/HowToCreateExtensionForMicrosoftEdgeInsiderPreview" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Micorosoft Edge(プレビュー)の拡張を作ってみる &#8211; ぷろじぇくと、みすじら。</a></li>
<li><a href="http://www.misuzilla.org/Blog/2016/03/21/InspectExtensionPlatformOfMicrosoftEdgeInsiderPreview" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Micorosoft Edge(プレビュー)の拡張について調べる、デバッグする方法 &#8211; ぷろじぇくと、みすじら。</a></li>
</ul>

<p>サポート予定のAPIは<a href="https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/extensions/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ロードマップ</a>が公開されています。Firefox, Edge, Chromium系で（だいたい）同じコードで拡張が動くようになるのでやる気がでますね。</p>

<h2>Safari 9.1リリース、さらにTechnology Preview登場</h2>

<p>3月21日に、OS X 10.11.4とiOS 9.3がアップデートされ、Safari 9.1がリリースとなりました。WebKitのブログで新しい機能が紹介されています。</p>

<ul>
<li><a href="https://webkit.org/blog/6008/new-web-features-in-safari/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">New Web Features in Safari</a></li>
</ul>

<p>新しい機能は内部的に利用されてもいるようで、追加されたCSS Custom Propertiesを使い、Web Inspectorのコードをシンプルにした話もエントリとして公開されています。</p>

<ul>
<li><a href="https://webkit.org/blog/5989/css-variables-in-webkit/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">CSS Variables in WebKit</a></li>
</ul>

<p>さらに、3月30日、Safari Technology Previewという開発者向けのビルドが公開されました。</p>

<ul>
<li><a href="https://webkit.org/blog/6017/introducing-safari-technology-preview/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Introducing Safari Technology Preview</a></li>
</ul>

<p>Safari Technology Previewはリリース版のSafariよりも新しいWebKitを搭載したビルドで、2週間にいちど更新されます。最初のビルドではES2015のArrow Functionsやイテレータ、Web標準ではShadow DOM (v1)などが使えるようになっています。</p>

<p>なお、レンダリングエンジンのWebKitはこれまでもナイトリービルドを提供していましたが、Safari Technology Previewは独立したUIを持ち、App Storeから更新されるといった違いがあります。</p>

<p>現段階でiOS版のプレビューは提供されていませんが、<a href="https://twitter.com/grorgwork/status/715481892548513794" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">多くの人がそれを望んでるだろうとは認識している</a>とのこと。こちらのほうが出ると嬉しいので、要望をあげましょう。</p>

<p><img src="/wp-content/uploads/2016/04/yakura-3-207x161.jpg" alt="" width="207" height="161" class="aligncenter size-full wp-image-18774" /></p>
]]></content:encoded>
		
		<series:name><![CDATA[WEB標準化動向]]></series:name>
	</item>
	</channel>
</rss>
