<?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>HTML5 Conference 2015 特集 &#8211; HTML5Experts.jp</title>
	<atom:link href="/series/h5conf2015/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>HTMLとJavaScript、CSSだけで作ろう！Firefox OSアプリ</title>
		<link>/chikoski/13697/</link>
		<pubDate>Thu, 16 Apr 2015 03:00:15 +0000</pubDate>
		<dc:creator><![CDATA[清水智公]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Webアプリ]]></category>

		<guid isPermaLink="false">/?p=13697</guid>
		<description><![CDATA[連載： HTML5 Conference 2015 特集 (5)こんにちは、清水です。先日のHTML5 ConferenceでFirefox OS上で動作するアプリの開発と、Firefox Marketplaceの公開に...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/h5conf2015/" class="series-257" title="HTML5 Conference 2015 特集" data-wpel-link="internal">HTML5 Conference 2015 特集</a> (5)</div><p>こんにちは、清水です。先日のHTML5 ConferenceでFirefox OS上で動作するアプリの開発と、Firefox Marketplaceの公開に関する講演をさせていただきました。今回はその講演内容のうち、アプリ作成に関する部分を重点的に説明します。</p>

<h2>すべてWeb技術で</h2>

<p>Firefox OSの特徴は、ユーザの目にする部分は全てHTML5で実装されている点にあります。音楽アプリ、カメラ、ギャラリーといったプリインストールされているものはもちろん、ダイヤラーや、SMS、スマホのロックスクリーンや、ホーム画面といったシステムよりのアプリもすべてHTMLとJavaScript、CSSだけで実装されています。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/01-html5.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/01-html5-300x225.png" alt="Firefox OSのアプリ、UIはWeb技術のみでできています" width="300" height="225" class="aligncenter size-medium wp-image-13700" srcset="/wp-content/uploads/2015/03/01-html5-300x225.png 300w, /wp-content/uploads/2015/03/01-html5.png 640w, /wp-content/uploads/2015/03/01-html5-207x155.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<h2>Firefoxをインストールして、開発スタート</h2>

<p>Firefox OSのアプリ開発に必要なことはただ一つ、Firefoxのインストールです。開発者アカウントの作成も、ディベロッパープログラムへの登録も、専用SDKのインストールも必要ありません。</p>

<p>FirefoxにはWebIDEという機能があります。これはアプリ開発ツールとして必要な機能を一通り持っています：</p>

<ul>
<li>ファイルの作成・編集機能、シンタックスハイライト</li>
<li>デバッガ、インスペクタ</li>
<li>シミュレータの起動、</li>
<li>実機との接続管理、アプリの転送機能</li>
</ul>

<p>リリース版のFirefoxでも十分開発に耐えますが、開発をするなら <a href="https://www.mozilla.org/firefox/developer/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Firefox Developer Edition</a>の利用をお勧めします。Mozillaの提供する開発者向けの機能をいち早く利用できる点が特徴です。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/02-fireox-developer-edition.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/02-fireox-developer-edition-300x210.png" alt="Firefox Developer Editionの起動画面" width="300" height="210" class="aligncenter size-medium wp-image-13699" srcset="/wp-content/uploads/2015/03/02-fireox-developer-edition-300x210.png 300w, /wp-content/uploads/2015/03/02-fireox-developer-edition.png 640w, /wp-content/uploads/2015/03/02-fireox-developer-edition-207x145.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>Firefox Developer Editionは、リリース版とは異なる場所にインストールされます。また初回起動時に開発用のプロファイルを作成するため、リリース版との併用が可能です。<a href="https://mozilla.org/firefox/sync/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Firefox Sync</a>を利用して同期しておけば、ブックマークや履歴、パスワードは通常利用しているものと共有できます。</p>

<h2>Hello World!</h2>

<p>ではさっそく、WebIDEを利用してHello Worldしてみましょう。Firefoxのメニューから「Web 開発」→「Web IDE」と進んでWeb IDEを起動します。起動すると次のような画面が表示されます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/04-webide.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/04-webide-300x241.png" alt="04-webide" width="300" height="241" class="aligncenter size-medium wp-image-14196" srcset="/wp-content/uploads/2015/03/04-webide-300x241.png 300w, /wp-content/uploads/2015/03/04-webide.png 640w, /wp-content/uploads/2015/03/04-webide-207x167.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>画面の左上にある「アプリを開く」をクリックすると展開されるメニューから「新規アプリ」を選びます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/05-newapp.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/05-newapp-300x145.png" alt="05-newapp" width="300" height="145" class="aligncenter size-medium wp-image-14197" srcset="/wp-content/uploads/2015/03/05-newapp-300x145.png 300w, /wp-content/uploads/2015/03/05-newapp.png 640w, /wp-content/uploads/2015/03/05-newapp-207x100.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>選ぶとテンプレートの選択を求められます。「HelloWorld」テンプレートを選び、プロジェクト名にアプリの名前を入力して、「OK」ボタンを押すとアプリのテンプレートが作成されます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/06-helloworld.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/06-helloworld-300x232.png" alt="HelloWorldテンプレートを利用して新規にアプリを作成する例" width="300" height="232" class="aligncenter size-medium wp-image-14198" srcset="/wp-content/uploads/2015/03/06-helloworld-300x232.png 300w, /wp-content/uploads/2015/03/06-helloworld.png 640w, /wp-content/uploads/2015/03/06-helloworld-207x160.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<h2>シミュレータのインストール</h2>

<p>次にシミュレータをインストールします。シミュレータはブラウザのアドオンとして提供されています。画面右上のメニューから「シミュレータをインストール」を選び、表示された画面の中から開発を行う Firefox OSのバージョンに合わせたシミュレータをインストールします。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/07-simulator-installation.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/07-simulator-installation-300x232.png" alt="シミュレータのインストール画面" width="300" height="232" class="aligncenter size-medium wp-image-14199" srcset="/wp-content/uploads/2015/03/07-simulator-installation-300x232.png 300w, /wp-content/uploads/2015/03/07-simulator-installation.png 640w, /wp-content/uploads/2015/03/07-simulator-installation-207x160.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>KDDIから販売されているFirefox OS端末、Fx0はFirefox OS 2.0で動作しています。国内向けにアプリを書く場合は、Firefox OS 2.0のシミュレータをインストールするとよいでしょう。</p>

<h2>アプリの起動と修正の反映</h2>

<p>作成したテンプレートを、インストールしたシミュレータ上で実行します。WebIDE上部にある「実行ボタン」を押すと、実行できます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/08-app-execution.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/08-app-execution-300x75.png" alt="08-app-execution" width="300" height="75" class="aligncenter size-medium wp-image-14200" srcset="/wp-content/uploads/2015/03/08-app-execution-300x75.png 300w, /wp-content/uploads/2015/03/08-app-execution.png 640w, /wp-content/uploads/2015/03/08-app-execution-207x52.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>実行すると、次のような画面が表示されます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/09-helloworld.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/09-helloworld-180x300.png" alt="09-helloworld" width="180" height="300" class="aligncenter size-medium wp-image-14201" srcset="/wp-content/uploads/2015/03/09-helloworld-180x300.png 180w, /wp-content/uploads/2015/03/09-helloworld.png 385w, /wp-content/uploads/2015/03/09-helloworld-125x207.png 125w" sizes="(max-width: 180px) 100vw, 180px" /></a></p>

<p>このテンプレートでは、起動時にindex.htmlが表示されます。これを次のように修正します。</p>

<p></p><pre class="crayon-plain-tag">&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8"&gt;
    &lt;meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1"&gt;
    &lt;title&gt;Hello World&lt;/title&gt;
    &lt;link rel="stylesheet" href="app.css"&gt;
    &lt;script src="app.js" defer&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h1&gt;こんにちは世界！&lt;/h1&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre><p></p>

<p>また、app.jsを次のように修正すると、アプリのロードが終了した時点でアラートダイアログが表示されます。</p>

<p></p><pre class="crayon-plain-tag">window.addEventListener("load", function() {
  alert("Hello World!");
});</pre><p></p>

<p>WebIDEの実行ボタンをもう一度押すと、これらの修正が実行中のアプリに反映されます。</p>

<h2>アプリの構造</h2>

<p>テンプレートに従って作成されるファイルは以下のような構造をしています。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/03-files-of-helloworld.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/03-files-of-helloworld-300x251.png" alt="Hello World テンプレートによって展開されたファイル" width="300" height="251" class="aligncenter size-medium wp-image-13698" srcset="/wp-content/uploads/2015/03/03-files-of-helloworld-300x251.png 300w, /wp-content/uploads/2015/03/03-files-of-helloworld-207x173.png 207w, /wp-content/uploads/2015/03/03-files-of-helloworld.png 600w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>HTMLやJavaScriptに加えて、&#8221;manifest.webapp&#8221;というファイルがあります。これはアプリに関するメタデータで、これはアプリのインストールや、Mozillaの提供するアプリストアであるFirefox Maretplaceにアプリを登録時に参照されます。</p>

<p>manifest.webappの実体は次のようなJSONファイルです。</p>

<p></p><pre class="crayon-plain-tag">{
  "name": "こんにちは世界",
  "description": "A Hello World app",
  "launch_path": "/index.html",
  "icons": {
    "16": "/icons/icon16x16.png",
    "48": "/icons/icon48x48.png",
    "60": "/icons/icon60x60.png",
    "128": "/icons/icon128x128.png"
  },
  "type": "privileged",
  "permissions": {}
}</pre><p></p>

<p>各項目の詳細については、<a href="https://developer.mozilla.org/Apps/Manifest" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Mozilla Developer Networkのアプリマニフェスト</a>
をご覧いただくのが確実ですが、上記の例にある項目は以下のような意味を持ちます。</p>

<table>
<thead>
<tr>
  <th>項目名</th>
  <th>説明</th>
</tr>
</thead>
<tbody>
<tr>
  <td>name</td>
  <td>人間が読むための、アプリ名。最長 128 文字</td>
</tr>
<tr>
  <td>description</td>
  <td>人間のためのアプリ説明文。最長 1024 文字</td>
</tr>
<tr>
  <td>launch_path</td>
  <td>アプリ起動時に読み込まれるHTMLファイルのパス。上記の例では、manifest.webappと同じフォルダにあるindex.htmlが読み込まれる</td>
</tr>
<tr>
  <td>icons</td>
  <td>アイコンのリスト。128ピクセルx128ピクセルのアイコンは必須。また 512ピクセルx512ピクセルのものも含めることが推奨されている</td>
</tr>
<tr>
  <td>type</td>
  <td>アプリの種別。特権アプリの場合は、privilegedと記入する。一般アプリの場合は省略可能だが、明示する場合はwebと記入する</td>
</tr>
<tr>
  <td>permissions</td>
  <td>Camera APIやDevice Storage APIのように、注意が必要なAPIを利用する場合は、ここに列挙する</td>
</tr>
</tbody>
</table>

<p>以上のように、HTML、CSS、JavaScriptにmanifest.webappを足したものが、Firefox OSアプリの最小構成となります。</p>

<h2>Firefox OS で利用できる API</h2>

<p>Firefox OS のアプリは、すべてJavaScriptで記述します。そのため カメラやGPSといったセンサー類へのアクセスや、バイブのコントロール、SDカードへのデータ保存などは、HTML5で利用できるAPIを通して行います。利用できるAPIの一部分を挙げると、以下のようになります。</p>

<ul>
<li>Ambient Light Sensor API：環境光センサーを利用して周囲の照度を取得できる</li>
<li>Geolocation API：端末の物理的な位置を取得できる</li>
<li>Vibration API：ゲームなどのフィードバックのために、バイブレーションをコントロールできる</li>
<li>Camera：デバイスに内蔵されたカメラを利用して動画や、写真を撮影できる</li>
<li>Contacts：連絡先データベースへのアクセスが可能になる</li>
<li>Device Storage：SD カードなど、端末の持つストレージに対して読み書きが行える</li>
</ul>

<p>例えばDevice Storage APIを利用して、SDカード中のファイルをすべてコンソールに出力するプログラムは、次のようになります。</p>

<p></p><pre class="crayon-plain-tag">var sdcard = navigator.getDeviceStorage("sdcard");
var cursor = sdcard.enumerate();
cursor.onsuccess = function(){
  var file = this.result;
  console.log(file.name);
  if(!this.done){
    this.continue();
  }
};</pre><p></p>

<h2>WebActivities：アプリの機能を利用する API</h2>

<p>音楽のライブラリや、写真のギャラリー、カメラでの撮影といった機能を実装する方法は2つあります。1つは上記にあげたAPIを利用して1から機能を作る方法、もう1つはWebActivitiesを利用して他のアプリを呼び出す方法です。</p>

<p>標準でインストールされている音楽アプリや、ギャラリー、カメラアプリは、「ライブラリから音楽の選択する」「ギャラリーから写真を選ぶ」「写真を撮る」といったアプリの機能の一部を他のアプリから利用できるようになっています。</p>

<p>これを利用しているアプリの例には、<a href="https://marketplace.firefox.com/app/cameran" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Cameran</a> があります。Cameranは写真にフィルタや効果を追加するアプリなのですが、自分で写真撮影や管理機能を実装しているのではなく、インストールされている他のアプリの提供する「画像を選ぶ機能」を利用しています。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/10-webactivities.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/10-webactivities-169x300.png" alt="10-webactivities" width="169" height="300" class="aligncenter size-medium wp-image-14203" srcset="/wp-content/uploads/2015/03/10-webactivities-169x300.png 169w, /wp-content/uploads/2015/03/10-webactivities.png 360w, /wp-content/uploads/2015/03/10-webactivities-116x207.png 116w" sizes="(max-width: 169px) 100vw, 169px" /></a></p>

<p>他のアプリが提供している機能を、自分のアプリから呼び出して利用するためのAPIが、WebActivitiesです。例えば、他のアプリが提供するJPEG形式の画像を選択する機能の呼び出しは、次のようにWebActivitiesを利用して実現できます。</p>

<p></p><pre class="crayon-plain-tag">var activity = new MozActivity({
  name: "pick",
  data: {
    type: "image/jpeg"
  }
});
activity.onsuccess = function() {
  var picture = this.result;
  console.log("A picture has been retrieved");
};</pre><p></p>

<p>尚、WebActivitiesを利用して呼び出せるのは機能の名前であって、アプリではありません。おなじ名前の機能が複数のアプリから提供されている場合、どのアプリを利用するかはユーザの選択に任されます。</p>

<p>WebActivitiesの詳細、特に標準でインストールされているシステムアプリが提供する機能名については、<a href="https://developer.mozilla.org/docs/Web/API/Web_Activities" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Mozilla Developer Network の Web アクティビティ</a>をご覧ください。</p>

<h2>アプリケーションの権限</h2>

<p>上記のAPIすべてを、アプリから利用できるわけではありません。強力なAPIの利用には、それに見合った権限が必要となります。</p>

<p>Firefox OSのアプリは権限に応じて次の3つに分類されます。</p>

<ul>
<li>一般のアプリ (type:web)</li>
<li>特権アプリ (type: privileged)</li>
<li>内部アプリ (type: certified / internal)</li>
</ul>

<p>最後の内部アプリ、以前は認定アプリ (Certified App)と呼ばれていたアプリは、キャリアもしくはそれに準じるベンダしか作成を許されていません。そのため私たちが作成するアプリは、一般アプリもしくは特権アプリのどちらかになります。</p>

<p>権限と、利用できるAPIの対応関係は、OSのバージョンによって異なります。対応関係はWebIDEの「許可設定一覧」で確認できます。</p>

<p>許可設定一覧は以下のようになっています。</p>

<p>✓は利用可能、✕ は不可能、! は利用可能だが利用時にユーザに対して通知されることを表しています。</p>

<p>以下の例では、Camera APIを利用するためには、アプリを特権アプリとしなければならないことがわかります。</p>

<table>
<thead>
<tr>
  <th>名前</th>
  <th>type:web</th>
  <th>type:privileged</th>
</tr>
</thead>
<tbody>
<tr>
  <td>geolocation</td>
  <td>!</td>
  <td>!</td>
</tr>
<tr>
  <td>camera</td>
  <td>✕</td>
  <td>!</td>
</tr>
<tr>
  <td>alarms</td>
  <td>✓</td>
  <td>✓</td>
</tr>
</tbody>
</table>

<h2>実際に作ってみよう</h2>

<p>以上がFirefox OSアプリの概要でした。これを踏まえて、ボイスレコーダーアプリの作成を例に、アプリの作成例をみてみましょう。</p>

<p>今回作成するアプリは次のような1画面のアプリとなります。画面をタップすると録音を開始し、もう1度のタップで録音を終了します。録音した音声は ogg ファイルとして音楽ライブラリに保存されるものとします。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/11-recorder.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/11-recorder-169x300.png" alt="作成するボイスレコーダーアプリの実行画面" width="169" height="300" class="aligncenter size-medium wp-image-14202" srcset="/wp-content/uploads/2015/03/11-recorder-169x300.png 169w, /wp-content/uploads/2015/03/11-recorder.png 360w, /wp-content/uploads/2015/03/11-recorder-116x207.png 116w" sizes="(max-width: 169px) 100vw, 169px" /></a></p>

<p>なお今回作成したサンプルは、 <a href="https://gist.github.com/chikoski/00bbcb2cff65293869a0" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">gist</a>で公開しています。
こちらもご利用ください。</p>

<h2>使用するAPIとアプリの権限</h2>

<p>今回は次のAPIを利用します。</p>

<table>
<thead>
<tr>
  <th>API名</th>
  <th>目的</th>
  <th>Firefox OS 2.0で必要な権限</th>
</tr>
</thead>
<tbody>
<tr>
  <td>GetUserMedia</td>
  <td>マイクからの音声入力を扱うため</td>
  <td>通常</td>
</tr>
<tr>
  <td>MediaRecorderAPI</td>
  <td>音声を録音するため</td>
  <td>通常</td>
</tr>
<tr>
  <td>Web Audio API</td>
  <td>音声の分析を行うため</td>
  <td>通常</td>
</tr>
<tr>
  <td>DeviceStorage API</td>
  <td>音声をファイルとして保存するため</td>
  <td>特権</td>
</tr>
</tbody>
</table>

<p>DeviceStorage APIを利用するためには、アプリの種別を特権アプリとする必要があります。またいくつかのAPIを利用するためには、manifest.webappのpermissionsの項目に記述を行う必要があります。そのため manifest.webappを以下のように記述します。typeと permissionsの項目が、それぞれ設定されていることを確認してください。</p>

<p></p><pre class="crayon-plain-tag">{
  "name": "audio-caputre-sample",
  "description": "An sample app to capture audio through microphone",
  "launch_path": "/index.html",
  "icons": {
    "16": "/icons/icon16x16.png",
    "48": "/icons/icon48x48.png",
    "60": "/icons/icon60x60.png",
    "128": "/icons/icon128x128.png"
  },
  "type": "privileged",
  "permissions": {
    "audio-capture": {
      "description": "To record audio"
    },
    "device-storage:music": {
      "description": "To store captured audio",
      "access": "readwrite"
    }
  }
}</pre><p></p>

<h2>HTML と CSS の記述</h2>

<p>アプリのビューは HTML と CSS で定義します。今回のアプリでは次のものを利用しました。</p>

<p></p><pre class="crayon-plain-tag">&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8"&gt;
    &lt;meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1"&gt;
    &lt;title&gt;audio capture test&lt;/title&gt;
     &lt;script src="app.js" defer&gt;&lt;/script&gt;
    &lt;link rel="stylesheet" href="app.css"&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;canvas id="canvas"&gt;&lt;/canvas&gt;
    &lt;p id="recording"&gt;●REC&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre><p></p>

<p>CSS は以下のようになっています。</p>

<p></p><pre class="crayon-plain-tag">body{
   margin: 0;
   padding: 0;
 }
 #canvas{
   width: 100%;
   height: 400px;
   margin: 0;
   padding: 0;
   box-sizing: border-box;
 }
 #recording{
   color: red;
   position: fixed;
   top: .5em;
   left: .5em;
   display: none;
 }</pre><p></p>

<h2>JavaScript を使った録音</h2>

<p>コードの全体像は <a href="https://gist.github.com/chikoski/00bbcb2cff65293869a0" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">gist に公開したもの</a>をご覧いただくこととして、
ここではマイクからの入力ストリームの取得、録音、そしてファイルへの出力部分について解説します。</p>

<p>まずは、マイクからの入力ストリームの取得方法です。manifest.webapp中のpermissionsの項目に&#8221;audio-capture&#8221;を追加すると、
つぎのようにGetUserMediaを使っ、てマイクからの入力を扱うための入力ストリームを取得できます。</p>

<p></p><pre class="crayon-plain-tag">navigator.getUserMedia({video: false, audio: true}, 
                       streamAquired, 
                       error =&gt;{
                         console.log(error);
                       });</pre><p></p>

<p>この実行が成功すると、コールバック関数が呼ばれます。取得した入力ストリームは、関数の第1引数として与えられます。上記の例では streamAquired という関数が呼ばれます。この関数は入力ストリームを利用する様々なオブジェクトの初期化を行います。</p>

<p>ここで初期化されるオブジェクトの中には MediaRecorder オブジェクトがあります。初期化は次の様に行われています。</p>

<p></p><pre class="crayon-plain-tag">var initRecorder = function(stream){
  recorder = new MediaRecorder(stream);
  recorder.ondataavailable = (event) =&gt; {
    console.log(event); 
    if(storage != null){
      var filename = createFileName(event);
      console.log("attempt to save as " + filename);
      var req = storage.addNamed(event.data, filename);
      req.onsuccess = function(){
        console.log("saved as " + this.result);
      };
      req.onerror = function(){
        console.log(this.error.name);
      };
    }
  };
};</pre><p></p>

<p>MediaRecorderオブジェクトは、その名の通りメディアデータの記録を行うオブジェクトです。startメソッドを実行すると記録を開始し、stopメソッドを実行すると記録を停止し、記録したデータを用意します。データの用意できると、dataavailableイベントが発生します。用意されたデータは、dataavailableのdata属性でBlobとして参照できます。</p>

<p>上記の例では取得したBlobオブジェクトを、DeviceStorage APIのaddNamedメソッドを使って保存をしています。ここで利用しているstorageオブジェクトは次の様に作成されています。</p>

<p></p><pre class="crayon-plain-tag">var storage = navigator.getDeviceStorage("music");</pre><p></p>

<p>これは音楽データ用のストレージを取得しています。取得できるストレージの種類は次の4種類です。これ以外にもappsというアプリ用ストレージがありますが、これはシステムアプリからのみアクセスが許可されており、我々の作成するアプリは操作できません。</p>

<table>
<thead>
<tr>
  <th>ストレージ名</th>
  <th>役割</th>
</tr>
</thead>
<tbody>
<tr>
  <td>music</td>
  <td>音楽データ用ストレージ</td>
</tr>
<tr>
  <td>pictures</td>
  <td>写真データ用ストレージ</td>
</tr>
<tr>
  <td>videos</td>
  <td>動画データ用ストレージ</td>
</tr>
<tr>
  <td>sdcard</td>
  <td>汎用データストレージ</td>
</tr>
</tbody>
</table>

<p>取得したストレージに対してメソッド呼び出しを行うと、DOMRequestオブジェクトを返します。このオブジェクトのonsuccess属性やonerror属性に関数を登録することで、その操作が成功したか、失敗したかを知ることができます。上記の例では単に成否をログに出力しているだけですが、エラー処理が必要な場合などは、こちらにその処理を記述することになります。</p>

<h2>気軽に作ろう！</h2>

<p>以上 Firefox OSアプリの構成と作成方法について概観しました。</p>

<p>Firefox OSに向けたアプリの作成についてまとめると、次の3点になるかと思います。</p>

<ul>
<li>Firefoxがあれば開発をはじめられる</li>
<li>Firefox OSアプリ = HTML + JS + CSS + manifest.webapp </li>
<li>ライブラリの追加なしで、ハードウェアをコントロールできる</li>
</ul>

<p>とにかく開発を始めるための敷居が低く、HTMLや CSS、JavaScriptといったWeb標準技術のみで、ハードウェアへアクセスし、コントロールするようなアプリが作れます。</p>

<p>しかもブラウザエンジンがOSに組み込まれているため、作成したアプリのコンパイルやビルドが必要ありません。Webページを作るように、修正したアプリを再読み込みして即座に実行できます。また本文中では解説しませんでしたが、実機へのアプリの転送やデバッグもシミュレータと同様の手順で行えます。</p>

<p>このように開発の敷居が低く、簡単にアプリを作り始められるFirefox OSで、みなさんも作る自由を謳歌してください。</p>

<p>当日のセッションの動画・スライドは、こちらからご覧ください。</p>

<div class="aligncenter">

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

</div>

<p><a href="https://www.youtube.com/watch?v=zi4u7eMfmKY" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Youtube</a> /
<a href="http://www.slideshare.net/chikoski/firefox-os-43867933" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Slideshare</a></p>

<h2>参考資料</h2>

<ul>
<li><a href="https://www.mozilla.org/firefox/developer" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Firefox Developer Edition</a></li>
<li><a href="https://mozilla.org/firefox/os/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Firefox OS</a></li>
<li><a href="https://developer.mozilla.org/Apps" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Mozilla Developer Networkのアプリセンター</a></li>
<li><a href="https://developer.mozilla.org/docs/WebAPI" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">WebAPI</a></li>
<li><a href="https://developer.mozilla.org/docs/Web/API/Navigator/getUserMedia" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">GetUserMedia</a></li>
<li><a href="https://developer.mozilla.org/docs/Web/API/Device_Storage_API" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">DeviceStorage API</a></li>
<li><a href="https://developer.mozilla.org/docs/Web/API/MediaRecorder_API" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">MediaRecorder API</a></li>
<li><a href="https://developer.mozilla.org/docs/Web/API/Web_Audio_API" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Audio API</a></li>
<li><a href="https://developer.mozilla.org/Apps/Manifest" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">アプリマニフェスト</a></li>
</ul>
]]></content:encoded>
		
		<series:name><![CDATA[HTML5 Conference 2015 特集]]></series:name>
	</item>
		<item>
		<title>昨今のCSS設計事情からみるCSS設計のあり方とは</title>
		<link>/hiloki/14372/</link>
		<pubDate>Wed, 15 Apr 2015 00:00:23 +0000</pubDate>
		<dc:creator><![CDATA[谷拓樹]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Web Components]]></category>
		<category><![CDATA[マークアップ]]></category>

		<guid isPermaLink="false">/?p=14372</guid>
		<description><![CDATA[連載： HTML5 Conference 2015 特集 (4)本記事は2015年1月に開催されたHTML5 Conferenceでお話させていただいた、 「Beyond CSS Architecture」というCSS設...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/h5conf2015/" class="series-257" title="HTML5 Conference 2015 特集" data-wpel-link="internal">HTML5 Conference 2015 特集</a> (4)</div><p>本記事は2015年1月に開催された<a href="http://events.html5j.org/conference/2015/1/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML5 Conference</a>でお話させていただいた、
「Beyond CSS Architecture」というCSS設計のセッションをフォローアップする記事です。</p>

<p>本記事では、このセッションの概要と補足、またセッション中に説明できなかった点などについて書いていきます。</p>

<p><img src="/wp-content/uploads/2015/04/beyondcssarchitecture.jpg" alt="" width="500" height="373" class="aligncenter size-full wp-image-14555" srcset="/wp-content/uploads/2015/04/beyondcssarchitecture.jpg 500w, /wp-content/uploads/2015/04/beyondcssarchitecture-300x224.jpg 300w, /wp-content/uploads/2015/04/beyondcssarchitecture-207x154.jpg 207w" sizes="(max-width: 500px) 100vw, 500px" /></p>

<p>※当日のセッションの動画・スライドも公開されているので、文末からご覧ください。</p>

<h2>CSSの難しさと、昨今のCSS設計事情</h2>

<p>この近年、CSSにおける設計論というのが話題に出てくるようになりました。筆者も拙著『<a href="http://www.amazon.co.jp/gp/product/4844336355" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web制作者のためのCSS設計の教科書</a>』を書いたり、各地でCSS設計をテーマとした講演をする機会が多くありました。</p>

<p>CSSの難しさというのは、<a href="https://html5experts.jp/t32k/13504/" data-wpel-link="internal">石本氏によるCSSコードの評価についての記事</a>にも書かれているのですが、CSSは良くも悪くも厳格なコード規約は少なく、ただ宣言的に書けばいいだけです。セレクタとその詳細度や、後出しされたルールの方が優先されるという、シンプルがゆえに「書く」のは簡単ですが、「直す」のは容易ではありません。</p>

<p>Normalize.cssの作者であり、現在Twitterのエンジニアであるニコラス・ギャラガー氏（<a href="https://twitter.com/necolas" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">@necolas</a>）のツイートを引用するならば、次のように考えられるかどうかです。</p>

<blockquote>
  <p>Replace &quot;can you build this?&quot; with &quot;can you maintain this without losing your minds?&quot;<br>
  &mdash; <a href="https://twitter.com/necolas/status/360170108028600320" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Nicolas Gallagher (@necolas) </a></p>
</blockquote>

<p><br></p>

<p>複数人のチームでの開発はもちろんですが、自分のひとりの開発であったとしても、いざメンテナンスするとなったときに、数日前に自分が書いたCSSを呪うようなことはよくあります。</p>

<p>中長期的に運用されるWebサイト、Webサービスにおいては、その運用に耐えうるメンテナブルかつ、拡張性のあるCSSを書くことは非常に重要です。
こうしたCSS設計の話題が以前よりも見かけるようになったのは、単純な数ページのWebサイトよりも、少しリッチで複数のテンプレートが必要なWebサイト、Webサービスが増えてきていることもあり、メンテナブルなCSSにするための設計とは何か、というのが求められているからかもしれません。</p>

<h2>OOCSSとBEM</h2>

<p>セッション内でも取り上げている<a href="https://github.com/stubbornella/oocss/wiki" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">OOCSS</a>と<a href="https://en.bem.info/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">BEM</a>は、CSS設計を考える上で避けられない方法論のひとつです。</p>

<p>OOCSSは、ページ上で繰り返されるビジュアルパターンをオブジェクトと考え、そのオブジェクトはHTML/CSSまたはJavaScriptのコードの固まりで構成されます。それはボタンやリスト、見出しというような単位であったり、場合によってはただ文字色を赤くするためのものかもしれません。こうした作られた小さなオブジェクトをレゴのように組み合わせてUIを作るというのが、OOCSSの基本的なアプローチです。</p>

<p>BEMは、Yandexという会社のフロントエンド開発チームによって考えられた開発手法です。BEMはUIをBlock,Element,Modifierという分類で設計するのですが、BEMで使われている命名規則とその記法が特徴的で、Blockを名前空間として使うのが良いアイデアとされています。</p>

<p></p><pre class="crayon-plain-tag">.menu { ... } /* Block */
.menu__item { ... } /* Block + Element */
.user { ... } /* Block */
.user_login { ... } /* Block + Modifier */
.user__avatar { ... } /* Block + Element */
.user__name { ... } /* Block + Element */</pre><p></p>

<p>このコード例では<code>.menu</code>がBlockの単位となり、またそれがセレクタの接頭辞にすることで、マークアップ上でつけられたクラス名を見るだけで、どのUI（Block）に依存するものかが分かります。例えば<code>class="item"</code>だと抽象的すぎて何に依存しているかわかりませんが、<code>.menu__item</code>であれば分かる、ということです。</p>

<p>また<code>_</code>、<code>__</code>の記号の組み合わせは、設計上のルールとして、単語間がどういう関係性を持つのかを明確にしています。<code>__</code>は一見冗長で、普通に名前をつけるときには使わなそうですが、それが良い意味でただの命名ではなく、デリミタ（区切り）として使われているということです。</p>

<p>このBEMのアプローチの細かなルールは必ずしもオリジナルのBEMに倣っているものばかりではなく、<a href="http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">MindBEMding</a>のような独自のルールで運用されることもあります。筆者の<a href="https://github.com/hiloki/flocss" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">FLOCSS</a>も、いろいろなものを参考にして作成したものです。</p>

<h2>モダンなCSS設計の誤解</h2>

<p>OOCSS、BEMについて言及される記事を見ると、これらやCSS設計における大きな誤解を招いていると感じることがあります。</p>

<p>OOCSS派か、BEM派か、というような表現も見かけますが、多くの場合、OOCSSは複数のクラスを組み合わせるアプローチ、BEMは単一クラスのアプローチ、というような解釈をされているようです。</p>

<p>OOCSSが体系化された当時にはSassのようなメタ言語もなく、OOCSSを実現するためには複数のクラスを組み合わせるアプローチが適切だったというだけでしょう。事実、彼女自身が<a href="https://www.youtube.com/watch?v=GhX8iPcDSsI" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">&#8220;OOCSS and Preprocessors in a tree, K-I-S-S-I-N-G&#8221;</a>という講演で、OOCSSとSassを組み合わせたアプローチについて述べています。</p>

<p>また提唱者であるニコール・サリバン氏が関わったプロジェクトにおいては、<code>font-size</code>という単位でもオブジェクトとして分解することが、数百と宣言される<code>font-size</code>プロパティを、たった数個のクラスで管理することに意味がありました。</p>

<p>ただそのいくつかの例が拡大解釈され、<code>.red {color: red;}</code>や<code>.large {font-size: 36px}</code>というような、見た目だけの、コンテンツ派生の意味をもたないクラスを複数組み合わせるアプローチがOOCSSである、と考えられることは少なくありません。</p>

<p>しかし、OOCSSの本質は、現在のHTML/CSSでは難しいモジュラーなアプローチを実践するためのパラダイムである、と筆者は考えています。</p>

<p>一方、BEMについてもいくつかの誤解があるように感じています。Block、ElementあるいはModifierとしての命名と設計は、マークアップを見て、その構造をセレクタにするものではありません。</p>

<p></p><pre class="crayon-plain-tag">&lt;nav class="globalNav"&gt;
  &lt;ul&gt;
    &lt;li&gt;
      &lt;a href="/home"&gt;Home&lt;/a&gt;
    &lt;/li&gt;
    &lt;!-- more --&gt;
  &lt;/ul&gt;
&lt;/nav&gt;</pre><p></p>

<p>例えばこのようなマークアップがあった時に、その構造を意識してしまい、次のようなCSSにしてしまうことがあります。</p>

<p></p><pre class="crayon-plain-tag">&lt;nav class="globalNav"&gt;
  &lt;ul class="globalNav__menu"&gt;
    &lt;li class="globalNav__menu__item"&gt;
      &lt;a href="/home"&gt;Home&lt;/a&gt;
    &lt;/li&gt;
    &lt;!-- more --&gt;
  &lt;/ul&gt;
&lt;/nav&gt;</pre><p></p>

<p>極端な例ではありますが、近いコードを見ることはあるのではないでしょうか。こうなってしまうと、BEMが冗長すぎる、気持ちが悪い、というのは素直な感情だともいえます。</p>

<p>しかし本来のBEMらしい考え方であれば、このようなマークアップを元にセレクタに命名するものではなく、UIをBlock,Element,Modifierのツリー構造で考え、それが名前にも与えられるものです。</p>

<p>この例でいえば、<code>globalNav</code>をBlockとするならば、それを構成する要素は次のようになるかもしれません。</p>

<p></p><pre class="crayon-plain-tag">&lt;nav class="globalNav"&gt;
  &lt;ul class="globalNav__menu"&gt;
    &lt;li class="globalNav__menuItem"&gt;
      &lt;a href="/home"&gt;Home&lt;/a&gt;
    &lt;/li&gt;
    &lt;!-- more --&gt;
  &lt;/ul&gt;
&lt;/nav&gt;</pre><p></p>

<p>そもそも、もっと小さな単位にするべきかもしれません。</p>

<p></p><pre class="crayon-plain-tag">&lt;nav class="globalNav"&gt;
  &lt;ul class="globalNav__menu menu"&gt;
    &lt;li class="menu__item"&gt;
      &lt;a href="/home" class="menu__target"&gt;Home&lt;/a&gt;
    &lt;/li&gt;
    &lt;!-- more --&gt;
  &lt;/ul&gt;
&lt;/nav&gt;</pre><p></p>

<p>どちらが正しいかというものではなく、その時々で適切な命名や分割があるはずですが、少なくともマークアップの構造をなぞって親子関係を命名で表すのが、BEMの命名規則というわけではありません。</p>

<p>最後の例を見ての通り、BEMの記法であっても、複数のBlockとElement、つまりはそれぞれはOOCSS的にいえばオブジェクトであり、組み合わせによって作られるわけです。</p>

<p>つまり、OOCSS派かBEM派かという天秤があるわけではありませんし、思想として良いところを取り入れて、プロジェクトに適切な方法論、設計を考えることが重要です。</p>

<p>逆にいえば、これらは<a href="http://ja.wikipedia.org/wiki/%E9%8A%80%E3%81%AE%E5%BC%BE%E3%81%AA%E3%81%A9%E3%81%AA%E3%81%84" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">銀の弾丸</a>というわけでもありませんから、OOCSSやBEMがすべての問題を解決するわけでもありません。プロジェクトの規模やその運用の方向性によっては、もっと単純な規約のもとでCSSが書かれていても構いません。</p>

<p>いずれの場合も、そのプロジェクト内において一貫性が保たれていることのほうが大事で、<a href="https://github.com/necolas/idiomatic-css" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ideomatic CSS</a>から引用するならば、次のようなことです。</p>

<blockquote>
  <p>どんなに多くの人が貢献したとしても、どのコードも一人で書いたようにすること。<br>
  &mdash; <a href="https://github.com/necolas/idiomatic-css" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ideomatic CSS</a></p>
</blockquote>

<p>セッションで紹介しているツール、スタイルガイドや<a href="http://www.stylestats.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">StyleStats</a>のようなツールは、一貫性を保ったCSSを書くための補助となるものです。</p>

<p>これらもまたツールでしかなく、導入しただけで問題が解決するというわけではないので、どのように運用するか、自動化などを含めた仕組みを考えることがより重要です。</p>

<h2>まとめ</h2>

<p>セッションの最後に<a href="https://html5experts.jp/tag/web-components/" data-wpel-link="internal">Web Components</a>に触れていました。Shadow DOMによって、今のHTML/CSSにないスコープの概念がもたらされれば、現状HTML/CSSをモジュラーに設計・実装するためのいくつかの課題は解決するかもしれません。</p>

<p>しかし、それによってCSS設計が簡単になるか、といえば決してそうではありませんし、どちらかといえばより難しくなるかもしれません。</p>

<p>またWeb Componentsの実用は少し先かもしれませんが、現在でも<a href="https://html5experts.jp/hokaccha/13301/" data-wpel-link="internal">React</a>のようなものを採用したプロジェクトにおいては、CSSはどのように設計するか、というのは課題として出てきています。個人的にはそれを考えることは、HTML/CSSをより面白くするものでもあります。（その分の苦しみも多くありますが）</p>

<p>どのような未来がくるにせよ、よりよいCSS設計をするためには、より多くのパターンを知ることだと考えています。</p>

<p>同じリスト型のUIを組むにしても、どのようなパターンが目の前のプロジェクトにおいて適切か、それはパターンを多く知らなければいけません。</p>

<p>そのためには、世の中に多く公開されているフレームワーク、またはプロダクトとして公開されているWebサイトやWebサービスのコードを読むことが大事です。続々と出てくる、新たなOOCSSやBEMのような方法論たちも、食わず嫌いはせず一読してみてください。</p>

<p>CSS設計は非常に難しく、壊れないCSSを書くというのは不可能です。私は次の言葉を胸に、いつもCSSを書いています。</p>

<blockquote>
壊れない完璧な設計を求めるのではなく、壊れたときに勇気を持って修復できる設計を<br>
&mdash; <a href="https://html5experts.jp/cssradar/" data-wpel-link="internal">斉藤 祐也</a>
</blockquote>

<p><br></p>

<p>はじめから作ることはもちろん、どれだけシミュレーションや設計をしても壊れるときはありますから、それをいかに直しやすいものにするか、そしてそれが他の開発者にとって可能であり、数日後の自分でも直せるようなCSSを書くようにしましょう。</p>

<p>当日のセッションの動画・スライドは、こちらからご覧ください。</p>

<div class="aligncenter">

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

</div>

<p><a href="https://www.youtube.com/watch?v=1VZ_Rm5_rY4" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Youtube</a> /
<a href="http://www.slideshare.net/hiloki/beyond-css-architecture" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Slideshare</a></p>
]]></content:encoded>
		
		<series:name><![CDATA[HTML5 Conference 2015 特集]]></series:name>
	</item>
		<item>
		<title>【Web Audio API + Web MIDI API】ブラウザで電子楽器を作ってみよう！</title>
		<link>/ryoyakawai/12569/</link>
		<pubDate>Mon, 23 Mar 2015 04:01:41 +0000</pubDate>
		<dc:creator><![CDATA[河合良哉]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Web Audio API]]></category>
		<category><![CDATA[Web MIDI API]]></category>
		<category><![CDATA[ブラウザ]]></category>

		<guid isPermaLink="false">/?p=12569</guid>
		<description><![CDATA[連載： HTML5 Conference 2015 特集 (3)ブラウザ上で音を扱うというと、直接音を加工できるWeb Audio API、ブラウザから直接MIDIデバイスと接続できるWeb MIDI APIの2つがここ...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/h5conf2015/" class="series-257" title="HTML5 Conference 2015 特集" data-wpel-link="internal">HTML5 Conference 2015 特集</a> (3)</div><p>ブラウザ上で音を扱うというと、直接音を加工できるWeb Audio API、ブラウザから直接MIDIデバイスと接続できるWeb MIDI APIの2つがここ数年の間に利用可能になり、実際のWebサイトでも使われるようになりました。<br>
今回は「ハンズオンだともっとよかった」というお声をいただきましたHTML5 Conference 2015での講演内容を元に、2つのAPIの説明と、実際にブラウザ上に電子楽器の1つであるシンセサイザーを作ってしまうという記事です。</p>

<p>記事中のサンプルは<a href="https://github.com/ryoyakawai/html5conference2015" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">GitHub</a>に公開していますので、そちらも合わせてご参照ください。</p>

<h2>利用するAPIの説明</h2>

<h3>Web Audio API</h3>

<p style="margin-bottom:8px">短く一言で説明すると<b>「ブラウザ上で音を直接作ったり、いじったりすることのできるAPI」</b>です。もう少し難しく言うと「ブラウザ上で波形処理を可能にしたAPI」となります。<br>
Web Audio APIの理解を深めるためにまず「音」とは何かを考えてみたいと思います。Wikipediaには以下のように書かれています。
</p>

<div style="border:solid 1px #cccccc;margin-bottom:8px">
<blockquote>
<ul style="margin-left:20px;margin:10px 0px 10px 20px">
 <li style="margin-top:2px">物の<b>響き</b>や人や鳥獣の声</li>
 <li style="margin-top:2px">（物体の振動が空気などの<b>振動</b>（音波）として伝わって起す）聴覚の内容</li>
 <li style="margin-top:2px">またはそのもととなる<b>音波</b></li>
</ul>
</blockquote>
<div style="margin:10px 0px 10px 80px;border-left:3px solid #aaaaaa;padding-left:10px">
「引用」『フリー百科事典　ウィキペディア日本語版』より。<br>
2015年3月16日 8:30 UTC<br>
<a href="http://ja.wikipedia.org/wiki/%E9%9F%B3" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">http://ja.wikipedia.org/wiki/%E9%9F%B3</a><br>
</div>
</div>

<p>
<b>響き</b>、<b>振動</b>、<b>音波</b>と出てきました。実は、音を目に見える形にすると<b>波</b>になるのです。Web Audio APIも原理は同じで、波を与えて音として出力しています。そして、その波の形（波形）をいじる（処理）して様々な音を作り出すとご理解いただけばよいと思います。</p>

<p style="margin-bottom:8px">原理の説明はここまでにして、最初に声を取得して、その声をWeb Audioでピッチシフト（音を高くしたり、低くしたりする効果）、Delay（音を遅らせる効果）の加工を行うデモをご紹介いたします。（できるだけマイクとヘッドホンをご用意ください）<a href="http://ryoyakawai.github.io/html5conference2015/audio/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ピッチシフト＆Delayのライブデモ</a></p>

<div class="aligncenter" style="clear:both;width:568px">
<div style="float:left;width:283px"><a href="http://ryoyakawai.github.io/html5conference2015/audio/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/Screen-Shot-2015-02-15-at-9.54.14-AM.png" alt="PitchShift&amp;Delay" width="281" height="289" class="alignnone size-full wp-image-12827" srcset="/wp-content/uploads/2015/02/Screen-Shot-2015-02-15-at-9.54.14-AM.png 281w, /wp-content/uploads/2015/02/Screen-Shot-2015-02-15-at-9.54.14-AM-201x207.png 201w" sizes="(max-width: 281px) 100vw, 281px" /></a></div>
<div style="float:left;width:283px">
 <div style="text-align:left;padding:40px 0px 0px 20px">
  <p style="margin-bottom:2px;font-weight:bold">ノブとボタンの説明▼</p>
  <div style="padding:4px">
   <p style="margin-bottom:2px"><b>(1)</b> PitchShift ON/OFF</p>
   <p style="margin-bottom:2px"><b>(2)</b> Shiftの種類：(上:高い、下：低い)</p>
   <p style="margin-bottom:2px"><b>(3)</b> Delay ON/OFF</p>
   <p style="margin-bottom:2px"><b>(4)</b> Delayの種類：並列/直列</p>
   <p style="margin-bottom:2px"><b>(5)</b> Feedback量</p>
   <p style="margin-bottom:2px"><b>(6)</b> Delay時間</p>
  </div>
 </div>
</div>
</div>

<div style="clear:both"></div>

<p><br></p>

<div class="aligncenter">
<img src="/wp-content/uploads/2015/02/delay-parallel.png" alt="delay-parallel" width="70%" class="alignnone wp-image-12849" srcset="/wp-content/uploads/2015/02/delay-parallel.png 631w, /wp-content/uploads/2015/02/delay-parallel-300x85.png 300w, /wp-content/uploads/2015/02/delay-parallel-207x59.png 207w" sizes="(max-width: 631px) 100vw, 631px" /></div>

<p><br>
ノードグラフ（Web Audioでは処理をする1つ1つをノードと呼び、それらをつなぎ合わせて1つのグラフにします）は上図のようになっています。ピッチシフト＆DelayのライブデモのDelayをONにして、種類を直列にする（（4）のスイッチを下にする）と<a href="https://html5experts.jp/wp-content/uploads/2015/02/delay-direct.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">このような接続</a>になります。直列につなげると、マイクで拾った音が(6)Delay時間だけ遅れてスピーカから出るようになります。<br>
このノードグラフをWeb Audio APIで書くとこうなります。（ピッチシフト部分、Delay部分をObjectにしてまとめている関係上、ゼロから書くともう少し長く、複雑になります）（<a href="http://ryoyakawai.github.io/html5conference2015/audio/sample01.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>）</p>
<pre class="crayon-plain-tag">var ctx=new AudioContext();
var mic;
var psin=ctx.createGain(), psout=ctx.createGain();
var delayin=ctx.createGain(), delayout=ctx.createGain();

navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
navigator.getUserMedia({audio : true}, successCallback, errorCallback);
function successCallback(stream) {
    mic = ctx.createMediaStreamSource(stream);
    mic.connect(psin);
}
function errorCallback(msg) {
    console.log(msg);
}
var pshift=new pitchShift(ctx);
psin.connect(pshift.getSrc());
pshift.connect(psout);

var delay=new delayProcess(ctx);
delayin.connect(delay.getSrc());
delay.connect(delayout);

psout.connect(delayin);
delayout.connect(ctx.destination);</pre></p>

<p>このように、Web Audio APIを使うと、今まではプラグインを使う以外に方法がなかったWebブラウザ上でのリアルタイムな波形処理を、比較的簡単に行うことが可能です。</p>

<h3>Web MIDI API</h3>

<p>短く一言で説明すると<b>「ブラウザとデバイス間でMIDIメッセージを送受信するためのAPI 」</b>です。MIDIとは <b>M</b>usical <b>I</b>nstrument <b>D</b>igital <b>I</b>nterface の略で、電子楽器の演奏データをデバイス間でデジタル転送するための世界共通規格であり、物理的な送受信回路・インタフェース、通信プロトコル、ファイルフォーマットなど複数の規定からなっています。Web MIDI APIは特にこの中の通信プロトコルをWebブラウザへの実装したAPIです。</p>

<p style="margin-bottom: 8px">Web MIDI APIの特徴は外付けのMIDIデバイス<a href="#footnote0" style="vertical-align: top;color: red;font-size:10px" data-wpel-link="internal">※0</a>とWebブラウザが直接接続できるところです。ですのでWeb Audio APIのようにそれ単体で音が鳴ったりする訳ではなく、MIDIデバイスからWebブラウザで動くアプリケーションをコントロールしたり、またWebブラウザからMIDIデバイスコントロールするために利用します。よって本記事では最初にWeb Audio APIを使った電子楽器アプリケーションを作り、それをWeb MIDI APIを使って外付けのMIDIデバイスからコントロールするというシナリオで進めさせていただきます。</p>

<div style="border:solid 1px #cccccc;margin-bottom:25px">
  <a name="footnote0" data-wpel-link="internal"></a>
  <div style="margin:10px 5px 10px 10px;border-left:3px solid #aaaaaa;padding-left:10px">
    <a name="footnote0" data-wpel-link="internal"></a>
    <span style="vertical-align: top;color: red;font-size:10px">※0</span> <b>MIDIデバイス</b>： 楽器関連では鍵盤をはじめ、ドラムパッド、スライダー、ノブ等があり、楽器以外ですと、ステージ上のセットを楽器等と一緒にMIDIでコントロールしてしまおうという発想で照明機器、その他噴水、爆破、炎の制御に使われていることもあります。<br>
  </div>
</div>

<p>なお、やや長い記事になってしまいましたので、ソースコードの量の少なさを体感していただき、その解釈は後回しにしてデモを触っていただくのがよいと思います。「電子楽器を実装する」というと難しそうに聞こえるかもしれませんが、そこまで難しくもありませんので実装に挑戦していただけるとうれしいです。</p>

<h2>Web Audio API で電子楽器を実装する</h2>

<p>電子楽器と言ってもその種類は複数あります。今回はその中からアナログシンセサイザーとFMシンセサイザーを実装してみます。</p>

<h3>Web Audio API でアナログ・シンセサイザー</h3>

<p>アナログ・シンセザイザーはアナログ回路を用いて信号処理を行うことで音を出す方式のシンセサイザーです。そのアナログ回路をWeb Audio APIを使って実装していきます。まずはどんな音が出るか<a href="http://ryoyakawai.github.io/html5conference2015/analog/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">完成形のデモ</a>で試してみてください。
</p>

<p><a href="http://ryoyakawai.github.io/html5conference2015/analog/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/Screen-Shot-2015-02-19-at-12.49.31-AM.png" alt="AnalogSynthApp" width="60%" class="aligncenter size-full wp-image-12998" srcset="/wp-content/uploads/2015/02/Screen-Shot-2015-02-19-at-12.49.31-AM.png 640w, /wp-content/uploads/2015/02/Screen-Shot-2015-02-19-at-12.49.31-AM-300x248.png 300w, /wp-content/uploads/2015/02/Screen-Shot-2015-02-19-at-12.49.31-AM-207x171.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>
画面上にある２つのスライダを動かすと音色を大きく変化させることができると思います。それでは原理を見てみましょう。
</p>

<p style="margin-bottom:8px">
このシンセサイザーは以下の3つの部品を使っています。
</p>

<ul style="margin-bottom:14px">
  <li style="margin-bottom:2px">基本の信号・波形を作り出す発振機<a href="#footnote1" style="vertical-align: top;color: red;font-size:10px" data-wpel-link="internal">※1</a> （VCO0、VCO1）</li>
  <li style="margin-bottom:2px">波形を加工するフィルタ（VCF）</li>
  <li style="margin-bottom:2px">低い周波数の制御信号を発振機から発生させて送ることで周期的な変化を与える（LFO）</li>
</ul>

<p>
これらを接続して下図のノードグラフを作ります。
<img src="/wp-content/uploads/2015/02/analogsynth.png" alt="AnalogSynthNodeGraph" width="60%" class="aligncenter size-full wp-image-13003" srcset="/wp-content/uploads/2015/02/analogsynth.png 527w, /wp-content/uploads/2015/02/analogsynth-300x225.png 300w, /wp-content/uploads/2015/02/analogsynth-207x155.png 207w" sizes="(max-width: 527px) 100vw, 527px" />


<div style="border:solid 1px #cccccc;margin-bottom:8px">
  <div style="margin:10px 5px 10px 10px;border-left:3px solid #aaaaaa;padding-left:10px">
    <a name="footnote1" data-wpel-link="internal"></a>
    <span style="vertical-align: top;color: red;font-size:10px">※1</span> <b>発振機</b>： 波を発生させる部品で、オシレータ（Oscillator）とも呼びます。<br>
  </div>
</div>



</p>

<p>ソースコードは以下のようになります。（<a href="http://ryoyakawai.github.io/html5conference2015/analog/sample02.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>、<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/analog/sample02.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）</p>

<p></p><pre class="crayon-plain-tag">var ctx=new AudioContext();
var vco0, vco1, lfo, vcf;

vco0=ctx.createOscillator();   // VCO0を作成
vco1=ctx.createOscillator();   // VCO1を作成
lfo=ctx.createOscillator();    // LFOを作成
vcf=ctx.createBiquadFilter();  // VCFを作成

vco0.connect(vcf);             // (1)の接続
vco1.connect(vcf);             // (2)の接続
lfo.connect(vco0.frequency);   // (3)の接続
lfo.connect(vco1.frequency);   // (4)の接続
lfo.connect(vcf.detune);       // (5)の接続
vcf.connect(ctx.destination);  // (6)の接続

// 値を変更
//vco0.type="sawtooth";
//vco1.detune.value=-35;
//lfo.frequency.value=2;
//vcf.frequency.value=10000;

// Oscillator（発振機）を動作させて発音
vco0.start(0);
vco1.start(0);
lfo.start(0);

// 音階を変える
vco0.frequency.value=440;
vco0.frequency.value=440;</pre><p></p>

<p style="margin-bottom:12px">これで発音されます。が、このままですとそのままの音が出るだけですので面白くありません。そこで、それぞれのノードのパラメータを変更してみます。コメント化していた「値を変更」の以下4行を生かしてみます。（<a href="http://ryoyakawai.github.io/html5conference2015/analog/sample03.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>、<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/analog/sample03.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）<br>
先程より音色が明るくなったと思います。<a href="http://ryoyakawai.github.io/html5conference2015/analog/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">完成形のデモ</a>のVCFのスライダを右に動かしたのと同様な値の変更を行いました。VCFは設定値より低い周波数を通す（ローパス）フィルタになっていて、そのパラメータを大きくしてより多くの明るい部分を通して明るい音色を出しています。</p>

<p>さらにシンセサイザーっぽい音にするべく、音量や音高などを時間で変化させる<a href="http://ja.wikipedia.org/wiki/ADSR" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ADSR</a><a href="#footnote2" style="vertical-align: top;color: red;font-size:10px" data-wpel-link="internal">※2</a> と呼ばれてるエンベロープ<a href="#footnote3" style="vertical-align: top;color: red;font-size:10px" data-wpel-link="internal">※3</a> の機能実装します。ここではこのエンベロープを発振機（Oscillator）の音量（VCO0、VCO1）に適応しますので音量を調節するGainNodeを(1)、(2)へ追加します。そのソースコードは以下のようになります。（ノード作成、接続部分のみ抜粋）

<div style="border:solid 1px #cccccc;margin-bottom:8px">
  <div style="margin:10px 5px 10px 10px;border-left:3px solid #aaaaaa;padding-left:10px">
    <a name="footnote2" data-wpel-link="internal"></a>
    <span style="vertical-align: top;color: red;font-size:10px">※2</span> <b>ADSR</b>：下図のように波形を処理する場合のそれぞれも部分を指しています。<br>
<img src="/wp-content/uploads/2015/02/Screen-Shot-2015-02-20-at-12.14.23-AM.png" alt="ADSR-DIAGRAM" width="60%" class="aligncenter size-full wp-image-13025" srcset="/wp-content/uploads/2015/02/Screen-Shot-2015-02-20-at-12.14.23-AM.png 473w, /wp-content/uploads/2015/02/Screen-Shot-2015-02-20-at-12.14.23-AM-300x157.png 300w, /wp-content/uploads/2015/02/Screen-Shot-2015-02-20-at-12.14.23-AM-207x108.png 207w" sizes="(max-width: 473px) 100vw, 473px" />
    <ul style="margin-bottom:14px;padding-left:5px">
      <li style="margin-bottom:2px"><b style="color:#ff0303">A</b> (Attack) :音の出始め（例えば鍵盤を押した瞬間）から最大音量に到達する時間</li>
      <li style="margin-bottom:2px"><b style="color:#3c78d8">D</b> (Decay) : Attackで到達した音量最大からSustainに到達するまでの時間</li>
      <li style="margin-bottom:2px"><b style="color:#6aa84f">S</b> (Sustain) : Decayから音が出続けている間保つ音量</li>
      <li style="margin-bottom:2px"><b style="color:#ffd966">R</b> (Release) : 演奏終了（例えば鍵盤を離した瞬間）から音量ゼロまで到達する時間</li>
    </ul>

  </div>

    <a name="footnote3" data-wpel-link="internal"></a>
  <div style="margin:10px 5px 10px 10px;border-left:3px solid #aaaaaa;padding-left:10px">
    <span style="vertical-align: top;color: red;font-size:10px">※3</span> <b>エンベロープ</b>： ピーク（最大値）を描いた曲線。特にここでは音量のピークを描く曲線のことを指しています。<br>
  </div>


</div>
</p>

<p></p><pre class="crayon-plain-tag">var ctx=new AudioContext();
var vco0, vco1, lfo, vcf;

vco0=ctx.createOscillator();
vco1=ctx.createOscillator();
lfo=ctx.createOscillator();
vcf=ctx.createBiquadFilter();

// GainNodeを追加
vco0gain=ctx.createGain();
vco1gain=ctx.createGain();

vco0.connect(vco0gain); // vco0の接続先を変更
vco1.connect(vco1gain); // vco1の接続先を変更
vco0gain.connect(vcf);  // vco0gainからvcfへ接続
vco1gain.connect(vcf);  // vco1gainからvcfへ接続
lfo.connect(vco0.frequency);
lfo.connect(vco1.frequency);
lfo.connect(vcf.detune);
vcf.connect(ctx.destination);

// Oscillator（発振機）を動作させて発音
vco0.start(0);
vco1.start(0);
lfo.start(0);</pre><p></p>

<p>続いて、実際にエンベロープを適応していきます。Web Audioには今回のエンベロープのような時間と目標値を指定して、その間を連続的に値を変化させるオートメーションの機能も提供されており、非常に簡単に実装することが可能です。今回は「指定した値まで直線的に連続して値を変化させる」linearRampToValueAtTime()を使いオートメーションを行います。
ソースコードは以下になります。（エンベロープ部分のみ抜粋）
</p><pre class="crayon-plain-tag">var now=ctx.currentTime;
var attack=0.5, decay=0.5, sustain=0.5, release=0.5;

var rootValue0=0.8; // Attackの目標値を0.8
vco0gain.gain.cancelScheduledValues(0);  // スケジュールを全て解除
vco0gain.gain.setValueAtTime(0.0, now);  // 今時点を音の出始めとする
vco0gain.gain.linearRampToValueAtTime(rootValue0, now + attack);  
// ▲ rootValue0までattack秒かけて直線的に変化
vco0gain.gain.linearRampToValueAtTime(sustain * rootValue0, now + attack + decay);
// ▲ sustain * rootValue0までattack+decay秒かけて直線的に変化

var rootValue1=0.8;
vco1gain.gain.cancelScheduledValues(0);
vco1gain.gain.setValueAtTime(0.0, now);
vco1gain.gain.linearRampToValueAtTime(rootValue0, now + attack);
vco1gain.gain.linearRampToValueAtTime(sustain * rootValue0, now + attack + decay);</pre><p>
<a href="http://ryoyakawai.github.io/html5conference2015/analog/sample03.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">1つ前のライブデモ</a>にエンベロープを適応させた<a href="http://ryoyakawai.github.io/html5conference2015/analog/sample04.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモはこちら</a>になります。（<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/analog/sample04.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）
</p>

<p>以上でアナログ・シンセサイザーの骨格が完成しました。楽器にするためには、パラメータをコントロールするスライダー、ノブ、VCOの周波数を変えて音階決める鍵盤を取り付ける作業を残すのみとなります。より個性的な音を作る場合、例えばノードグラフにVCOをもう1つ並列に追加したりすることで、更に多彩な音色を作ることが可能になりますので試してみてはいかがでしょうか。</p>

<p>ちなみに<a href="http://ryoyakawai.github.io/html5conference2015/analog/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">完成形のデモ</a>で使っているノブ、鍵盤は楽器、Audio系のアプリケーションには欠かせないカッコイイノブが簡単に取り付けられるスゴク便利なツール<a href="https://github.com/g200kg/webaudio-controls" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">webaudio-controls</a>というPolymerエレメント（<a href="https://html5experts.jp/1000ch/11905/" target="_blank" data-wpel-link="internal">詳しくはこちらをご覧ください</a>）を利用して実装しています。</p>

<p>アナログ・シンセサイザーの実装の説明は以上になります。</p>

<h3>Web Audio API でFMシンセサイザー</h3>

<p>FMシンセサイザーのFMはFrequency Modulationの頭文字を取っていて、その名の通り周波数を変調して音を作り出す方法で、周波数変調と呼んでいます。（しかしながら、Web Audio APIに用意されている発振機では周波数変調ができません。よって、ここでは複数の波を掛け合わせFMシンセサイザーっぽい音を作っていることにご注意ください。本当のFMシンセサイザーを作るためには周波数変調可能な発振機の作成が必要です）<br>
それでは、どんな音が出るか<a href="http://ryoyakawai.github.io/html5conference2015/fm/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">完成形のデモ</a>を試してみてください。
<a href="http://ryoyakawai.github.io/html5conference2015/fm/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/Screen-Shot-2015-02-20-at-1.23.53-AM.png" alt="AnalogSynthApp" width="60%" class="aligncenter size-full wp-image-12998" /></a>
</p>

<p>
アナログ・シンセサイザーよりももう少し金属音的な音が出ていると思います。画面右上のプルダウンメニューにて音色も変更することができるようになっていますので、ぜひお試しください。
</p>

<p>
さて、実装に関してですが複数の発振機（Oscillator）を接続していきます。ここで、掛け合わせる側の発振機（Oscillator）をモジュレータ、その影響を受けて掛け合わされる側の発振機（Oscillator）をキャリアと呼びます。今回の実装はモジュレータとキャリアを1つづつ直列に接続し、更にモジュレータを自身にFeedbackしするような接続にします。ノードグラフに表すと以下のようになります。
<img src="/wp-content/uploads/2015/02/fmsynth00.png" alt="fmsynthnodegraph" width="60%" class="aligncenter size-full wp-image-13095" />
少し余談ですが、モジュレータの数が増やすと接続の組み合わせによって複数の接続方法が考えられます。その接続方法の1つ1つをアルゴリズムと呼んでいます。
</p>

<p>ソースコードをみてみましょう。（<a href="http://ryoyakawai.github.io/html5conference2015/fm/sample05.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>、<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/fm/sample05.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）</p>

<p></p><pre class="crayon-plain-tag">var ctx=new AudioContext();
var modulator, carrier;
var modulatorGain, carrierGain, feedbackGain;

modulator=ctx.createOscillator();  // モジュレータを作成
carrier=ctx.createOscillator();    // キャリアを作成
modulatorGain=ctx.createGain();    // モジュレータの振幅を制御するためのGainの作成 (1)の途中にある
carrierGain=ctx.createGain();      // キャリアの振幅を制御するためのGainの作成 (2)の途中にある
feedbackGain=ctx.createGain();     // フィードバックの振幅を制御するためのGainの作成

// 接続
modulator.connect(modulatorGain);          // モジュレータとモジュレータGainの接続
modulatorGain.connect(carrier.frequency);  // モジュレータGainとキャリアの接続
carrier.connect(carrierGain);              // キャリアとキャリアGainの接続
carrierGain.connect(ctx.destination);      // キャリアGainとDestinationの接続
modulator.connect(feedbackGain);           // モジュレータとフィードバックGainの接続
feedbackGain.connect(modulator.frequency); // フィードバックGainとモジュレータの接続

carrier.frequency.value=440;

// 値を変更
//var presetList={ "name":"Elec.Piano1", "freqRatio":[1,9], "feedback":"0", "outRatio":[99,55]};
//var freq=540;
//modulator.frequency.value=presetList.freqRatio[1]*freq;
//carrier.frequency.value=presetList.freqRatio[0]*freq; // 音階を変える
//feedbackGain.gain.value=presetList.feedback;
//modulatorGain.gain.value=(presetList.outRatio[1]/100)*1024;
//carrierGain.gain.value=(presetList.outRatio[0]/100);

// 発振機（Oscillator）を動作させて発音
modulator.start(0);
carrier.start(0);</pre><p></p>

<p>これで発音されます。が、アナログ・シンセサイザーの時と同様にそのままの音が出るだけで面白くないので、ここでもパラメータを変更してみます。コメント化されている「値を変更」の以下7行を生かしてみます。（<a href="http://ryoyakawai.github.io/html5conference2015/fm/sample06.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>、<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/fm/sample06.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）<br>
なんと、音がキラキラしてきました。さて、ではアナログ・シンセサイザーのときと同じようにエンベロープを適応してみます。ソースコードは以下になります。（エンベロープ部分のみ抜粋）
</p><pre class="crayon-plain-tag">var now=ctx.currentTime;
var m_attack=0, m_decay=0.5, m_sustain=0.3, m_release=0.5;
var c_attack=0.4, c_decay=0.3, c_sustain=0.7, c_release=0.4;

var modulatorRootValue=modulatorGain.gain.value;  // Attackの目標値をセット
modulatorGain.gain.cancelScheduledValues(0);      // スケジュールを全て解除
modulatorGain.gain.setValueAtTime(0.0, now);      // 今時点を音の出始めとする
modulatorGain.gain.linearRampToValueAtTime(modulatorRootValue, now + m_attack);
// ▲ rootValue0までm_attack秒かけて直線的に変化
modulatorGain.gain.linearRampToValueAtTime(m_sustain * modulatorRootValue, now + m_attack + m_decay);
// ▲ m_sustain * modulatorRootValueまでm_attack+m_decay秒かけて直線的に変化

var carrierRootValue=carrierGain.gain.value;      // Attackの目標値をセット
carrierGain.gain.cancelScheduledValues(0);        // スケジュールを全て解除
carrierGain.gain.setValueAtTime(0.0, now);        // 今時点を音の出始めとする
carrierGain.gain.linearRampToValueAtTime(carrierRootValue, now + c_attack);
// ▲ rootValue0までc_attack秒かけて直線的に変化
carrierGain.gain.linearRampToValueAtTime(c_sustain * carrierRootValue, now + c_attack + c_decay);
// ▲ c_sustain * carrierRootValueまでc_attack+c_decay秒かけて直線的に変化</pre><p>
<a href="http://ryoyakawai.github.io/html5conference2015/fm/sample06.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">1つ前のライブデモ</a>にエンベロープを適応させた<a href="http://ryoyakawai.github.io/html5conference2015/fm/sample07.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモはこちら</a>になります。（<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/fm/sample07.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）
</p>

<p>FMシンセサイザーの骨格もこれで完成しました。<a href="http://ryoyakawai.github.io/html5conference2015/fm/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">完成形のデモ</a>ではパラメータの集合に音色名をつけて選択できるようにしていますが、アナログ・シンセサイザーのときのように、ノブやスライダでパラメータをコントロールするという方法も実現可能ですので、いろいろとお試しいただくと楽しいと思います。</p>

<p>アナログ・シンセサイザーとFMシンセサイザーの実装を通して「Web Audio APIで電子楽器を作ってみる」をやってきましたが、印象はどうでしょう。「Web Audio APIって簡単で楽しいな〜」と感じていただけているととても嬉しいのです！</p>

<p>さて、それでは次のセクションでは作成した電子楽器を本物の楽器のように鍵盤から演奏できるように、MIDIの接続を説明します。</p>

<h2>Web MIDI APIを使う</h2>

<p>
先ほど少しだけMIDIとWeb MIDI APIについてご説明させていただきました。さらに理解したいという方はDTM界隈で著名な藤本健さんの&#8221;DTMステーション&#8221;に<a href="http://www.dtmstation.com/archives/51930656.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">「今さら聞けない、「MIDIって何？」「MIDIって古いの？」」</a>というMIDIを理解するのにドンピシャな記事が公開されましたので、詳細はそちらにお任せするとしてここでは粛々と実装を行っていきたいと思います。</p>

<p>ちなみに2015年3月現在でWeb MIDI APIが動作するブラウザは<a href="https://www.google.co.jp/chrome/browser/desktop/index.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Google Chrome</a>だけとなっています。また、その使用には<a href="https://plus.google.com/u/0/+RyoyaKAWAI/posts/8QeU6ss4dHM" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">フラグの変更（Web MIDI APIを有効にする方法）</a>が必要ですので、お試しになる前にフラグの変更を忘れないようにお願い致します。（MIDIデバイスがお手元になく、Macをお使いの場合は<a href="https://itunes.apple.com/jp/app/easy-midi-free-turn-your-mac/id614043075?l=en&amp;mt=12" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Easy MIDI Free</a>をお使いいただくと演奏できるはずです）
</p>

<p>
コンピュータに接続されているMIDIデバイスをブラウザで取得するには以下のコードを書き、MIDI InputとOutputのデバイスリストを取得します。
</p>

<p></p><pre class="crayon-plain-tag">var inputs, outputs;
navigator.requestMIDIAccess.then({sysex:true})(successCallback, errorCallback);
function successCallback(midiAccess) {
  var inputIterator=midiAccess.inputs.values();
  for(var o=inputIterator.next(); !o.done; o = inputIterator.next()) {
    inputs.push(o.value);
  }
  var outputIterator=midiAccess.outputs.values();
  for(var o=outputIterator.next(); !o.done; o = outputIterator.next()) {
    outputs.push(o.value);
  }
}</pre><p></p>

<p>
MIDI Inputを使う場合、例えば使いたいMIDI Inputデバイスがinputsの先頭にリストされた（index=0）とします。その場合は以下のようにイベントハンドラをつけてあげます。
</p><pre class="crayon-plain-tag">inputs[0]=function(event) {
  console.log("[MIDI Message] " + event.data + " [Timestamp] " + event.timestamp);
}</pre><p>
こうすることで、inputsの先頭にリストされている外部MIDIデバイスからMIDIメッセージが飛んできた場合にMIDIメッセージとタイムスタンプをコンソールに出力するようになります。
</p>

<p>
MIDI Outputを使う場合、例えば使いたいMIDI Outputデバイスがoutputsの先頭にリストされた（index=0）にあったとします。
</p><pre class="crayon-plain-tag">outputs[0].send([0x90, 0x45, 0x3f], performance.now()+0);</pre><p>
とすると、outputsの先頭にリストされたMIDIデバイスに対して0x90, 0x45, 0x3fというMIDIメッセージを今すぐ(第２引数)送信します。MIDIメッセージ0x90, 0x45, 0x3fは、A4の音（0x45）を、50%の音量（0x3f）でチャンネル1を音を鳴らしなさい(0x90)、です。
</p>

<p>といっても、MIDIに慣れ親しんでいない場合は実装のハードルが高いと思っています。そこでWeb MIDI APIの実装を簡単にするPolymerエレメントを公開しています。それが、 <a href="https://github.com/ryoyakawai/x-webmidi" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">x-webmidi</a>です。x-webmidiを使うとHTMLタグを5つ追加する（そのうち1つはWeb ComponentsのPolyfill）だけで、コンピュータに接続されているMIDIデバイスを取得して、セレクトボックスを生成して表示する、までを行ってくれます。MIDI InputデバイスからのメッセージはEventハンドラを、またMIDI Outputデバイスへのメッセージの送信は.sendRawMessage()を使い生のMIDIメッセージを、.sendHRMessage()を使いMIDIに慣れていない方でも分かるようにメッセージを送信できるようになっています。コードにするとこうなります。</p>

<p></p><pre class="crayon-plain-tag">&lt;script src="path/to/webcomponents.js"&gt;&lt;/script&gt;
&lt;link rel="import" href="x-webmidirequestaccess.html"&gt;
&lt;x-webmidirequestaccess sysex="true" input="true" output="true"&gt;&lt;/x-webmidirequestaccess&gt;
&lt;x-webmidiinput id="midi-input"&gt;&lt;/x-webmidiinput&gt; 　　// MIDI Inputデバイスのセレクトボックスを表示 
&lt;x-webmidioutput id="midi-output"&gt;&lt;/x-webmidioutput&gt; // MIDI Inputデバイスのセレクトボックスを表示

// MIDIメッセージを受信する
window.addEventListener("midiin-event:midi-input", function(event){
    // MIDIノートナンバーと、対応する周波数をConsoleに出力
    console.log("[noteNumber] "+event.property.noteNumber+" [frequency] "+event.property.frequency);
});

// outputsの先頭にリストされたデバイスにMIDIメッセージを送信する
var outputs=documenet.getElementById("midi-output");
outputs[0].sendHRMessage("noteon", 0, ["d4", 127], performance.now()+0);</pre><p></p>

<p>それでは、Web Audio APIで作ったシンセサイザーを、MIDIデバイスから操作できるように実装していきます。演奏するためには、音階を変えるのですが、そのためには発振機（Oscillator）の周波数を変更する必要があります。MIDIの鍵盤は1つ1つに連番の番号がついていてこれを<a href="http://ja.wikipedia.org/wiki/MIDI" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">MIDIノートナンバー（ノートナンバーでページ内を検索）</a>と言いますが、そのMIDIノートナンバーから周波数に変換する必要がありますが、それをコードにすると以下のようになります。
</p>

<p></p><pre class="crayon-plain-tag">var freq=440.0 * Math.pow(2.0, (noteNo - 69.0) / 12.0); // noteNoはMIDI鍵盤の鍵盤番号</pre><p></p>

<p style="margin-bottom:8px">しかし、x-webmidiを使うとEventの引数として演奏した鍵盤の番号とそれに対応する周波数が取得することができるので、MIDIノートナンバーから周波数の変更をする必要はありません。これらをアナログ・シンセサイザーとFMシンセサイザーに実装をするとこのように実装できます。</p>

<ul>
<li style="margin-bottom:2px">（単音）アナログ・シンセサイザー：<a href="http://ryoyakawai.github.io/html5conference2015/analog/sample08.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>（<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/analog/sample08.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）</li>
<li style="margin-bottom:2px">（単音）FMシンセサイザー：<a href="http://ryoyakawai.github.io/html5conference2015/fm/sample09.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>（<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/fm/sample09.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）</li>
</ul>

<p style="margin-bottom:8px">
でもこのままだと単音しか出なくて楽しくないので、和音も出せるようにしちゃいます。そうするとこうなります。
</p>

<ul style="margin-bottom:14px">
  <li style="margin-bottom:2px">（和音可）アナログ・シンセサイザー：<a href="http://ryoyakawai.github.io/html5conference2015/analog/sample10.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>（<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/analog/sample10.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）</li>
  <li style="margin-bottom:2px">（和音可）FMシンセサイザー：<a href="http://ryoyakawai.github.io/html5conference2015/fm/sample11.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>（<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/fm/sample11.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）</li>
</ul>

<p>自作した楽器を両手で演奏できちゃいますよね。立派な楽器のできあがりです！「Web Audio APIとWeb MIDI APIを接続するのって簡単で楽しいな～」と感じていただけているととても嬉しいのです！</p>

<h2>番外編</h2>

<p style="margin-bottom:8px">2015年3月13日（金）にWeb MIDI APIはGoogle Chromeにおいて実験的APIから標準のAPIとなることが承認されました。これによって、フラグを変更することなく（これが不要になる ▶ <a href="https://plus.google.com/u/0/+RyoyaKAWAI/posts/8QeU6ss4dHM" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Web MIDI APIを有効にする方法</a>）、Web MIDI APIを利用することが可能になります。この変更がChromeに適応されるまでにはもう少し時間がかかりますが、実現するとWeb MIDI APIがChrome APPsでの利用も可能になります。（<a href="https://developer.chrome.com/apps/about_apps" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Chrome Appsとは：英語</a>）Chrome Appsにしてしまえばオフラインでも利用可能<a href="#footnote4" style="vertical-align: top;color: red;font-size:10px" data-wpel-link="internal">※4</a>になります。ですので、ユースケースとして例えばライブでWeb Audio API、Web MIDI APIを使った自作楽器でパフォーマンスを行いたい、という場合に活躍してくれることでしょう。</p>

<p style="margin-bottom:8px">そこで、今回ご紹介した2つのシンセサイザーをChrome Appsにして公開してみました。（Web MIDI API部分の動作はしません：2015年3月14日現在）</p>

<ul style="margin-bottom:14px">
  <li style="margin-bottom:2px"><a href="https://chrome.google.com/webstore/detail/analog-synthesizer2-oscil/fpgbjodpjjmmjmoeiddbbmlkonmkjnhf" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">アナログ・シンセサイザー</a></li>
  <li style="margin-bottom:2px"><a href="https://chrome.google.com/webstore/detail/fm-synthesizer1-operator/okaomknpndkkiieohhibkfkbiniijpoe?utm_source=chrome-ntp-icon" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">FMシンセサイザー</a></li>
</ul>

<p style="margin-bottom:8px">細かいところですが、Chrome AppsはCSP（Contents Security Policy）によってスクリプト（JavaScript等）をHTMLファイルへインラインで書くことが禁止されていますが、これら2つのアプリにはPolymerエレメントを使っています（インラインJavaScirptが書かれたHTMLファイルです）のでちょっと困ったことになります。それを解決してくれるBuildツールに<a href="https://github.com/polymer/vulcanize" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">vulcanize</a>があります。&#8221;csp&#8221;オプションをつけてツールを実行することでHTML部分ととスクリプトを分けてくれますので、ソースコードの変更なしにCSPに合致したソースコードを生成することが可能なのです。
</p>

<p><code>
$ vulcanize --csp -o build.html index.html
</code></p>

<p style="margin-bottom:8px">Google Chromeのフラグの変更なしにWeb MIDI APIの利用が可能になることで、Web Audio API、Web MIDI APIを使ったブラウザで作った電子楽器の使えるシーンがより拡大されることを期待しています。manifest.jsonとバックグランドで動作させるJavaScriptの2つのファイルを用意することで簡単に実現できますので、ぜひ試してみてください。</p>

<div style="border:solid 1px #cccccc;margin-bottom:25px">
  <div style="margin:10px 5px 10px 10px;border-left:3px solid #aaaaaa;padding-left:10px">
    <a name="footnote4" data-wpel-link="internal"></a>
    <span style="vertical-align: top;color: red;font-size:10px">※4</span> <b>オフラインでも利用可能</b>：Webアプリは大きく分けて以下の2つの種類があります。<br>
    <ul style="margin-bottom:14px;padding-left:5px">
      <li style="margin-bottom:2px"><b>Hosted App</b>: HTML、CSS、JavaScript等の全てのリソースファイルがWebサーバに保存されているWebアプリのことです。URLにアクセスしてアプリを起動する所謂従来からよく知られているWebアプリです。</li>
      <li style="margin-bottom:2px"><b>Packaged App</b>: Hosted Appとは違い、HTML、CSS、JavaScript等のリソースファイルがzip等で1つになっており、Webブラウザにインストールします。Webブラウザにインストールされたリソースから起動します。そのため、オフラインでも動作が可能になっています。Chrome Appsはこの方式のWebアプリです。</li>
    </ul>
  </div>
</div>

<h2>おわりに</h2>

<p>いかがでしたでしょうか？Web Audio APIで用意されている発振機（Oscillator）は正弦波、ノコギリ波、矩形波、三角波の基本的な波形しかなく、それ単体では単調な音しか出なかったのが、少し波形処理をしてあげることで楽器らしい音にすることができたと思います。さらにはWebブラウザに鍵盤をつなげると、和音まで演奏できるようになってしまいました。
</p>

<p>さて、自作で楽器が開発ができるのはWebブラウザが初めてでしょうか？いえ、そんなことはありません。Windows、Mac、Android、iOS等の所謂Nativeな環境でも開発することは可能でした。では、Webブラウザで開発できるようになった利点はなんでしょう。それは楽器を開発するということに対するハードルが一段と低くなったところです。WebアプリケーションはWeb標準言語で開発します。Web標準言語の開発はブラウザとテキストエディタで行います。ですのでコンピュータを買ってきたその日から開発が可能です。さらにご説明させていただいた通り、こんなにも簡単に楽器を開発することができるのです。</p>

<p>今までは難しそうなイメージがあった音楽を使ったアプリケーション。しかしWeb Audio APIを使うと音を作ることができます。またWeb MIDI APIを使うと外部のMIDIデバイスとの双方向の操作が可能です。開発するWebアプリケーションに音を鳴らす要素を追加してみる、または遊び心でMIDIデバイスからWebアプリケーションを操作してみる等、ほんの少しの遊び心があなたのWebアプリケーションをより面白くする可能性があります。これを機会にいろいろなとことで試してみてはいかがでしょうか？
</p>

<h2>セッションの資料と動画</h2>

<p>2015年1月25日に行われたHTML5 Conference 2015の当日の資料と動画へのリンクです。こちらも合わせて御覧ください。</p>

<h3>動画</h3>

<div class="aligncenter">
<iframe width="315" height="177" src="https://www.youtube.com/embed/sRHhclavETY?feature=oembed&#038;wmode=opaque" frameborder="0" allowfullscreen></iframe>
</div>

<h3>スライド</h3>

<div class="aligncenter">
<iframe src="https://www.slideshare.net/slideshow/embed_code/key/6s8QuVndYhqe7U" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="https://www.slideshare.net/ryoyakawai/web-audi-oapi-web-midi-api-2015-html5-conference" title="Web Audio API, Web MIDI API - 2015 html5 conference" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Web Audio API, Web MIDI API &#8211; 2015 html5 conference</a> </strong> from <strong><a href="http://www.slideshare.net/ryoyakawai" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Kawai Ryoya</a></strong> </div>
</div>
]]></content:encoded>
		
		<series:name><![CDATA[HTML5 Conference 2015 特集]]></series:name>
	</item>
		<item>
		<title>悩める組み込み機器向けWebコンテンツのパフォーマンス</title>
		<link>/futomi/12887/</link>
		<pubDate>Fri, 20 Mar 2015 01:34:56 +0000</pubDate>
		<dc:creator><![CDATA[羽田野 太巳]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[サイト制作]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[パフォーマンス]]></category>
		<category><![CDATA[ブラウザ]]></category>

		<guid isPermaLink="false">/?p=12887</guid>
		<description><![CDATA[連載： HTML5 Conference 2015 特集 (2)近年、ブラウザやブラウザランタイムは、PCやスマートフォンのみならず、テレビ、コンソールゲーム機などの組み込み機器にも導入されるようになりました。また、Ra...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/h5conf2015/" class="series-257" title="HTML5 Conference 2015 特集" data-wpel-link="internal">HTML5 Conference 2015 特集</a> (2)</div><p>近年、ブラウザやブラウザランタイムは、PCやスマートフォンのみならず、テレビ、コンソールゲーム機などの組み込み機器にも導入されるようになりました。また、<a href="http://www.raspberrypi.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Raspberry Pi</a>に代表される<a href="http://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%83%9C%E3%83%BC%E3%83%89%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">シングルボードコンピュータ</a>も流行り出し、ロースペックな環境で動作しなければならないWebアプリケーション開発の需要が高まろうとしています。</p>

<p>多くの組み込み機器に搭載されたブラウザは、近年よく使われるAPIやCSSをサポートしています。しかし、そのパフォーマンスはスマートフォンと比べて非常に貧弱です。スマートフォンでは当たり前のパフォーマンスが得られることはありません。</p></p>

<p>本記事では、組込機器のブラウザ事情を紹介し、その上で動作するWebアプリケーションの開発の課題、私の経験での苦労話、そして、それに立ち向かうためのTipsを紹介します。</p>

<h2>組込機器とブラウザ</h2>

<p>組込機器でWebアプリケーションを開発すると言われても、あまり馴染みがないかもしれません。しかし、すでに身近にブラウザを搭載した機器や、Webアプリケーションをパッケージ化して、ダウンロード・インストール型のWebランタイム環境を提供している機器があります。</p>

<p>もっとも身近な機器といえばテレビでしょう。近年発売されたテレビは、<a href="http://www.iptvforum.jp/hybridcast/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Hybridcast</a>に対応していますが、この<a href="http://www.iptvforum.jp/hybridcast/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Hybridcast</a>のコンテンツは、HTML5対応ブラウザランタイム上で動作しており、そのコンテンツはHTML、CSS、JavaScript を使って作られています。</p>

<p>テレビメーカー各社は、スマートTVをよりスマートフォンなどのデバイスとの親和性を高めるために、Web開発者やスマートフォンアプリ開発者には馴染みがあるOSの採用を発表しています。たとえば、日本では販売されていませんが、<a href="http://www.samsungdforum.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">SamsungはテレビOSにTizenを採用</a>し、すでに一部の国で販売が開始されています。<a href="http://developer.lge.com/webOSTV/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">LGはwebOSを採用</a>しており、すでに日本でも販売されています。また、<a href="http://www.sony.net/Products/tv/androidtv/ja/?j-short=androidtv" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ソニーはAndroidの採用</a>を、<a href="http://www.prnewswire.com/news-releases/panasonic-unveils-its-cx850-flagship-4k-uhd-tv-series-300015519.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">パナソニックはFirefox OSの採用</a>を発表済みです。</p>

<p>これらのOSの多くは、アプリをHTML5ベースで開発することができるようになっています。また、Androidも、WebView（アプリから利用できるWebブラウザのランタイム）を使うことで、Webベースのアプリを動かすことが可能になります。</p>

<p>ゲームコンソールもWebと密接に関わるようになっています。<a href="https://wiiu-developers.nintendo.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Nintendo Wii U</a>は、ゲームアプリをWebベースで開発できる環境を用意してます。利用者はそれがWebで作られていると意識することなく、そのゲームで遊ぶことができます。</p>

<p>そのほか、近年は、<a href="http://www.raspberrypi.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Raspberry Pi</a>に代表されるような<a href="http://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%83%9C%E3%83%BC%E3%83%89%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">シングルボードコンピュータ</a>が流行っていますが、当然、こういったデバイスでも、OSにブラウザをインストールすることで、Webコンテンツを表示することが可能です。</p>

<p>このように、Webコンテンツが使われるステージは広がる一方、PC やスマートフォン向けのWebコンテンツと比べて、パフォーマンスはこれまで以上に意識する必要があります。</p>

<h2>組込機器ブラウザの問題</h2>

<p>テレビやゲームコンソールなどの機器のブラウザは、実は、Web開発者にはお馴染みのオープンソースのブラウザがベースになっています。すでに販売されている機器のブラウザは、WebKitやOpera Prestoがベースになっているものが多いのですが、今後は、Chromium（Blink）やGecko（Firefox）ベースのブラウザを搭載した機器も出てくることでしょう。組込機器といえども、使える機能や互換性の問題については、スマートフォンの状況に近いと言えます。</p>

<p>しかし、組込機器に特有の事情があります。まず、機器のライフサイクルが長いことです。スマートフォンのライフサイクルはおおむね2年程度でしょう。しかし、テレビやゲームコンソールは、そこまで早く買い換えられることはありません。それ以外の用途の組込機器であれば、さらにライフサイクルが長い場合も考えられるでしょう。</p>

<p>Webコンテンツを開発する上で、この機器のライフサイクルが大きく足を引っ張ることがあります。よほど致命的なバグがあれば、バグ改修のアップデートはあるかもしれませんが、基本的にブラウザが機能面でバージョンアップされることは稀です。やや新しい機器だとしても、何世代も前のブラウザだと考えたほうがよいでしょう。</p>

<p>次に大きな問題としては、貧弱なCPUと少ないメモリーです。スマートフォンでは瞬間的に終わるような処理でも、組込機器では時間がかかります。この場合は、もっと洗練されたアルゴリズムを考案する、または、処理を分割するなどの回避策が必要となります。</p>

<p>また、メモリーリークも注意が必要です。組込機器向けのアプリケーションは、メモリーが少ないため、スマートフォンでは問題にならなかったメモリーリークが顕在化しやすくなります。とりわけ、組込み機器向けアプリケーションでは、長時間利用するものも少なくありません。そういったケースにおいては、少しのメモリーリークですら、致命的です。</p>

<h2>パフォーマンスとは</h2>

<p>一般的にパフォーマンスといえば、起動を早く、処理を速く、アニメーションを滑らかにする、という文脈で語られることが多いといえるでしょう。しかし、組込機器向けアプリケーションでは、さらに、メモリー消費を少なく、CPU処理を少なく、そして、安定的に長時間動作し続ける、という視点が重要になります。</p>

<p>もちろん、すべてが実現できればそれに越したことはありませんが、残念ながら、貧弱なCPUと少ないメモリーでは、すべてを叶えることは物理的にも不可能です。端的に言ってしまえば、何を諦めて捨てるのか、が重要になります。とりわけ、アプリケーション開発の企画の段階で、こういった事情を考慮しておく必要があります。</p>

<p>とはいえ、このような制約がある中でも、アプリケーション開発において、ちょっとした配慮だけで、パフォーマンスが改善する場合があります。以降では、それらの具体的なテクニックについて、ご紹介しましょう。</p>

<h2>ページのロード</h2>

<p>Webアプリケーションを早く起動するために考慮しなければならないこととして、関連のファイルのダウンロードのデータ量と、ダウンロードするファイルの数が挙げられます。これらを減らすことで、アプリケーションの起動が早くなるだけでなく、ファイルロード時におけるメモリー消費も抑えられます。</p>

<p>ダウンロードするデータ量を減らす方法としては、HTML、CSS、JavaScriptの最小化が効果的です。この最小化は、よくファイル圧縮と言われることがありますが、Zipなどの圧縮アルゴリズムなどを使うものではありません。そのため、Webサーバーとブラウザとの間のHTTP通信に使われるデータ圧縮とは意味が違います。もちろん、HTTP通信における圧縮は最大限活用するほうがよいことは言うまでもありませんが、ここでは、HTML、CSS、JavaScriptの最小化にフォーカスします。</p>

<p>これらのテキストデータは、一般的に改行やインデントが数多く含まれますが、多くの場合、それはなくても構わないものです。とりわけ、JavaScriptはサイズが大きくなりがちですので、最小化の効果も大きいと言えます。さらに JavaScriptでは、構文を解析しながら変数名などを短い名前に変換するなどして、ファイルサイズを小さくするツールもあります。こういったツールを使うと、最小化の効果が増します。</p>

<p>ただし、こういったツールは JavaScript コードを変更します。そのため、はじめからそれを意識してコードを書かないと、最小化した後に動作しなくなる問題が起こりますので注意が必要です。筆者が個人的に好んでいるのは、<a href="https://developers.google.com/closure/compiler/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google Closure Compiler</a> です。最小化のレベルを選択することも可能です。最小化のレベルを欲張らなければ、最小化を意識せずに書いたコードも問題なく動作する可能性が高くなります。</p>

<p>ダウンロードするファイルの数を減らす方法としては、CSSやJavaScriptをファイルとして分離せずに、HTMLの中に直接書いてしまうのが手っ取り早いでしょう。たとえば、<a href="https://www.google.co.jp/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Googleのトップページ</a>では、ほとんどすべてが一つのHTMLの中に書き込まれています。また、CSSスプライトも効果的です。ただし、こういった対策は、コードの保守性を損ないますので、やり過ぎには注意が必要です。</p>

<h2>ペイント領域とGPUメモリー</h2>

<p>ブラウザ上に表示されたコンテンツに何かしらの変化があると、ブラウザはそれを再描画します。当然ながら、再描画する領域の面積は狭いほど良いわけですが、それを確認することは重要です。描画が行われるということは、メモリーの読み書きが発生することにほかなりません。しかし、組込機器の場合、そのメモリーの読み書きの速度がPCやスマートフォンと比べて遅い場合があります。ましてや、全画面を再描画する、というのは、相当にマシンに負荷をかけることになるため、組込機器においては、これまで以上に描画領域の面積を意識する必要があります。</p>

<p>Chromeであれば、デベロッパーツールから描画領域をリアルタイムに確認することができます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/02/chrome_developer_tools_paint.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/chrome_developer_tools_paint.png" alt="chrome_developer_tools_paint" width="640" height="284" class="alignnone size-full wp-image-12916" srcset="/wp-content/uploads/2015/02/chrome_developer_tools_paint.png 640w, /wp-content/uploads/2015/02/chrome_developer_tools_paint-300x133.png 300w, /wp-content/uploads/2015/02/chrome_developer_tools_paint-207x91.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>実際にWebアプリケーションを開発しているときには、書き換えたコンテンツだけが再描画されると思いがちなのですが、描画領域をリアルタイムに見ていると、状況によっては、より広範囲な領域を再描画していることがよく分かります。いくつか例をご紹介しましょう。</p>

<p>下図は、img 要素を使って組み込まれたスマイリー画像をゆっくりと右に移動するアニメーションの一コマをキャプチャーしたものです。この例では、JavaScriptからsetTimeout()を何度も呼び出して、CSSのleftプロパティの値を徐々に増やしています。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/02/paint_1.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/paint_1.png" alt="paint_1" width="640" height="99" class="alignnone size-full wp-image-12923" srcset="/wp-content/uploads/2015/02/paint_1.png 640w, /wp-content/uploads/2015/02/paint_1-300x46.png 300w, /wp-content/uploads/2015/02/paint_1-207x32.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>この例では、移動のたびに画像の領域が何度も再描画されていることが分かります。一秒間に数十回も再描画するわけですから、それなりに負荷がかかっているはずです。</p>

<p>この移動アニメーションを、CSS TransisionsとCSS TransformsのtranslateX()を使って作りなおした結果は、下図のとおりです。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/02/paint_2.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/paint_2.png" alt="paint_2" width="640" height="99" class="alignnone size-full wp-image-12924" srcset="/wp-content/uploads/2015/02/paint_2.png 640w, /wp-content/uploads/2015/02/paint_2-300x46.png 300w, /wp-content/uploads/2015/02/paint_2-207x32.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>この結果は、CSSをうまく使うことで、GPUアクセラレーションが有効になり、移動対象となる画像がレイヤーとして処理されていることを表しています。移動の都度、再描画が発生せず、GPUによってレイヤーを移動することでアニメーションが実現されますので、非常に効率的です。</p>

<p>しかし、GPUアクセラレーションにも注意が必要です。組込機器では、GPUのメモリーがPCやスマートフォンと較べて少ない場合が多いと言えます。何でもかんでもGPUアクセラレーションの対象となるようコンテンツを作ってしまうと、かえって不効率になる場合もあります。必要最小限にとどめることも重要です。</p>

<p>次は、単に文字を書き換えるだけの簡単な例です。その代わり、かなりの頻度で文字が書き換えられます。HTMLとJavaScriptは次のとおりです。</p>

<p></p><pre class="crayon-plain-tag">&lt;p&gt;経過時間：&lt;span id="t"&gt;0&lt;/span&gt;ミリ秒。&lt;/p&gt;</pre><p></p>

<p></p><pre class="crayon-plain-tag">var el = document.querySelector("#t");
(function countUp(now) {
    el.textContent = Math.round(now);
    window.requestAnimationFrame(countUp);
})();</pre><p></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/02/paint_3.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/paint_3.png" alt="paint_3" width="640" height="110" class="alignnone size-full wp-image-12930" srcset="/wp-content/uploads/2015/02/paint_3.png 640w, /wp-content/uploads/2015/02/paint_3-300x51.png 300w, /wp-content/uploads/2015/02/paint_3-207x35.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>ご覧のとおり、この例では、書き換えたいのは数字の部分だけにも関わらず、行全体が再描画の対象になってしまっています。これを改善するために、少しだけHTMLとCSSの力を借ります。</p>

<p></p><pre class="crayon-plain-tag">&lt;p&gt;経過時間：&lt;span id="outer"&gt;&lt;span id="t"&gt;0&lt;/span&gt;&lt;/span&gt;ミリ秒。&lt;/p&gt;</pre><p></p>

<p></p><pre class="crayon-plain-tag">#outer {
    display: inline-block;
    width: 100px;
    height: 20px;
    position: relative;
}
#t {
    display: inline-block;
    width: 100px;
    position: absolute;
    text-align: right;
}</pre><p></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/02/paint_4.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/paint_4.png" alt="paint_4" width="640" height="110" class="alignnone size-full wp-image-12941" srcset="/wp-content/uploads/2015/02/paint_4.png 640w, /wp-content/uploads/2015/02/paint_4-300x51.png 300w, /wp-content/uploads/2015/02/paint_4-207x35.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>このようにCSSを使って書き換えコンテンツの幅と高さを固定することで、ブラウザの再描画の領域を固定することができます。</p>

<p>最後に極端な例をご覧いただきましょう。次の例は、ロゴ画像が1秒おきに点滅するだけのシンプルな例です。</p>

<p></p><pre class="crayon-plain-tag">&lt;body&gt;
    &lt;img id="logo" src="imgs/logo.png"&gt; 
    &lt;footer&gt;...&lt;/footer&gt;
&lt;/body&gt;</pre><p></p>

<p></p><pre class="crayon-plain-tag">var el = document.getElementById("logo");
var hidden = false;
window.setInterval(function() {
    hidden = !hidden;
    el.style.display =
        hidden ? "none" : "block";
}, 1000);</pre><p></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/02/paint_5.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/paint_5-300x130.png" alt="paint_5" width="300" height="130" class="alignnone size-medium wp-image-12949" srcset="/wp-content/uploads/2015/02/paint_5-300x130.png 300w, /wp-content/uploads/2015/02/paint_5-207x89.png 207w, /wp-content/uploads/2015/02/paint_5.png 640w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>ご覧のとおり、再描画の領域が、ブラウザの表示領域全体に及んでしまっています。これは、画像を表示しているimg要素の表示が切り替わる都度、リフローが発生しているからです。実際には書き換える必要がない領域まで、再描画の対象になってしまい、非効率と言えます。これも、CSSの力を少し借りて解決します。</p>

<p></p><pre class="crayon-plain-tag">#logo {
    position: absolute;
}</pre><p></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/02/paint_6.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/paint_6-300x130.png" alt="paint_6" width="300" height="130" class="alignnone size-medium wp-image-12952" srcset="/wp-content/uploads/2015/02/paint_6-300x130.png 300w, /wp-content/uploads/2015/02/paint_6-207x89.png 207w, /wp-content/uploads/2015/02/paint_6.png 640w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>今回は、CSSのpositionプロパティにabsoluteを指定することで、img要素を、ある意味、浮かせます。これによって、リフローが発生しなくなり、img要素だけが再描画の対象になります。</p>

<h2>画像のロード</h2>

<p>組込デバイスでは、大きな画像をロードする場合にも注意すべきことがあります。特に、img要素の画像のロードが完了したら、次の処理を行いたい場合です。この場合、恐らく次のようなコードを書くのではないでしょうか。</p>

<p></p><pre class="crayon-plain-tag">imgElement.onload = function() {
    // 何か次の処理
};</pre><p></p>

<p>実は、画像が大きい場合、img要素で loadイベントが発生しても、その画像のレンダリング処理が終わっていないのです。<a href="http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML5 仕様ではこのように定義</a>されています。</p>

<blockquote title="原文">
<p>If the download was successful and the user agent was able to determine the image&#8217;s width and height, [&#8230;] fire a simple event named load at the img element.</p></blockquote>

<blockquote title="日本語訳">
<p>ダウンロードが成功し、ユーザーエージェントが画像の幅と高さを判定できたら、[&#8230;]img要素でloadという名前のシンプルなイベントを発出します。</p></blockquote>

<p>つまり、loadイベントの発生はレンダリング完了を表しているわけではありません。組込機器では、loadイベントの発生のタイミングと、実際にレンダリングが完了したタイミングの差が大きく出る場合があります。仮に、loadイベント発生直後に重い処理を開始してしまうと、処理が重複してしまい、予期せぬ結果を招く可能性があります。</p>

<p>残念ながら、画像のレンダリングが完了したことを表すイベントは存在しません。そのため、不格好ですが、タイマーなどを使って、少しだけ連続する処理を遅らせるのが手っ取り早いでしょう。</p>

<p></p><pre class="crayon-plain-tag">imgElement.onload = function() {
    window.setTimeout(function() {
        // 何か次の処理
    }, 100);
};</pre><p></p>

<p>何ミリ秒遅らせるべきかは、対象となるハードウェアのスペックに依存しますので、状況に合わせて微調整が必要となります。</p>

<h2>ビデオのロード</h2>

<p>HTML5には<a href="http://www.w3.org/TR/html5/embedded-content-0.html#the-video-element" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">video要素</a>が導入され、マークアップだけでビデオを埋め込むことができるようになったのはご存知のとおりです。しかし、ビデオを簡単に組み込めるようになったとはいえ、ブラウザに大きな負荷をかけることを意識しなければいけません。とりわけ、ビデオ再生はメモリー消費が大きいため、複数のビデオを組み込む場合には注意が必要です。</p>

<p>video要素には<a href="http://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">preload属性</a>が用意されています。これをうまく使いこなすことが重要となります。</p>

<p>もし、再生開始タイミングのパフォーマンスを気にするなら、preload属性の値をautoにします。</p>

<p></p><pre class="crayon-plain-tag">&lt;video preload="auto"&gt;</pre><p></p>

<p>たとえビデオが再生されなくても、バッファリング分のメモリーを消費してしまいます。もし複数のビデオを事前に用意したい場合は注意が必要です。確実にそのビデオが再生されると確信できる状況で使うのが良いでしょう。</p>

<p>もし、メモリー消費の低減を優先したいなら、preload属性の値をnoneにします。</p>

<p></p><pre class="crayon-plain-tag">&lt;video preload="none"&gt;</pre><p></p>

<p>この場合は、再生開始のタイミングがかなり遅れることは覚悟しておく必要があります。また、ビデオのサイズ（寸法）や、ビデオの長さの情報は、この時点で取得できません。</p>

<p>もし、どうしても事前にビデオの寸法と長さを知りたいなら、preload属性の値をmetadataにします。</p>

<p></p><pre class="crayon-plain-tag">&lt;video preload="metadata"&gt;</pre><p></p>

<p>次に、ビデオ再生の開始の命令を出してから、可能な限り早くビデオが再生できる方法について紹介します。実際にvideo要素を使って再生するビデオファイルは、主にH.264/AAC/MP4 形式が多いのではないでしょうか。MP4形式のコンテナでは、ビデオの長さや寸法などのメタ情報は、ファイルの先頭ではなく最後に格納されます。この場合、ブラウザは、ビデオ再生の直前に、Webサーバーに対して何度もHTTPリクエストを投げることになります。実際にChromeのデベロッパーツールでそれを確認することができます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/02/chrome_network_mp4.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/chrome_network_mp4.png" alt="chrome_network_mp4" width="640" height="213" class="alignnone size-full wp-image-12962" srcset="/wp-content/uploads/2015/02/chrome_network_mp4.png 640w, /wp-content/uploads/2015/02/chrome_network_mp4-300x99.png 300w, /wp-content/uploads/2015/02/chrome_network_mp4-207x68.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>ご覧のとおり、再生開始前に3回もWebサーバーにリクエストを送っています。ブラウザはまずファイルの先頭を読み取りにいきます。しかし、そこにメタ情報がないとわかると、今度はファイルの末尾を取得するためにリクエストを送ります。メタ情報が取得できたら、ファイルの先頭に戻ってバッファリング分のビデオデータをダウンロードします。これでやっと、ビデオ再生の準備ができることになります。</p>

<p>MP4形式には、Fast Startという仕組みが用意されています。多くのビデオエンコードソフトには、MP4のオプションとしてFast Startを有効にするかどうかを指定することができます。Fast Startを有効にすると、メタ情報をファイルの末尾ではなく先頭に配置してくれます。こうすることで、ブラウザの読取り回数が1回で済み、再生開始のパフォーマンスが向上します。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/02/chrome_network_mp4_2.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/chrome_network_mp4_2.png" alt="chrome_network_mp4_2" width="640" height="213" class="alignnone size-full wp-image-12965" srcset="/wp-content/uploads/2015/02/chrome_network_mp4_2.png 640w, /wp-content/uploads/2015/02/chrome_network_mp4_2-300x99.png 300w, /wp-content/uploads/2015/02/chrome_network_mp4_2-207x68.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<h2>メモリー消費</h2>

<p>組込機器向けのブラウザ上で動作するアプリケーション開発において、メモリー消費の推移はとても重要です。PCやスマートフォンと比べ、組込機器ではブラウザに割り当てられるメモリーの容量が非常に少ない場合があるからです。PCやスマートフォンではまったく問題にならなかったにも関わらず、組込機器向けに移植すると、メモリー不足でブラウザから警告が表示されたり、場合によっては、ブラウザがクラッシュしてしまいます。また、長時間起動し続けなければならない状況においては、数時間後にメモリー不足に陥ることもあります。このようなシーンでは、少しのメモリーリークでも致命的な結果をもたらします。</p>

<p>組込機器向けWebアプリケーション開発においては、ChromeのデベロッパーツールのTimelineは欠かせません。これはPC上で確認します。組込機器向けのブラウザには、こういったツールが用意されることはないため、実際の状況を把握できるわけではありませんが、少なくとも、PC上でメモリーリークが発生している限り、当然ながら、実機でもメモリーリークが発生しているはずです。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/02/chrome_timeline.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/chrome_timeline.png" alt="chrome_timeline" width="640" height="215" class="alignnone size-full wp-image-12975" srcset="/wp-content/uploads/2015/02/chrome_timeline.png 640w, /wp-content/uploads/2015/02/chrome_timeline-300x100.png 300w, /wp-content/uploads/2015/02/chrome_timeline-207x69.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>ここで注目すべきポイントは、折れ線グラフで表示されたUsed JS Heap、Documents、Nodes、Listenersの推移です。上図では、Used JS Heap、Nodesの値が、ある時点で下がっていることが分かります。これはJavaScriptエンジンにてガベージコレクションが実行されたことを意味します。これを長時間モニタリングして、ガベージコレクションが実行されるたびに、当初の値に戻ることが理想です。ガベージコレクションが実行されたにも関わらず、これらの値が完全に元に戻らずに、少しずつ増えていく場合は、何かメモリーが開放されない要因があるはずです。</p>

<p>特に、HTML要素を生成と削除する繰り返す場合は、注意が必要です。removeChild()メソッドを使って要素を表すノードをドキュメントから削除しても、上記の折れ線グラフに表示されたNodesの数がガベージコレクション実行後でも減らない場合があります。恐らく、それは、<a href="https://www.google.co.jp/webhp?ie=UTF-8#q=javascript%20%e5%be%aa%e7%92%b0%e5%8f%82%e7%85%a7" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">循環参照</a>が残っている可能性があります。また、addEventListener()メソッドやイベントハンドラプロパティを使って、イベントリスナーやイベントハンドラをセットしたにも関わらず、ノードを削除する際に、これらを解除し忘れた場合も該当します。これはChromeデベロッパーツールのListenersの数の推移を見れば把握できます。</p>

<p>ChromeデベロッパーツールのTimelineのUsed JS Heapについて、少し深く見てみましょう。下図は、とあるアプリケーションの Used JS Heapの推移をキャプチャしたものです。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/02/chrome_heap.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/chrome_heap.png" alt="chrome_heap" width="640" height="78" class="alignnone size-full wp-image-12976" srcset="/wp-content/uploads/2015/02/chrome_heap.png 640w, /wp-content/uploads/2015/02/chrome_heap-300x36.png 300w, /wp-content/uploads/2015/02/chrome_heap-207x25.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>このメモリー消費の推移では、少しずつ上昇しながら、ある時点で降下し、それを頻繁に繰り返しています。つまり、何度もガベージコレクションが発生していることを意味しています。これはよく「ノコギリ型」と言われます。</p>

<p>基本的にガベージコレクションの処理は重いため、その時点でのアニメーションなどを邪魔することがあります。そのため、あまり頻繁にガベージコレクションが発生するのはよくないと言われることがあります。一方、メモリーが少ない環境においては、ブラウザがクラッシュするくらいなら、頻繁にガベージコレクションが発生することで、メモリー消費のピークを抑えるほうがよい場合もあります。どちらがよいかは、状況次第です。</p>

<p>もし頻繁にガベージコレクションを発生させないようにしたいなら、必要な値はすべて変数として事前に用意しておき、それらをできる限り使いまわして、新たな変数を作らないようにします。これはDOMでも同じです。必要なDOMノードを事前に作っておき、それを使いまわします。その代わり、この方法は、実際にそういった変数やDOMノードを使わかなったとしても、メモリーをその分だけ消費してしまいます。</p>

<p>逆にガベージコレクションを早めに発生させたいなら、必要な都度、変数やDOMノードを生成し、不要になった時点で破棄することを繰り返します。パフォーマンスは悪くなりますが、メモリー消費のピークを抑えることができます。</p>

<p>ここでは具体的なテクニックの紹介は伝えきれませんでしたが、メモリーが少ない環境においては、Chromeデベロッパーツールなどのメモリー消費の推移は常に意識しなければいけません。</p>

<h2>prototypeの活用</h2>

<p>Webアプリケーションを作る際には、コンストラクタ関数を用意し、new演算子を使ってインスタンスを生成することが多いのではないでしょうか。ここでは、ECMAScriptのprototypeを活用するかしないかによって、メモリー消費が違ってくることを紹介します。まずは次のコンストラクタ関数をご覧ください。</p>

<p></p><pre class="crayon-plain-tag">var MyWallet = function(init_price) {
    this.price = init_price;
    this.earn = function(price) {
        this.price += price;
        if(this.price &gt; 1000) {
            this.pay(this.price - 1000);
        }
    };
    this.pay = function(price) {
        this.price -= price;
    };
    this.look = function() {
        return this.price;
    };
};</pre><p></p>

<p>上記のコードでは、コンストラクタ関数の中にメソッドを定義しています。では、次のコードをご覧ください。</p>

<p></p><pre class="crayon-plain-tag">var MyWallet = function(init_price) {
    this.price = init_price;
};
MyWallet.prototype.earn = function(price) {
    this.price += price;
    if(this.price &gt; 1000) {
        this.pay(this.price - 1000);
    }
};
MyWallet.prototype.pay = function(price) {
    this.price -= price;
};
MyWallet.prototype.look = function() {
    return this.price;
};</pre><p></p>

<p>今度は、メソッドをprototypeで定義しています。これら2つのコンストラクタは、prototypeを使っているか使っていないかの違いしかなく、事実上、同じ機能を提供します。</p>

<p>では、これらのコンストラクタからインスタンスを大量に生成して、消費メモリーを見てみましょう。いずれも、次のコードを実行します。</p>

<p></p><pre class="crayon-plain-tag">var list = [];
for( var i=0; i&lt;100000; i++ ) {
    var w = new MyWallet(0);
    list.push(w);
}</pre><p></p>

<p>結果に大きな違いを出すために、現実的ではありませんが、10万個のインスタンスを生成し、それを配列に格納します。この処理が終わった時点でのJS Heap Sizeは次のとおりとなります。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/02/prototype_compare.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/prototype_compare.png" alt="prototype_compare" width="640" height="102" class="alignnone size-full wp-image-12978" srcset="/wp-content/uploads/2015/02/prototype_compare.png 640w, /wp-content/uploads/2015/02/prototype_compare-300x47.png 300w, /wp-content/uploads/2015/02/prototype_compare-207x32.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>左側はprototypeを使わなかった場合の結果を、右側はprototypeを使った場合の結果を表しています。ご覧のとおり、消費メモリーに倍近い違いがでていることが分かります。</p>

<p>もし、大量にコンストラクタからインスタンスを生成するのであれば、積極的にprototypeを使うのが良いでしょう。</p>

<h2>DOMアクセス</h2>

<p>最後となりましたが、ここでは、DOMアクセスについて触れます。近年は、jQueryなどのJavaScriptライブラリを使って特定のDOM ノードにアクセスすることが多いのではないでしょうか。しかし、こういったJavaScriptライブラリは便利である反面、使わない機能もテンコ盛りです。しかし、使わなくても、それはブラウザではメモリーに展開されてしまい、無駄にメモリーを消費していることになります。もしJavaScriptライブラリを使うなら、機能を最小限に抑えた軽量なものを使うべき、ということは言うまでもありません。</p>

<p>ここでは、筆者がお気に入りのDOMアクセス用JavaScriptライブラリをご紹介しましょう。その名は、&#8221;<a href="http://vanilla-js.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Vanilla JS</a>&#8220;です。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/02/vanillajs_top.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/vanillajs_top.png" alt="vanillajs_top" width="640" height="427" class="alignnone size-full wp-image-12980" srcset="/wp-content/uploads/2015/02/vanillajs_top.png 640w, /wp-content/uploads/2015/02/vanillajs_top-300x200.png 300w, /wp-content/uploads/2015/02/vanillajs_top-207x138.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>Vanilla JSは、機能を選択して必要な分だけダンロードできるようになっています。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/02/vanillajs_download.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/vanillajs_download.png" alt="vanillajs_download" width="640" height="294" class="alignnone size-full wp-image-12981" srcset="/wp-content/uploads/2015/02/vanillajs_download.png 640w, /wp-content/uploads/2015/02/vanillajs_download-300x137.png 300w, /wp-content/uploads/2015/02/vanillajs_download-207x95.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>すべての機能にチェックを入れても、gzipでたったの25バイト、展開したら、なんと0バイトです。</p>

<p>このサイトでは、他のJavaScriptライブラリとの速度の比較も掲載されています。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/02/vanillajs_speed.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/vanillajs_speed.png" alt="vanillajs_speed" width="640" height="287" class="alignnone size-full wp-image-12982" srcset="/wp-content/uploads/2015/02/vanillajs_speed.png 640w, /wp-content/uploads/2015/02/vanillajs_speed-300x134.png 300w, /wp-content/uploads/2015/02/vanillajs_speed-207x92.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>このグラフは、1秒間に、何回、ID指定でノードにアクセスできるかを計測したものです。もちろん、数が多いほどパフォーマンスが良いことを表します。ご覧のとおり、Vanilla JSの速度は、他のJavaScriptライブラリの速度を圧倒しています。</p>

<p>さて、皆さんはもうお気づきですね。Vanilla JSはジョークサイトです。何が言いたいかというと、DOMアクセスを速くしたいなら、JavaScriptライブラリに頼らずに、直接Web標準のDOMで規定されたメソッドを使った方が良いということです。</p>

<p>Web標準のDOMであれば、速度も速い、メモリー消費にも優しい、といいことずくめです。メソッドが長くてコードを書くのが面倒、便利なメソッドがない、というデメリットはありますが、少なくとも、CPUが遅い、メモリーが少ない、といったナイナイ尽くしの組込機器においては、そのデメリットを覆すほどのメリットがあるのです。</p>

<p>これは当然、組込機器にかぎらず、スマートフォンにも当てはまります。あらためて、Web標準のDOMに注目してみてはいかがでしょう。</p>

<h2>まとめ</h2>

<p>ここではCPUが遅い、メモリーが少ない環境でも、ちょっとした配慮でパフォーマンスの効果が出るトピックを紹介してきました。</p>

<p>近年、さまざまなJavaScriptライブラリ、プログラミング手法、アルゴリズムなどが登場しています。もちろん、そういう新たな知識は必要ですが、それらが登場した背景などは理解しておく必要があるでしょう。例えばそれが、メモリーが潤沢な環境を前提としていたとしたら、少なくとも、組込機器向けのWebアプリケーション開発では、ベストな解とはいえません。</p>

<p>カッコ悪いかもしれませんが、レガシーな手法も、こういった環境では役に立つのです。レガシーな手法は、メモリーが少ない時代に考えられたものも多く、今なお組込デバイスでは有効なのです。</p>

<p>今後、Web技術は、PCやスマートフォンを超えてさまざまなデバイスに浸透してくことでしょう。また、スマートフォンは、日本ではハイエンド機ばかりで、年々、そのスペックは劇的に向上しています。しかし、一方で、新興国ではローエンドで安価なスマートフォンが主流です。海外にサービスを広げる際には、こういったローエンドのスマートフォンを無視することはできません。まるで時代を逆行しているかのように見えますが、今後は、ますますローエンドな環境でのWebアプリケーション開発が求められるようになるでしょう。もし、そういう状況になったときに、この記事が役に立てれば幸いです。</p>

<h3>関連資料</h3>

<iframe src="//www.slideshare.net/slideshow/embed_code/43866729" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe>

<div style="margin-bottom:5px"> <strong> <a href="https://html5experts.jp//www.slideshare.net/futomihatano/20140125-html5-conference2015-43866729" title="HTML5 Conference 2015 悩める組込機器向けウェブコンテンツのパフォーマンス" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">HTML5 Conference 2015 悩める組込機器向けウェブコンテンツのパフォーマンス</a> </strong> from <strong><a href="https://html5experts.jp//www.slideshare.net/futomihatano" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Futomi Hatano</a></strong> </div>
]]></content:encoded>
		
		<series:name><![CDATA[HTML5 Conference 2015 特集]]></series:name>
	</item>
		<item>
		<title>【HTML5 Conference基調講演】村井純・及川卓也が語る「IoT」でWeb技術はどう変わっていくのか？</title>
		<link>/miyuki-baba/12511/</link>
		<pubDate>Thu, 05 Feb 2015 23:30:33 +0000</pubDate>
		<dc:creator><![CDATA[馬場 美由紀]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[HTML5 Conference]]></category>
		<category><![CDATA[IoT]]></category>
		<category><![CDATA[及川卓也]]></category>
		<category><![CDATA[村井純]]></category>

		<guid isPermaLink="false">/?p=12511</guid>
		<description><![CDATA[連載： HTML5 Conference 2015 特集 (1)2014年10月にHTML5が勧告され、いまやHTML5はさまざまなデバイスに浸透しつつある。まさに「Web is Everywhere」。Webはごく普通...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/h5conf2015/" class="series-257" title="HTML5 Conference 2015 特集" data-wpel-link="internal">HTML5 Conference 2015 特集</a> (1)</div><p>2014年10月にHTML5が勧告され、いまやHTML5はさまざまなデバイスに浸透しつつある。まさに「Web is Everywhere」。Webはごく普通の、どこにでもあるものへと変化している。<br>
2015年1月25日に開催された「HTML5 Conference」では、この「Web is Everywhere」をテーマに慶應義塾大学 環境情報学部長・教授の村井純先生とGoogleの及川卓也さんが基調講演を行った。村井先生と及川さんはWeb技術をどう見ているのか。</p>

<p><img src="/wp-content/uploads/2015/02/html5-1.jpg" alt="" width="640" height="383" class="alignnone size-full wp-image-12520" srcset="/wp-content/uploads/2015/02/html5-1.jpg 640w, /wp-content/uploads/2015/02/html5-1-300x179.jpg 300w, /wp-content/uploads/2015/02/html5-1-207x123.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>村井先生が松葉杖姿で登壇！それができたのもWebの力？</h2>

<p>なんと村井先生は松葉杖で登壇。「生まれて初めての松葉杖です」と冗談交じりに、米国で足の指を骨折したときのことを、自らのレントゲン写真をスクリーンに映し出しながら話し始めた。そのレントゲン写真のデータは米国の診療所でもらったもの。
<br><br>
「データ化されたレントゲン写真を日本の整形外科に送ったところ、「すぐに手術しなければならない」ということになったのだそう。帰国して即、処置してもらったことで「今日、登壇することができた。このようなことが自由にできたのもWebの力だ」と村井先生。</p>

<p><img src="/wp-content/uploads/2015/02/html5-2.jpg" alt="" width="640" height="410" class="alignnone size-full wp-image-12524" srcset="/wp-content/uploads/2015/02/html5-2.jpg 640w, /wp-content/uploads/2015/02/html5-2-300x192.jpg 300w, /wp-content/uploads/2015/02/html5-2-207x132.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" />
<br><br>
そんな村井先生の講演テーマは「Web and Things」。
<br>
「70億人を超える人が参加しており、1000億のデバイスとセンサーがつながり、無限のデジタルデータがグローバルに流通し共有する、インターネット前提社会とはどのような社会なのか。それについて話をしていきたい」と語り、まず、近年流行の「IoT」という言葉を取り上げた。
<br><br>
「IoT」は「Internet of Things」の略語である。この言葉を最初に使ったのは、英国人のケヴィン・アシュトン氏で、RFIDネットワークと新しいセンシング技術に関する研究機関「オートIDラボ」をマサチューセッツ工科大学（MIT）に設立した人物である。ちなみに同研究機関の日本拠点は村井先生のいる慶応SFCにある。ケヴィン氏と村井先生はそのときからの知り合いだそうだ。</p>

<p>この当時のケヴィン氏が使ったIoTのコンセプトは、モノがトラッキングできるということだった。しかし今、私たちの間で使われるIoTは「Everythings speaks HTML、HTTP、TCP/IP、HTTP」、つまりすべてのモノがインターネットによって双方向でつながるようになるということ。</p>

<p>このことによってどう変わるか。その一例として村井先生が紹介したのが、米の人気ドラマ「House of Cards」。これはネットフリックスという動画配信サービスの会社が制作したドラマである。実はこのドラマは視聴者がどんな監督、俳優、どんなテーマの作品を好んでいるのか、どんな場面でチャンネルを離れたのかなど、セットボックスを介して得たビッグデータを解析して制作したのだという。</p>

<p><img src="/wp-content/uploads/2015/02/html5-3.jpg" alt="" width="640" height="415" class="alignnone size-full wp-image-12531" srcset="/wp-content/uploads/2015/02/html5-3.jpg 640w, /wp-content/uploads/2015/02/html5-3-300x194.jpg 300w, /wp-content/uploads/2015/02/html5-3-207x134.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" />
<br><br>
「これまでテレビは一方向のメディアだったが、もはや双方向の時代。GoogleTVやAppleTVなどのスマートテレビのプラットフォームを提供している企業は、もっと情報が取得できるようになる。そしていずれはテレビにもPCのようにカメラをつけることになるだろう。このようにモノがつながることによって、まったく新しいテレビ番組作りが始まっている」と村井先生は語る。</p>

<h2>デジタルファブリケーションが進むと物流や税関、税金がなくなる!?</h2>

<p>またもう一つのIoTの例として紹介されたのが、3Dプリンタなどを使ったデジタルファブリケーションの動きである。慶応SFCは2014年に図書館に3Dプリンタなどを設けたファブスペースを開設した。3Dプリンタは学生なら自由に使えるようになっているという。例えば脳の研究室では、学生が自分の脳を3Dプリンタで印刷して授業に活用しているという。</p>

<p>また村井先生はデジタルファブリケーションの面白事例として、3つの字が同時に書ける「cheating pencil」という学生が考えた作品を披露した。そしてこの作品の3Dデータは公開されており、ダウンロードすれば世界中の誰もが複製できるという。つまり「Download This Thing!だ」と村井先生。例えばこれを防災グッズに応用する。バケツが足りなくても、「Download This Thing!」ですぐバケツが作れる。</p>

<p><img src="/wp-content/uploads/2015/02/html5-4.jpg" alt="" width="640" height="413" class="alignnone size-full wp-image-12534" srcset="/wp-content/uploads/2015/02/html5-4.jpg 640w, /wp-content/uploads/2015/02/html5-4-300x193.jpg 300w, /wp-content/uploads/2015/02/html5-4-207x133.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" />
<br><br>
「このようにスキャンしたイメージをプリントすることが世界中でできるようになると、物流、税関、税金もなくなる。社会へのインパクトは大きい」と村井先生は力説する。</p>

<p>しかし問題点も出てくる。それは品質管理、知的所有権、製造責任の3点。その一つの解決方法として村井先生が示したのはRFIDの活用である。RFIDを印刷物に埋め込む3Dプリンタを開発し、個体を識別するというのだ。</p>

<p>このように技術はどんどん発展している。しかし経済産業省の調査によると、日本はイノベーションにデータを活用していないという。しかも経営者はイノベーションへのデータ活用をネガティブに捉えているという。</p>

<p>最後に村井先生は、かつて世界中のプレイステーション3をつないで並列処理を行ったことを挙げ、「これと同じことがWebでもできるのではないか。強力なAIができるのでは。IoTとはまさにこのことではないか」と問いかけた。ただしそのAIを動かすのは人間である。</p>

<p><img src="/wp-content/uploads/2015/02/html5-5.jpg" alt="" width="640" height="390" class="alignnone size-full wp-image-12536" srcset="/wp-content/uploads/2015/02/html5-5.jpg 640w, /wp-content/uploads/2015/02/html5-5-300x182.jpg 300w, /wp-content/uploads/2015/02/html5-5-207x126.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>鉄人28号がリモコンを持っている人間によって、良くも悪くもなるということと同様、「Human Centricであることは忘れてはならない」と指摘することも忘れなかった。
<br>
「並列処理ができる環境にブラウザやWebはなるのか。みんなで議論したい。今年はきっと面白い年になる」と語り、村井先生は講演を締めた。</p>

<h2>「ネクタイ姿」というコスプレで登壇した及川卓也さん</h2>

<p>次に登壇したのは、Googleの及川卓也さん。講演テーマは「Web技術の今後と展望」。毎年、同イベントに登壇している及川さんは、かぶりものやコスプレをすることも多いのだとか。今回はなんとネクタイを締めての登場。及川さんは冒頭で「ネクタイを締めてきたのはコスプレなので（笑）」と会場を沸かせ、講演をスタートさせた。</p>

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

<p>最近のトレンドについて「ロボットやIntel Edison、シングルボード・コンピューティングや、通信やウェラブルやマルチコプターなどが出てきており、シングルボード・コンピュータなどIoTが注目を集めている」と及川さん。検索トレンドとして「IoT」が急上昇しており、「一般にも広まりつつある」と語る。</p>

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

<p>またIaaSやPaaS、BaaSなどのクラウドの普及も低価格化、コンテナ技術、ノンプラミング実装、オープン標準技術などにより、ますます加速している。さらにすでに実装が進んでいるので、それほどインパクトはないかもしれないがHTML5が勧告されたことも挙げられる。</p>

<p>ChromeでもShadow DOMやCustom Elements、HTML Imports、Picture Elementなど、コンポーネント化する技術、デバイス連携、暗号化技術などの技術などが取り入れられている。</p>

<p>さらにChromebookやFirefox OSが搭載されたスマートフォン「Fx0」など、Webアプリケーションを使うデバイスの多様化も進んでいる。こういった一般的なITトレンドの背景を踏まえ、2015年、Webはどう変わっていくのか。</p>

<h2>2015年Web技術はどう変わる？</h2>

<p>及川さんはIoTでWebの仕組みも変わっていくと言う。<br>
「WebはこれまでクライアントからHTTPリクエストを送って、Webサーバからレスポンスが返ってくるという接続方法のみだった。そしてこの世界での機器との連携といえば、キーボード、ディスプレイ、マウスぐらいで（最近はMIDI機器なども登場しているが）、基本的にはクライアントに接続されていた」</p>

<p>このように非常にシンプルだったのだ。しかしIoTの世界になると、Bluetoothなどでクライアントに接続される機器もあれば、機器自身に搭載されたWi-Fiにより、クラウドとつながるものもある。</p>

<p><img src="/wp-content/uploads/2015/02/html5-9.jpg" alt="" width="640" height="410" class="alignnone size-full wp-image-12545" srcset="/wp-content/uploads/2015/02/html5-9.jpg 640w, /wp-content/uploads/2015/02/html5-9-300x192.jpg 300w, /wp-content/uploads/2015/02/html5-9-207x132.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>またWebSocketという技術を使えば、双方向ではない通信も行える。「もはやWebとはなんぞやという世界」と及川さん。マッシュアップしてHTML上にマップのパーツを埋め込むなど、いろんなサービスと連携もできる。最近、Chromeに採用されたService Workerの技術は、ブラウザの中に非常にインテリジェンスの高いWebプロキシが入っているような技術。</p>

<p>これにより独自にサーバからリソースを取得することが、ブラウザ側でできるようになる。このようにIoTのトレンドなどを見ていくと、「Webはかなり自由度が高いが、複雑になる可能性のある技術へと変わりつつある」と指摘した。</p>

<p>そしてWeb技術の使われ方もそのものも変わってきているという。これまでのWWWを支えるフロントエンド技術としてだけではなく、「組み込み機器の分野で、いまやアプリケーションを開発する技術として使われることが増えている」と言う。「プログラミング人口も開発ツールも増えるので、すごくいいこと」と及川さん。</p>

<p>一方で、メモリ容量やバッテリ消費などの要件が関わってくる。「これまでのようにDOMで記述するだけで本当に足りるのか、DOMというモデルがどこまで有効なのか、今後、検討していかねばならない」と指摘を促した。</p>

<p>もう一つ「大事なことがある」と及川さんは語る。それは既存のWebサイトのユーザー体験の向上である。今や多くの人がインターネット端末としてスマートフォンを使っている。しかし地方自治体のモバイル対応状況はまだまだ低い。</p>

<p><img src="/wp-content/uploads/2015/02/html5-8.jpg" alt="" width="640" height="404" class="alignnone size-full wp-image-12543" srcset="/wp-content/uploads/2015/02/html5-8.jpg 640w, /wp-content/uploads/2015/02/html5-8-300x189.jpg 300w, /wp-content/uploads/2015/02/html5-8-207x130.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>また日経225企業と米S&amp;P500企業のWebサイトの表示速度を比較したところ、日経225の方が少し遅いという。<br>
「少しの工夫でこれらのユーザー体験は改善されるので、既存Webサイトの底上げを図って欲しい」と及川さん。最後に「がんばれニッポン！」と呼びかけ、講演を終えた。</p>

<p>2015年、IoTがより進んでいくことでWeb技術は新たな展開を見せることになりそうだ。</p>

<p><br>
<strong>■上記の基調講演は動画でも公開中です</strong></p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/xRrbY5OUiik" frameborder="0" allowfullscreen></iframe>

<p><DIV align=right>（写真協力：HTML5 Conference 撮影チーム）</div></p>
]]></content:encoded>
		
		<series:name><![CDATA[HTML5 Conference 2015 特集]]></series:name>
	</item>
	</channel>
</rss>
