<?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>川田寛 &#8211; HTML5Experts.jp</title>
	<atom:link href="/furoshiki/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>JSエンジン「V8」はバージョン6で世代移行を終える ── Google I/O 2017レポート</title>
		<link>/furoshiki/23289/</link>
		<pubDate>Tue, 12 Sep 2017 01:00:47 +0000</pubDate>
		<dc:creator><![CDATA[川田寛]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Google I/O 2017]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[V8]]></category>

		<guid isPermaLink="false">/?p=23289</guid>
		<description><![CDATA[連載： Google I/O 2017特集 (3)ChromeやNode.jsで利用されているJavaScriptエンジン「V8」に、8年の歴史の中でも大きな変化が訪れました。8月3日にリリースされたバージョン6.1で、...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/google-io-2017/" class="series-450" title="Google I/O 2017特集" data-wpel-link="internal">Google I/O 2017特集</a> (3)</div><p>ChromeやNode.jsで利用されているJavaScriptエンジン「V8」に、8年の歴史の中でも大きな変化が訪れました。8月3日にリリースされたバージョン6.1で、数年かけて進めてきたJavaScriptコンパイラーが世代交代を終えました。詳しい話は、<a href="https://v8project.blogspot.jp/2017/08/v8-release-61.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">V8のブログでも語られていますが</a>、ここでは大きなトピックであるコンパイラーの世代交代についてお話します。</p>

<p>なお、この動きについては、<a href="https://www.youtube.com/watch?v=r5OWCtuKiAk" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">昨年に開かれたカンファレンス「BlinkOn 6」でも語られており</a>、Google I/O 2017でも、Seth Thompsonによるセッション「<a href="https://events.google.com/io/schedule/?section=may-18&amp;sid=06ad955b-2387-45b8-9a5b-9ebd00a6f952&amp;gclid=CKuXh-a6g9QCFVR9vQodz50B6g" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">V8, Advanced JavaScript, &amp; the next performance frontier</a>」によって紹介されています。本記事では、これらの発表内容を補足してご紹介します。</p>

<p><img src="/wp-content/uploads/2017/05/top.png" alt="" width="640" height="439" class="alignnone size-full wp-image-23339" srcset="/wp-content/uploads/2017/05/top.png 640w, /wp-content/uploads/2017/05/top-300x206.png 300w, /wp-content/uploads/2017/05/top-207x142.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h1>V8のミッションとは？</h1>

<p>Chromeで使われているJavaScriptエンジン「V8」ですが、そのミッションはとてもシンプルです。</p>

<p>「Speed up real-world performance for modern JavaScript, and enable developers to build a faster future web.(実世界での要求にあわせてモダンなJavaScriptのパフォーマンスを向上させること。そして、今後の変化していくWebに早く追従し、開発者がそれらをビルドできるようにすること)」</p>

<h1>V8のパフォーマンス改善につきまとう2つのトレードオフ</h1>

<p>V8とはなんでしょう？JIT(just-in-time compile)で動作させることができるJavaScriptのエンジンです。ブラウザがJavaScriptを受け取ると、ブラウザはそのコードをトランスレートして実行したり。また、コードを翻訳してコンピューターが理解できるネイティブコードにコンパイルしてから実行します。</p>

<p>ただ、そこにはいくつかのトレードオフが存在します。</p>

<ol>
<li>コンパイルして生成されたネイティブコードは、実行されるピーク時の速度が早い一方で、コードの量が多いほど、最初に実行されるまでに遅延が発生する。一方で、トランスレーターを使った場合は、実行されるまでの遅延は小さいけど、実行時の速度が遅い。</li>
<li>JavaScriptエンジンは、パフォーマンスを良くしようとするとメモリの消費量が多くなる。一方で、省メモリを進めようとするとパフォーマンスは悪化する。</li>
</ol>

<p>例えば、以下のような一行のfunctionを呼び出すコードについて考えてみましょう。</p>

<p><img src="/wp-content/uploads/2017/05/02-1.png" alt="" width="640" height="330" class="alignnone size-full wp-image-23350" srcset="/wp-content/uploads/2017/05/02-1.png 640w, /wp-content/uploads/2017/05/02-1-300x155.png 300w, /wp-content/uploads/2017/05/02-1-207x107.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>このコードでは、 <code>function foo()</code> は一度しか呼び出されていませんよね。このケースでは、実行されるまでの速さ（Fast Startup）を重視し、実行時のパフォーマンス（Peak Perf）は重要視しません。</p>

<p>しかし、以下のケース。</p>

<p><img src="/wp-content/uploads/2017/05/03-1.png" alt="" width="640" height="350" class="alignnone size-full wp-image-23352" srcset="/wp-content/uploads/2017/05/03-1.png 640w, /wp-content/uploads/2017/05/03-1-300x164.png 300w, /wp-content/uploads/2017/05/03-1-207x113.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>1万回も <code>function foo()</code> を呼び出しています。このケースでは、Fast Startupが遅れてでも、Peak Perfを重視する必要がでてきます。 <code>foo()</code> はネイティブコードにコンパイルされていなくてはいけません。そしてそれがデスクトップ型のコンピューターであれば、メモリも潤沢なので、大量のメモリ消費を犠牲にネイティブコードをさらに幾度に渡り最適化させます。</p>

<p>ただ、これはあくまでデスクトップ型コンピューターの場合。同じ1万回 <code>foo()</code> を呼び出すコードであっても、モバイルの場合は同じアプローチにはなりません。Androidデバイスはモバイルなので、デスクトップと同じようにメモリを扱うことはできません。</p>

<p><img src="/wp-content/uploads/2017/05/04.png" alt="" width="640" height="428" class="alignnone size-full wp-image-23356" srcset="/wp-content/uploads/2017/05/04.png 640w, /wp-content/uploads/2017/05/04-300x201.png 300w, /wp-content/uploads/2017/05/04-207x138.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>ネイティブのコードへコンパイルはされますが、メモリの消費量は抑えられるよう最適化は制限されます。</p>

<p>別のパターンについても考えてみましょう。それが以下のコード。</p>

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

<p>これはNode上で実行されているコードです。一度起動されたら、ずっと利用されるわけですから、当然、Fast Startupを犠牲にしてPeak Perfを改善しようとしますね。しかし…</p>

<p><img src="/wp-content/uploads/2017/05/06.png" alt="" width="640" height="397" class="alignnone size-full wp-image-23360" srcset="/wp-content/uploads/2017/05/06.png 640w, /wp-content/uploads/2017/05/06-300x186.png 300w, /wp-content/uploads/2017/05/06-207x128.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>IoTデバイス上で動作するとなると、同じ状況とは言えません。サーバー用マシンとは異なり、メモリ消費は抑えなくてはいけません。Peak Perfを上げるようにはしますが、それはメモリ消費が少なくて済むようなアプローチで進めます。</p>

<p>同じ一行のfunction呼び出しであっても、その最適化方法は無数にあり、コンテキストやデバイスの状況に強く依存するのです。そしてそれは、Fast Startupなのか、あるいはPeak Perfに最適化していくのか、メモリを富豪的に扱うのか、それとも小さくなるよう努力するのか、解決しなくてはいけません。</p>

<h1>8年前のリリース時点から全てが変わろうとしているV8</h1>

<p>V8エンジンは、ここまでに説明したあらゆる状況で最適化できるようにしたり、また新しいパターンのJavaScript（asm.js, WebAssembly等）に対応できるよう、2〜3年かけて実行パイプラインを作り変えました。</p>

<p>過去の変遷を見てみると。</p>

<p>2008年のリリース時点の段階では、シンプルなコードジェネレーターがあって、そこからやや最適化を行ったマシンコードが生成されるだけでした。あらゆるJavaScriptのコードは、この仕組を使って実行されます。</p>

<p>ただ、最適化には計算が必要なため、コードを実行できる状態にするまでに多くの時間を要します。大量のJavaScriptコードを扱う場合は、Startup Time短縮するために最適化の処理をスキップすることが求められます。</p>

<p><img src="/wp-content/uploads/2017/06/c01.png" alt="" width="640" height="295" class="alignnone size-full wp-image-23697" srcset="/wp-content/uploads/2017/06/c01.png 640w, /wp-content/uploads/2017/06/c01-300x138.png 300w, /wp-content/uploads/2017/06/c01-207x95.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>2010年にコンパイラ「Crankshaft」が追加されます。計算コストの高い最適化処理を分離し、Crankshaftにその責務が委譲されました。コードの生成だけであれば、Full-codegenは最小のコストでマシンコードを吐き出すため高速なため、Startup Timeが最適化されます。そして、CrankShaftを使ってコンパイルすれば、計算コストを犠牲にPeak Perfにとって最適なマシンコードが生成されます。</p>

<p>実行時に、CrankShaftが吐き出したコードを、Full-codegenが吐き出したコードへ置き換えることで最適化を図ります。</p>

<p><img src="/wp-content/uploads/2017/06/c03.png" alt="" width="640" height="328" class="alignnone size-full wp-image-23698" srcset="/wp-content/uploads/2017/06/c03.png 640w, /wp-content/uploads/2017/06/c03-300x154.png 300w, /wp-content/uploads/2017/06/c03-207x106.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>2015年。Crankshaftには限界が来ます。JavaScriptの仕様そのものが大きく変化する時代になりましたが、Crankshaftはその設計上、JavaScriptの機能をサポートしきれず、また新しいパターンのJavaScript（asm.js, WebAssembly等）にも十分に対応できませんでした。当時のフロントエンドエンジニアなら、V8のECMAScript標準への対応の遅れに苛立ちを感じたはずです。</p>

<p>V8開発チームは、それを改善しようと新たなコンパイラ「TurboFan」を追加します。</p>

<p><img src="/wp-content/uploads/2017/06/c04.png" alt="" width="640" height="326" class="alignnone size-full wp-image-23699" srcset="/wp-content/uploads/2017/06/c04.png 640w, /wp-content/uploads/2017/06/c04-300x153.png 300w, /wp-content/uploads/2017/06/c04-207x105.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>2016年。「Ignition」と呼ばれる仕組みを追加しました。Ignitionには、ソースコードをいきなりマシンコードにするのではなく、バイトコード(マシンコードほどハードウェアに依存しない「中間コード」と呼ばれるもの)を生成するコンパイラーと、それを実行するインタプリターが内包されています。</p>

<p>そして、TurboFanはバイトコードを扱う形へと作り変えられました。そして現在、最新のVersionである5.9では、この2つの仕組みは既に使われていません。内部にコードこそ存在していますが、バイトコードの生成と解釈するインタープリターIgnitionと、PeakPerfを改善するための処理をするコンパイラーTurboFanだけで動作しているという状況です。</p>

<p><img src="/wp-content/uploads/2017/06/c05.png" alt="" width="640" height="325" class="alignnone size-full wp-image-23701" srcset="/wp-content/uploads/2017/06/c05.png 640w, /wp-content/uploads/2017/06/c05-300x152.png 300w, /wp-content/uploads/2017/06/c05-207x105.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>そして、これからまもなくリリースされる6.0では、コードとして完全にV8から削除されます。</p>

<p><img src="/wp-content/uploads/2017/06/c06.png" alt="" width="640" height="312" class="alignnone size-full wp-image-23702" srcset="/wp-content/uploads/2017/06/c06.png 640w, /wp-content/uploads/2017/06/c06-300x146.png 300w, /wp-content/uploads/2017/06/c06-207x101.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h3>「Ignition Interpreter」とは？</h3>

<p>中間コードを生成して実行するインタプリター。メモリ消費が小さく動く、Fast Startupも最適という特徴があります。</p>

<ul>
<li>モバイルなどのメモリの小さな環境で動かすのに最適。</li>
<li>Startup Timeに最適化すべきコードの実行に向いている。</li>
<li>TurboFanと組み合わせることで、実行速度を最適化できる。</li>
</ul>

<h3>「TurboFan」とは？</h3>

<p>主として、最適化を行うことを目的としたコンパイラー。</p>

<ul>
<li>使われ方としては、拡張的な感じ。ただ、あらゆる新しいJavaScript機能に対応していき、その場合も活用される。</li>
<li>WebAssemblyのバックエンドでもある。</li>
<li>最近はtry/catch/finallyとか、ES2015+の最適化が可能になった。</li>
</ul>

<h1>まとめ</h1>

<p>V8について、メモリ管理向けガーベジコレクター「Orinoco」など、さまざまな技術要素が進化し、語り尽くせないほどのトピックがあるのですが、それはまた別の機会にお話しましょう。TurboFanへの完全移行、実態としてすでにほとんど終わった状況といっても過言ではありませんが、8年前とは全く異なる、Web・JavaScriptの変化に追従する大きな変化です。今後も楽しみですね。</p>
]]></content:encoded>
		
		<series:name><![CDATA[Google I/O 2017特集]]></series:name>
	</item>
		<item>
		<title>この1年、Webのパフォーマンスで変わったことは？──HTML5 Conference 2016</title>
		<link>/furoshiki/21501/</link>
		<pubDate>Thu, 27 Oct 2016 00:00:26 +0000</pubDate>
		<dc:creator><![CDATA[川田寛]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">/?p=21501</guid>
		<description><![CDATA[連載： HTML5 Conference 2016 特集 (6)こんにちは、ふろしきです。HTML5 Conference 2016の当日は、38度近くの熱があり、発表時はろれつが回ってませんでした。しかし、伝えたいこと...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/html5-conf2016/" class="series-403" title="HTML5 Conference 2016 特集" data-wpel-link="internal">HTML5 Conference 2016 特集</a> (6)</div><p>こんにちは、<a href="https://twitter.com/_furoshiki" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ふろしき</a>です。HTML5 Conference 2016の当日は、38度近くの熱があり、発表時はろれつが回ってませんでした。しかし、伝えたいことは伝えられたと思っています。その内容とは…</p>

<p>「この1年でWebのパフォーマンスの技術にどんな動きがあったのか」</p>

<p>というダイジェスト。ここで話した3つのテーマについて、本記事でもご紹介。</p>

<p><img src="/wp-content/uploads/2016/10/kawada2.jpg" alt="" width="640" height="455" class="alignnone size-full wp-image-21557" srcset="/wp-content/uploads/2016/10/kawada2.jpg 640w, /wp-content/uploads/2016/10/kawada2-300x213.jpg 300w, /wp-content/uploads/2016/10/kawada2-207x147.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h1>1. レイアウト処理を減らす</h1>

<p>HTML5がバスワードするよりもずっと前から、CSSでアニメーションさせることはごくごくあたりまえ。JSが扱えないデザイナーであっても手軽にアニメーションできる良い世界になりました。しかしそこに、モバイルが出現したことで、JSだけで満足という人たちもCSSの機能を活用しなくてはいけなくなりました。</p>

<p>モバイルのUIによくありがちなのが、あるコンポーネントの形状を変化させるようなアニメーションや、スワイプ操作のような指の位置に応じてコンポーネントを動かすもの。それを描画するとなると、CPUはあまりにも非力で、GPUの力を借りることが求められています。CSSはGPUと相性がよいため、JSからCSSの機能を呼び出して効率的にGPUを活用するということが求められています。</p>

<p>そのアプローチについては、HTML5 Experts.jpでも「<a href="https://html5experts.jp/furoshiki/19276/" data-wpel-link="internal">モバイルWebのUIを速くする基本テクニックがわかる──Google I/O 2016 High Performance Web UI</a>」で紹介していますので、本記事では簡単にだけ説明。</p>

<p>GPUでできることは、極めてシンプル。ある四角形の描画結果を、どの位置に表示させるのか、拡大縮小させるのか、回転させるのか、といった変更加えるだけ。それだけでいいというのであれば、CPUを介さず、GPUのみで描画処理を完結させることができます。</p>

<p>これをブラウザで行う場合は、ある特定のDOMとその配下にあるDOMの描画結果をGPU側に転送し、GPU側にどういう描画を行わせるのか指示を送ることで、高速に処理させます。その間、操作はすべてCSSのプロパティを使って行うことになります。</p>

<p><img src="/wp-content/uploads/2016/10/3-1.jpg" alt="3" width="640" height="392" class="alignnone size-full wp-image-21515" srcset="/wp-content/uploads/2016/10/3-1.jpg 640w, /wp-content/uploads/2016/10/3-1-300x184.jpg 300w, /wp-content/uploads/2016/10/3-1-207x127.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>CSSも、従来の <code>left</code> や <code>top</code> といった、レイアウトを操作するようなものではなく、 <code>transform</code> プロパティ経由で指定。 JS上で、以下のように指定することで、CPUによるレイアウト処理を避けつつ、GPUで描画の位置のみを変えるというもの。</p>

<p></p><pre class="crayon-plain-tag">// ある要素の横の位置を移動
elem.style.transform = `translateX(#{position}%)`;</pre><p></p>

<p>この方法は一昔前には泥臭いとされ、バッドプラクティスと考えられていました。しかしそれも、最近は <code>will-change</code> というCSSプロパティが正式に標準化の流れに入ったことで、考えが改められています。GPU上に描画結果を保存させるのはバッテリー消費が大きいため、開始時に <code>will-change: transform;</code> で有効にし、終了時には <code>will-change: none;</code> で解除する、という流れになります。</p>

<p>簡単な例をあげると、以下の通りです。</p>

<p></p><pre class="crayon-plain-tag">// スワイプ時、指の位置にあわせてコンポーネントを左右に動かす。
class MovableComponent {
  constructor(elem) {
    this.elem = elem; // 動かす対象のコンポーネントのDOM
  }
  // ある要素の横の位置移動を開始
  function begin(beginX) {
    this.x = beginX; // 開始位置をセット
    this.elem.style.willChange = 'transform'; // GPU側に描画結果を置く
  }
  // 位置を変更(指の位置がかわるごとに呼び出される)
  move(currentX) {
    this.x = currentX; // 現在の位置をセット
  }
  // 描画(requestAnimationFrameで毎回呼び出される)
  render() {
    this.elem.style.transform = `translateX(#{this.x}px)`;
  }
  // 横移動の完了
  end() {
    this.elem.style.willChange = 'none'; // 解除
  }
}</pre><p></p>

<h1>2. スクロールイベントを減らす</h1>

<p>ブラウザのscrollイベントが、スクロールの滑らかさを落としてしまう。とはいえ、「どれだけスクロールされたのか？」というのに応じて何かしらのJSの処理を動かしたくなるという需要はなくならず、できるかぎりパフォーマンスを上げようという努力はされてきました。</p>

<p>2015年の4月にChromium Blogにポストされた「<a href="http://blog.chromium.org/2015_04_01_archive.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Chromium Blog
News and developments from the open source browser project
</a>」は有名な話です。Chromeではブラウザ上で動作するタスクに優先度を与え、JSの処理やブラウザ側の内部で行われる処理のうち、スクリーン上への描画が関わるタスクを優先的に扱うようにすることで、スクロールの滑らかさを損なわないようにしようという取り組み。確かに、ユーザーの体感としてパフォーマンスは上がったようにみえるでしょう。</p>

<p>しかしこの問題、その本質は、イベント自体が無駄に多く呼び出されてしまっているというところが大きかったりします。したがって、ユーザーワールド側でも、scrollイベントを毎回素直に実行するのではなく、頻度を落として実行するThrottlingという方法が一般的になっています。</p>

<p>これらはパフォーマンスを改善する上で、たしかに有効ではあります。ただ、デベロッパーが本当にやりたいことに目をむけ、そこにより特化した機能をブラウザ側が持てば、もっと良い解決につながるのは間違いありません。ハードウェアが貧弱で、スレッドの扱いに制約の多いブラウザでは、そこに踏み込んだアプローチが求められています。</p>

<p>scrollイベントの利用ケースで、かなり多いもののひとつに「画像の遅延読み込み」があげられます。例えば、ATF(Above The Fold : Webページアクセス直後にスクリーン内に映り込む領域)の表示を速くしたい！それこそ、headタグ内の大量のCSSファイルやトップの巨大な画像ファイルに帯域を譲らないことには高速化が困難ということになれば、ATF外にある画像ファイルは後から読み込んだほうがいい、ということになります。もちろん、サーバーの負荷を下げるという用途でも活用されるでしょう。</p>

<p>それを解決する方法として、Web標準「<a href="https://www.w3.org/TR/resource-priorities/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Resource Priorities</a>」にて、lazyloadというプロパティをHTMLのタグに追加しようという流れが生じ、IE11にも実装されたのですが、「そもそもそういう用途で使われるようなプロパティは追加されるべきなのか？」「本来JSであったり、より低レイヤーなアプローチで解決すべきでは？」という意見もあり、削除されてしまいました。</p>

<p>あれから2年が経ち、lazyloadは理想的な形で実現できるようになりました。それが「<a href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Intersection Observer</a>」です。</p>

<p>Intersection Observerは、スクロール時に特定のDOMがスクリーン上に現れるタイミングでイベントを発火させてくれます。したがって、scrollイベントよりも軽量な上、scrollイベントの多くのユースケースを巻き取ることができます。そもそもDOMの位置を取得する、scrollTop、offset、getBoundingClientRect、といったプロパティやメソッドは、本記事の1章でもあげたような、レイアウト処理というヘビーな処理を呼び出しのタイミングで必要とする場合がある。それも無くなるとなれば、一石二鳥でlazyloadのような類の処理を最適化できるというわけです。</p>

<p>以下、使い方の例。jQuery.lazyloadのようなものを実装するとしたら、以下のようになります。</p>

<p></p><pre class="crayon-plain-tag"><!--
  画像を遅延読み込みさせる要素。
-->
<img src='dummy.gif' data-original='original.jpg' alt='hoge' class="lazyload"></pre><p>
</p><pre class="crayon-plain-tag">// 遅延読み込みをさせる専用のObserverを生成
let imageLazyLoader = new IntersectionObserver((changes) =&gt; {
  // イベント発火のタイミングで、遅延読み込みさせる
  changes.forEach((change) =&gt; {
    let image = change.target;
    image.src = image.getAttribute('data-original');
  });
}, {
  rootMargin: "120% 0" // 読み込みを開始するタイミング
});
// 遅延読み込みさせたいimg要素を取り出し、Observeさせる
let images = Array.from(document.querySelectorAll('img.lazyload'));
images.forEach((image) =&gt; {
  imageLazyLoader.observe(image);
});</pre><p></p>

<h1>3. タスクキューの待ちを減らす</h1>

<p>最後に、タスクの最適化の話です。ここの話については、ピクシブのブログのエントリー「<a href="http://inside.pixiv.net/entry/2015/12/24/182248" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">JSがブラウザを固めてつらいので、新しいAPI「requestIdleCallback」を使うことにした</a>」でも取り上げてますので、ざっくりと背景と概要を。</p>

<p>元々は、2016年頃にMicrosoft側が「setImmediateをちゃんと実装しよう！」と。Microsoftのプラットフォームにおいて、多くのユーザーがsetImmediateを利用しているということを、W3C Web Performance WGのMLで問題提議し、 <code>setTimeout(fn,0)</code> を使ってタスクを遅延実行させるバッドプラクティスを緩和しようという提案から始まった話です。こうした悩みは「requestAnimationFrameで解決されるものだ！」という意見もあったのですが、現実問題としてはそうはうまくいかないというのは、フロントエンドをやっているエンジニアなら感じられたはずです。</p>

<p>そもそもこの問題はどこから生じたのか？一昔前のビデオカードが、１つのスレッドでしか描画を扱えないという制約があった。そういった背景もあり、現在のブラウザもまた、ブラウザの内部の処理からJSで実装したユーザーワールドの処理に至るまで、その多くのUIスレッドと呼ばれる単一のスレッドだけで処理しざる得ない状況となった。その恩恵というべきか、JSはこれだけ単一スレッドで処理実行させることに進化したのですが！JSでやることが多くなってしまった今、本記事の2章でも語られたような「タスクの優先度」に手を加えないことには、解決出来ない問題も多くなったのです。</p>

<p>こうした中ででてきたのが、requestIdleCallbackという機能です。</p>

<p>2章にもでてきた、Chromeのスクロールパフォーマンスを改善した、パフォーマンス周りを専門としているGoogleのエンジニア<a href="http://research.google.com/pubs/RossMcIlroy.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ross McIlroy</a>ら。彼らが、Microsoftがだした「setImmediateを全ブラウザでちゃんと実装しようぜ！」という案をはねのけて提案したのがこのrequestIdleCallback。</p>

<p>scrollイベントの改善で、彼らはあくまでブラウザ側のタスクの優先度に対して手を加えたわけですが、ここにきてデベロッパーが作ったJSの処理。ユーザーワールドで実行されるものについても、優先度のようなものを与えて、タスクが実行されるタイミングをうまく制御しようという提案をしたのでした。scrollイベントで培ったノウハウを広げようとしたんだろうなぁと、私は推測してます。</p>

<p>requestIdleCallbackはどういうものか？scrollイベントの一件では、緊急度の高いブラウザ内のタスクを、あらゆるタスクよりも優先して速く実行するというものでした。一方でrequestIdleCallbackは、ユーザー側の体験としてパフォーマンスが低いという状況を生み出しがちな、緊急度が低いユーザーワールドのタスクを、あらゆるタスクよりも低く実行するというもの。ブラウザ側だけじゃ限界があるから、デベロッパー側でもなんとかする術というのを提供したといったところです。</p>

<p>その仕組はとてもシンプルで、処理されることを待っているタスクがあれば絶対に実行しない。無ければそのタイミングで実行しようというもの。</p>

<p><img src="/wp-content/uploads/2016/10/20151224013042.jpg" alt="20151224013042" width="640" height="450" class="alignnone size-full wp-image-21540" srcset="/wp-content/uploads/2016/10/20151224013042.jpg 640w, /wp-content/uploads/2016/10/20151224013042-300x211.jpg 300w, /wp-content/uploads/2016/10/20151224013042-207x146.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>サンプルは以下の通り。</p>

<p></p><pre class="crayon-plain-tag">var hd = requestIdleCallback( =&gt; {
  // タスクキューが空になってから実行されるタスク
},{
  timeout: 10000 // 何msであきらめるか。
});</pre><p></p>

<h1>最後に</h1>

<p>CPUからGPUに処理を移したいというお話から、それでもどうしようもないシングルスレッド問題を、いかにして効率的に運用するのかというお話まで。GPUがデベロッパーを幸せにしたり、不幸にされたからどうにかしようとしたり、という感じで、GPUとブラウザのパフォーマンス問題は切っても切り離せないようですね。</p>

<p>ちなみに、この記事を書いている今、TPACというイベントが開かれ、パフォーマンスに関する議論も行われています。そこでは様々な議論が繰り広げられているのですが「Measuring and improving scroll latency (~30m; rbyers)」というスクロールをもっと良くしようよという話や、「Paint metrics」といったレイアウト処理のさらに先の描画系の発展的な話であったり、「Long Tasks API」みたいな、requestIdleCallbackとか以前にタスクの処理時間長くね？ってところをなんとか変えていこうよという議論もあったりします。</p>

<p>個人的に注目しているのは、以前からデベロッパーの間で薄っすら思われていた、SPAの時にブラウザのナビゲーション計測系のAPIが役に立たないのだけどどうするの？って問題に注目しているところです。SPAと一言でいっても、Ruby on RailsのTurbo Linksのようなものもあり、ブラウザの持つページ遷移機能が活用されないケースがある中で、パフォーマンス計測はどうあるべきなのか。「ナビゲーションの開始」と断定することが困難であり、それゆえに画面の切り替わりにどの程度の時間がかかったのかわからないこの問題を、今後どう扱うのかが議論されるようです。</p>

<p>一通り終わったなぁ、パフォーマンス周りの機能整備、なんて思ったのですが、よくよく考えたら実態にそこまで即した感じでもないんですよね。今後も様子を見ておきたいと思います。それでは！</p>
]]></content:encoded>
		
		<series:name><![CDATA[HTML5 Conference 2016 特集]]></series:name>
	</item>
		<item>
		<title>モバイルWebのUIを速くする基本テクニックがわかる──Google I/O 2016 High Performance Web UI</title>
		<link>/furoshiki/19276/</link>
		<pubDate>Fri, 08 Jul 2016 00:00:28 +0000</pubDate>
		<dc:creator><![CDATA[川田寛]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[I/0 2016]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[モバイル]]></category>

		<guid isPermaLink="false">/?p=19276</guid>
		<description><![CDATA[こんにちは、ふろしきです！ 私はHTML5 Experts.jpで、過去2年ほどGoogle I/Oの情報を発信し、Web技術の変化についてお伝えしてきました。振り返るとGoogleは、2014年にモバイルWebの提唱と...]]></description>
				<content:encoded><![CDATA[<p>こんにちは、<a href="http://furoshiki.hatenadiary.jp/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ふろしき</a>です！</p>

<p>私はHTML5 Experts.jpで、過去2年ほどGoogle I/Oの情報を発信し、Web技術の変化についてお伝えしてきました。振り返るとGoogleは、2014年に<a href="https://html5experts.jp/furoshiki/8582/" data-wpel-link="internal">モバイルWebの提唱と技術要素の拡大</a>を図り、2015年からは「<a href="http://furoshiki.hatenadiary.jp/entry/2015/06/01/122537" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">RAIL（モバイルWebが目指すべきパフォーマンス指標）</a>」や「<a href="http://myakura.hatenablog.com/entry/2015/11/18/053939" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Progressive Web Apps（アプリのように振る舞うWeb）</a>」といった、モバイルとの親和性が高いWebを作り出すための&#8221;考え方&#8221;を推し進めました。今年2016年は、さらにそれを踏み込んでいったという感じがします。</p>

<p>今回のI/Oで取り上げるのもそのひとつ。毎度お馴染みGoogle Developer Advocateの<a href="https://twitter.com/aerotwist" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Paul Lewis</a>氏による 「<a href="https://events.google.com/io2016/schedule?sid=59ba8126-111e-e611-a517-00155d5066d7#day3/59ba8126-111e-e611-a517-00155d5066d7" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">High performance web user interfaces</a>」です。彼は、モバイルにおいて、時に<strong>アプリのように振る舞うこと</strong>が求められる昨今のWeb、すなわち「Progressive Web Apps」について、UIで起こりがちなパフォーマンス問題と、その改善方法について紹介しています。</p>

<p><img src="/wp-content/uploads/2016/05/31.jpg" alt="31" width="640" height="361" class="alignnone size-full wp-image-19332" srcset="/wp-content/uploads/2016/05/31.jpg 640w, /wp-content/uploads/2016/05/31-300x169.jpg 300w, /wp-content/uploads/2016/05/31-207x117.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>※ この講演、動画無しでは説明が難しかったり、前提知識も多かったりするので、私でかなりアレンジ・要約して紹介しています。より詳細に内容を知りたい場合は、<a href="https://events.google.com/io2016/schedule?sid=59ba8126-111e-e611-a517-00155d5066d7#day3/59ba8126-111e-e611-a517-00155d5066d7" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ソース</a>をみることをオススメします！</p>

<h1>Webは時として、モバイルアプリのような体験が求められる</h1>

<p>モバイルにおいて、ホームスクリーンは重要な場所だ。人々はホームスクリーンから、目的を達成するためのアプリを起動する。Webは、<a href="https://developer.chrome.com/multidevice/android/installtohomescreen" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Add to Homescreen</a>を使うことで、ホームスクリーンからWebサイトへアクセスすることができるようになった。</p>

<p>するとどうなるか。このホームスクリーンをよくみてほしい。どれがWebで、どれがネイティブアプリなのかは見分けがつかないだろう。Google Mapsなんかはネイティブにみえるけれど、他はまったく想像がつかない。しかしこれらが、Google Mapsと同様にネイティブアプリにみえるなら、Webはネイティブアプリのように振る舞うことが求められている。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/06/eef129cc7f2d6302d8f0c7b0529934c5.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/06/eef129cc7f2d6302d8f0c7b0529934c5.png" alt="スクリーンショット 2016-06-06 23.14.36" width="640" height="294" class="alignnone size-full wp-image-19582" srcset="/wp-content/uploads/2016/06/eef129cc7f2d6302d8f0c7b0529934c5.png 640w, /wp-content/uploads/2016/06/eef129cc7f2d6302d8f0c7b0529934c5-300x138.png 300w, /wp-content/uploads/2016/06/eef129cc7f2d6302d8f0c7b0529934c5-207x95.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>パフォーマンスモデル、インタラクションモデルの2つによって、Webはモバイルネイティブアプリのような振る舞いをえることができる。Progressive Web Appsを実現することができる。今日はこの2つのモデルのうち、パフォーマンスモデルの話をしたい。</p>

<p>昨年は、<a href="https://twitter.com/paul_irish" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Paul Irish</a>や<a href="https://twitter.com/igrigorik" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ilya Grigorik</a>などの私のチームのメンバーが、「RAIL」というパフォーマンスモデルについて話した。RAILとは、Responseは0.1秒、Animationは16ミリ秒、Idleは50ミリ秒、Loadは1秒で動作すべきというもの。ただ、それを聞いた人々は、たまに勘違いをする。この4つの要素は、どれも全て、最も重要なこととして語ってしまうのだ。それは間違っている。</p>

<p>例えば、Webサイトにおいて、タップした時に求められるのは、4つの要素のうちLoadが重要になる。Idleが重要になることはそこまでない。そして、ホームスクリーンからタップして起動されるProgressive Web Appsでは、ResponseやAnimationが重要になる。Webサイトをつくるのと、Progressive Web Appsをつくるのでは、求められることが違う。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/06/fa9feaef46461db0ff943d0dcca3099a.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/06/fa9feaef46461db0ff943d0dcca3099a.jpg" alt="スクリーンショット 2016-06-11 17.19.02" width="640" height="481" class="alignnone size-full wp-image-19663" srcset="/wp-content/uploads/2016/06/fa9feaef46461db0ff943d0dcca3099a.jpg 640w, /wp-content/uploads/2016/06/fa9feaef46461db0ff943d0dcca3099a-300x225.jpg 300w, /wp-content/uploads/2016/06/fa9feaef46461db0ff943d0dcca3099a-207x156.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>さて、このようにパフォーマンス面で求められることが異なるProgressive Web Apps。そこに、3つのコンポーネントがある。Side Navigation、Swipeable Cards、Expand an Collapse。これらを実現するセオリーを紹介しよう。</p>

<h1>1. Side Navigation</h1>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/07/a8b14ec6d320cc19a86bb10650d79c5c.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/07/a8b14ec6d320cc19a86bb10650d79c5c.jpg" alt="スクリーンショット 2016-07-03 22.27.14" width="640" height="385" class="alignnone size-full wp-image-19946" srcset="/wp-content/uploads/2016/07/a8b14ec6d320cc19a86bb10650d79c5c.jpg 640w, /wp-content/uploads/2016/07/a8b14ec6d320cc19a86bb10650d79c5c-300x180.jpg 300w, /wp-content/uploads/2016/07/a8b14ec6d320cc19a86bb10650d79c5c-207x125.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>まずは、このコンポーネント。メニューボタンをタップすると左からスライドインするバー。これは、2つのElementによって構成される。半透明の黒い背景と、サイドメニューを表示する領域だ。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/07/0007f280db2411a1c5629b23c9035c49.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/07/0007f280db2411a1c5629b23c9035c49.jpg" alt="スクリーンショット 2016-07-03 23.18.35" width="640" height="352" class="alignnone size-full wp-image-19959" srcset="/wp-content/uploads/2016/07/0007f280db2411a1c5629b23c9035c49.jpg 640w, /wp-content/uploads/2016/07/0007f280db2411a1c5629b23c9035c49-300x165.jpg 300w, /wp-content/uploads/2016/07/0007f280db2411a1c5629b23c9035c49-207x114.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>このサイドメニューの部分のCSSは非表示の時、CSSに<code>pointer-events: none;</code>を指定する。そして、表示されたタイミングで<code>pointer-events: auto;</code>を指定する。</p>

<p>そしてここからが大事な話。左から右、あるいは右から左に移動させる際に、transformを使う。ブラウザがDOMの位置を変更する際に、CPUを使ったレイアウト変更してはいけない。GPUの力を借りて、描画位置を変更することで、最適なパフォーマンスを得ることができる。</p>

<p>例えば、一昔前。サイドメニューが左に消えている時にCSSは</p>

<p></p><pre class="crayon-plain-tag">.side-nav {
  position:       fixed;
  left:           -102%; /* DOMのレイアウト位置を左にずらしてメニューを隠す */
  top:            0;
  width:          100%;
  height:         100%;
  over-flow:      hidden;
  pointer-events: none;
}</pre><p></p>

<p>と、<code>left: -102%</code>で隠す。これは一般的な方法だった。しかし、描画を高速に処理できるGPUの恩恵を受けたいなら、transformを使って以下のように記述する。</p>

<p></p><pre class="crayon-plain-tag">.side-nav {
  position:       fixed;
  left:           0;                 /* DOMのレイアウト位置は常に0のまま */
  top:            0;
  width:          100%;
  height:         100%;
  over-flow:      hidden;
  pointer-events: none;
  transform:      translateX(-102%); /* 描画の位置を左にずらすことでメニューを隠す */
  will-change:    none;              /* &lt;- これは何！？ */
}</pre><p></p>

<p>サイドメニューのDOMのレイアウト位置としては、x位置の<code>left</code>もy位置の<code>top</code>も、0のまま。横幅<code>width</code>も縦幅<code>height</code>も、100%ということで、全面を覆っているという扱いになる。しかし、<code>transform: translateX(-102%);</code>で描画の位置自体を、左に寄せている。</p>

<p>そして、ここで登場するのが<code>will-chanage: none；</code>だ。</p>

<p>一昔前に<code>transform: translateZ(0);</code>をCSSプロパティに指定して、パフォーマンスを改善するというハックが出回ったのをご存知だろうか。このCSSが指定されると、描画には必然的にGPUの力が必要になるため、強制的にGPUに描画を依頼することになる。GPUの恩恵を受けるために活用されたこのバッドノウハウは、<code>will-chanage: transform；</code>という新しいCSSプロパティをWeb標準として追加することによって、同様のことを実現できるようにした。(※注:実態はブラウザ対応の問題もあり、今も<code>transform: translateZ(0);</code>を使うのが一般的)</p>

<p>ただ、<code>transform: translateZ(0);</code>や<code>will-chanage: transform；</code>といったCSS指定は、常時ビデオカード上のRAMメモリーに描画結果をテクスチャーとして保存することになる。モバイル環境では、バッテリー消費などに悪影響を及ぼすことになる。動作するタイミングだけ<code>will-chanage: transform；</code>を指定し、動作しない時は無効化<code>will-chanage: none；</code>するといい。これが、バッテリー消費パフォーマンスと描画速度パフォーマンスのトレードオフ問題に対する、落とし所だ。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/07/1518b8d765c003f2c4c92df1c282624d.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/07/1518b8d765c003f2c4c92df1c282624d.jpg" alt="スクリーンショット 2016-07-04 0.37.11" width="640" height="479" class="alignnone size-full wp-image-19974" srcset="/wp-content/uploads/2016/07/1518b8d765c003f2c4c92df1c282624d.jpg 640w, /wp-content/uploads/2016/07/1518b8d765c003f2c4c92df1c282624d-300x225.jpg 300w, /wp-content/uploads/2016/07/1518b8d765c003f2c4c92df1c282624d-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>黒背景については、<code>will-change: opacity;</code>というプロパティがあり、transformと同様の方法で、高いパフォーマンスで描画させることができる。(※ JSの実装については、「2. Swipeable Cards」にノウハウが似ているので割愛)</p>

<h1>2. Swipeable Cards</h1>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/07/e80ab460bd4bdf5ce0c4cbeddc8b80d8.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/07/e80ab460bd4bdf5ce0c4cbeddc8b80d8.jpg" alt="スクリーンショット 2016-07-03 22.27.37" width="640" height="386" class="alignnone size-full wp-image-19947" srcset="/wp-content/uploads/2016/07/e80ab460bd4bdf5ce0c4cbeddc8b80d8.jpg 640w, /wp-content/uploads/2016/07/e80ab460bd4bdf5ce0c4cbeddc8b80d8-300x181.jpg 300w, /wp-content/uploads/2016/07/e80ab460bd4bdf5ce0c4cbeddc8b80d8-207x125.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>CSSを使ったパフォーマンス改善のテクニックの他に、注意しなくてはいけないのが、スワイプ操作時のコンポーネントの移動処理。ユーザーからの指の位置状況を入力し、それをスクリーン上に反映しなくてはいけない。この際、有用なのが「ゲームループ」のノウハウだ。</p>

<p>描画のイベントは常に、1/60秒ごとに発生する。対してスワイプのイベントは、常に一定には発生しない。描画のタイミングにはあわせてくれないのだ。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/07/1c83d9b8767367275cca087cc1dd9000.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/07/1c83d9b8767367275cca087cc1dd9000.jpg" alt="スクリーンショット 2016-07-04 1.05.35" width="640" height="364" class="alignnone size-full wp-image-19982" srcset="/wp-content/uploads/2016/07/1c83d9b8767367275cca087cc1dd9000.jpg 640w, /wp-content/uploads/2016/07/1c83d9b8767367275cca087cc1dd9000-300x171.jpg 300w, /wp-content/uploads/2016/07/1c83d9b8767367275cca087cc1dd9000-207x118.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>そこで、スワイプにより発生するイベントについては、変数に位置情報だけを記録する。そして、描画時のイベントでは、記録された位置情報を元に、CSSを通じて描画位置変更をおこなう。</p>

<p>スワイプの開始時・移動時・終了時は以下の通り。<code>this.startX</code>、<code>this.currentX</code>、<code>this.targetX</code>といった変数に、現在の位置や、移動すべき位置を記録している。</p>

<p></p><pre class="crayon-plain-tag">/**
 * スワイプ開始
 */
onStart(evt) {

  // スワイプの開始位置を記録する
  this.startX = evt.pageX || evt.touches[0].pageX;
  this.currentX = this.startX;

  // cardの移動が開始されたことを記録する
  this.draggingCard = true;

  // will-change: transform; を有効にする
  this.target.style.willChange= ‘transform’;

  // カード上の要素にイベントを伝播させないように
  evt.preventDefault();

  // アニメーションを開始する
  requestAnimationFrame(this.update);
}

/**
 * スワイプ移動時
 */
onMove(evt) {

  // スワイプの現在地点を記録する
  this.currentX = evt.pageX || evt.touches[0].pageX;

}

/**
 * スワイプ終了時
 */
onEnd(evt) {

  // cardを削除すべきかどうか判定する
  let translateX = this.currentX - this.startX;
  const threshold = this.cardWidth * 0.35;
  if( Math.abs(translateX) &gt; threshold ) {

    // cardの移動先をスクリーンの外へ(※cardは削除)
    this.targetX = (translateX &gt; 0) ? this.cardWidth : -this.cardWidth;

  } else {

    // cardの移動先を最初の位置へ(※cardは削除されない)
    this.targetX = 0;

  }

  // cardの移動が終了されたことを記録する
  this.draggingCard = false;
}</pre><p></p>

<p>描画のタイミングにrequestAnimationFrameから呼び出されるコールバックで、先ほどの位置情報を元に反映していく。</p>

<p></p><pre class="crayon-plain-tag">/**
 * 描画内容の変更
 */
update(evt) {

  // 次の描画タイミングでも自身を呼び出す
  requestAnimationFrame(this.update);

  // スワイプ中の場合
  if( this.draggingCard ) {

    // 現在の位置を描画させる
    this.translateX = this.currentX - this.startX;

  // スワイプが完了している場合
  } else {

    // カードを削除するかしないかに応じて指定の場所に能動的に移動する
    this.translateX += (this.targetX-this.translateX)/4;

  }

  // CSSプロパティを経由してGPUに変更を伝える
  this.target.style.transform = `translateX(${this.translateX}px)`;
}</pre><p></p>

<p>(※ この後の処理については、「3. Expand and Collapse」にノウハウが似ているので割愛。)</p>

<h1>3. Expand and Collapse</h1>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/07/20934ecb9653e0b4ca6c9b68f442ecef.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/07/20934ecb9653e0b4ca6c9b68f442ecef.jpg" alt="スクリーンショット 2016-07-03 22.27.51" width="640" height="345" class="alignnone size-full wp-image-19948" srcset="/wp-content/uploads/2016/07/20934ecb9653e0b4ca6c9b68f442ecef.jpg 640w, /wp-content/uploads/2016/07/20934ecb9653e0b4ca6c9b68f442ecef-300x162.jpg 300w, /wp-content/uploads/2016/07/20934ecb9653e0b4ca6c9b68f442ecef-207x112.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>タップすると、領域が広がり全体化されるUIコンポーネント。CSSではどうするのか？もちろん、ここまで説明してきた「transform」を活用する！では、JSについてはどうか？実は、「2. Swipeable Cards」とは異なり、スワイプ操作でなくタップによって、自動的にアニメーションする。この点で、より効率的な実装が求められる。</p>

<p>まず、アニメーションについて、動作中の状態はJS上で持たない。動作前後の状態だけを、CSSプロパティを通じてGPUに指示する。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/07/9cac4ec846ad6ecf66df6cfa3fe74323.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/07/9cac4ec846ad6ecf66df6cfa3fe74323.jpg" alt="スクリーンショット 2016-07-04 1.54.47" width="640" height="237" class="alignnone size-full wp-image-19990" srcset="/wp-content/uploads/2016/07/9cac4ec846ad6ecf66df6cfa3fe74323.jpg 640w, /wp-content/uploads/2016/07/9cac4ec846ad6ecf66df6cfa3fe74323-300x111.jpg 300w, /wp-content/uploads/2016/07/9cac4ec846ad6ecf66df6cfa3fe74323-207x77.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p></p><pre class="crayon-plain-tag">// 変化量を計算する
invert.x = first.left - last.left;
invert.y = first.top - last.top;
invert.sx = first.width / last.width;
invert.sy = first.height / last.height;

// 変化後の状態をCSSプロパティを通じてGPUに指示
card.style.transformOrigin = ‘0 0’;
card.style.transform =
    `translate(${invert.x}px, ${invert.y}px)
      scale(${invert.sx}, ${invert.sy})`;</pre><p></p>

<p>そのままでは、タップした要素は一瞬にして全体化されてしまう。どのようにして何ミリ秒もかけて徐々に広げていくか？その方法は、CSSで指定する。JSではない。原理的には、従来よく使われているCSSアニメーションだ。</p>

<p></p><pre class="crayon-plain-tag">.cards {
  transition: transform 0.2s cubic-bezier(0,0,0.3.1); // アニメーションさせる
}</pre><p></p>

<p>ここまで、Progressive Web Applsのパフォーマンス改善の話をしてきたが、「<a href="http://bit.ly/render-perf" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google DevelopersのRendering peformance</a>」が役に参考になる。一読するといいだろう。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/07/3969bb8d861ac4399b9de045c3863743.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/07/3969bb8d861ac4399b9de045c3863743.jpg" alt="スクリーンショット 2016-07-04 2.13.00" width="640" height="391" class="alignnone size-full wp-image-19992" srcset="/wp-content/uploads/2016/07/3969bb8d861ac4399b9de045c3863743.jpg 640w, /wp-content/uploads/2016/07/3969bb8d861ac4399b9de045c3863743-300x183.jpg 300w, /wp-content/uploads/2016/07/3969bb8d861ac4399b9de045c3863743-207x126.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<h1>Progressive Web Appsのパフォーマンス改善。要はこう言いたかった</h1>

<p>いかがでしたでしょうか？文字数の制限やコンテキストの高さもあり、多くのエンジニアに伝わるようかなりアレンジしてみましたが、ご理解いただけましたでしょうか？</p>

<p><a href="https://twitter.com/aerotwist" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Paul Lewis</a>氏が言いたかったことは単純な話です。先ほどのGoogle Developersの記事にもありますが、Progressive Web AppsにおけるAnimationやReactionの課題は、いかにしてブラウザのレンダリング処理における「レイアウト」を減らすか、という話です。この講演は、そのTIPS集といえます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/07/fc525d40355e9e5ea2564f21ab3a910a.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/07/fc525d40355e9e5ea2564f21ab3a910a.jpg" alt="スクリーンショット 2016-07-04 2.19.41" width="640" height="352" class="alignnone size-full wp-image-20002" srcset="/wp-content/uploads/2016/07/fc525d40355e9e5ea2564f21ab3a910a.jpg 640w, /wp-content/uploads/2016/07/fc525d40355e9e5ea2564f21ab3a910a-300x165.jpg 300w, /wp-content/uploads/2016/07/fc525d40355e9e5ea2564f21ab3a910a-207x114.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>今日のノウハウ、特に新しいというわけでもなく2年前には既に実践されていたことです。実際のところ多くの現場では、OnsenUIやIonicのようなUIライブラリを活用することになり、このあたりの話を意識することはないのでしょう。ただ、Webのサービスを作っているフロントエンドエンジニアにとっては、ライブラリの有無に関係なく知っておくべき知識のように思えます。サイドメニューについては、Webサイトであっても鉄板のUIコンポーネントなので、Progressive Web Appsか否かはもはや関係ないノウハウだったに違いありません。</p>

<p>Webがモバイルに順応していくことは、今後もさらに求められていきます。これは、フレームワークやライブラリに限った話ではなく、トータルにみたWeb、フロントエンドへの要求に変化を与えるに違いません。</p>

<p>今後も、モバイルとWebの関わりに、目が離せませんね。</p>
]]></content:encoded>
			</item>
		<item>
		<title>これからのモバイル向けWeb制作──The Next Generation Mobile Web</title>
		<link>/furoshiki/15144/</link>
		<pubDate>Fri, 26 Jun 2015 01:00:12 +0000</pubDate>
		<dc:creator><![CDATA[川田寛]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google I/O]]></category>
		<category><![CDATA[パフォーマンス]]></category>
		<category><![CDATA[モバイル]]></category>

		<guid isPermaLink="false">/?p=15144</guid>
		<description><![CDATA[連載： Google I/O 2015 特集 (4)最近、モバイルではネイティブ一強という状況にみえます。Webはあまり注目されません。今後も同じ状況が続くのでしょうか？そのことについて、Google I/O 2015の...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/google_io_2015/" class="series-313" title="Google I/O 2015 特集" data-wpel-link="internal">Google I/O 2015 特集</a> (4)</div><p>最近、モバイルではネイティブ一強という状況にみえます。Webはあまり注目されません。今後も同じ状況が続くのでしょうか？そのことについて、Google I/O 2015のセッション「The Next Generation Mobile Web」が参考になります。補足を加えつつ翻訳してみましたので、どうぞご覧ください。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/f29abf68c0f445a56f7dfc2747f2f6d9.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/f29abf68c0f445a56f7dfc2747f2f6d9.jpg" alt="スクリーンショット 2015-06-23 15.13.24" width="640" height="292" class="alignnone size-full wp-image-15669" srcset="/wp-content/uploads/2015/06/f29abf68c0f445a56f7dfc2747f2f6d9.jpg 640w, /wp-content/uploads/2015/06/f29abf68c0f445a56f7dfc2747f2f6d9-300x137.jpg 300w, /wp-content/uploads/2015/06/f29abf68c0f445a56f7dfc2747f2f6d9-207x94.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<h1>But What About Mobile</h1>

<p>Webはパワフルな技術だ！これからも、ビジネスをもっと盛り上げていく。2014年、Eコマースは低く見積もっても1.5兆ドルの規模になった。そんな中、モバイルは何を変えたのか？ユーザにどんなインパクトを与えたのか？</p>

<p>モバイルは経済のシフト、デスクトップが担っていた領域の変化だ。パフォーマンスが求められるような動作も、従来のPCとは違い、バッテリーで動いているデバイス上で実現しなくてはいけない。必要とされる機能も完全に変わってしまった。プッシュ通知はモバイルのポテンシャルを高める上で重要なのだが、Webにそれはできなかった。結果、ネイティブの方が当然良く見えるわけだ。</p>

<p><img src="/wp-content/uploads/2015/06/1142563afd4b16f188a4fbcb59137e37.jpg" alt="スクリーンショット 2015-06-23 15.30.34" style="width:320px;float:right;padding-left:10px" class="alignnone wp-image-15673" srcset="/wp-content/uploads/2015/06/1142563afd4b16f188a4fbcb59137e37.jpg 640w, /wp-content/uploads/2015/06/1142563afd4b16f188a4fbcb59137e37-300x185.jpg 300w, /wp-content/uploads/2015/06/1142563afd4b16f188a4fbcb59137e37-207x127.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" />しかし、我々は全てをネイティブアプリに置き換えるべきなのだろうか？ネイティブにはいいところがあるけれど、Webもまた負けないいいところがあるはずだ。</p>

<p>みなさんは、Chrome Dev Toolsがどれだけの人に使われているのかご存知だろうか？Androidは400万人/週だが、Dev Toolsは2,500万人/週に使われている。そして、素晴らしいことに、今もなお増加し続けている。全ての人が巨大で複雑なWebサイトを作っているわけじゃないし、中にはあまり上手くWebサイトを作れていない人もいる。けど、少なくともDev Toolsを使っているみなさんは十分にスキルが高い。今からするこの話は、そんなWebを愛する2,500万人のあなたたちに伝えたい。</p>

<h1>Reach</h1>

<p>Webサイトはツリー型だ。例えば以下の図だと、ノードにあたるのが<a href="https://www.pinterest.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Pinterest.com</a>みたいなサイトで、あなたたちのサイトはその葉にあたる。URLからURLへ、ノードから葉へ飛ぶ。異なるサイトであっても、リンクからリンクへ飛ぶことはそんなに難しいことじゃない。サイトの奥地へだって行ける。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/95a6fa84e4c5674d4d394ca513b17a7f.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/95a6fa84e4c5674d4d394ca513b17a7f.jpg" alt="スクリーンショット 2015-06-23 16.59.35" width="640" height="346" class="alignnone size-full wp-image-15677" srcset="/wp-content/uploads/2015/06/95a6fa84e4c5674d4d394ca513b17a7f.jpg 640w, /wp-content/uploads/2015/06/95a6fa84e4c5674d4d394ca513b17a7f-300x162.jpg 300w, /wp-content/uploads/2015/06/95a6fa84e4c5674d4d394ca513b17a7f-207x112.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>人間が使うモバイルアプリは平均12から20と言われている。しかし一方で、アクセスされるWebサイトは、一ヶ月あたり100ドメイン以上だ。それはWebが、リンクを使って簡単にアクセスできるからだ。USにおいて、85%のリテーラーはモバイル上のトラフィックがWeb経由でやってくる。これがWebの持つパワーなのだ。</p>

<h1>Performance</h1>

<p>では、これらのリーチに対して、Webページはどの程度のパフォーマンスが必要なのか？ページの読み込み時間か？いや、それでは十分とは言えない。実際にはもっと様々なメトリクスがある。スクロールだってサクサク動かなくちゃいけないし、アニメーションも60fpsで動かすべきだ。ただ、どんなパフォーマンスをどれぐらい速くすれば十分なのかは、なかなかわからない。</p>

<p>その答えとして「RAIL」というコンセプト挙げている。Reaction、Animation、Idle、Loadの略称だ。RAILでカギとなっている考え方は「When is performance &#8216;Good Enough&#8217;? When the user can&#8217;t perceive it.(十分な速さとは、ユーザがそれを気にしないことだ)」だ。そしてそれを実現するために、60fpsを意味する16.67ミリ秒、100ミリ秒、1秒という時間に注目している。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/4a57d3f075698caef5bacd6807a5b89f.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/4a57d3f075698caef5bacd6807a5b89f.jpg" alt="スクリーンショット 2015-06-23 17.39.31" width="640" height="345" class="alignnone size-full wp-image-15681" srcset="/wp-content/uploads/2015/06/4a57d3f075698caef5bacd6807a5b89f.jpg 640w, /wp-content/uploads/2015/06/4a57d3f075698caef5bacd6807a5b89f-300x162.jpg 300w, /wp-content/uploads/2015/06/4a57d3f075698caef5bacd6807a5b89f-207x112.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>RAILのR、Reaction Timeは、例えば画面にタップするなどのアクションに対して、100ミリ秒未満でリアクションすることを求めている。そうでないと、ユーザはそのアプリが、壊れているだとか遅いだとか感じるだろう。100ミリ秒未満で、ボタンの色を変えたりインジケーターを回したりすれば、フリーズしたようには見えない。</p>

<p>RAILのA、Animation Time。アニメーションは、16.67ミリ秒未満で動作することを求めている。RAILのI、Idle Timeについて。JavaScriptなどでデコードなどの重い処理を行うと、UIが固まってしまう。処理をチャンクを使うなどして分けて、Idleを作り出さなくてはいけない。その期間は50ミリ未満が望ましいだろう。そうすることで、RのReaction Timeの100ミリ秒未満は守られるだろう。</p>

<p>RAILのLは、みなさんもよく知っているLoad Timeだ。これは1秒未満が望ましい。ただ、これに関しては、Service Workerを使えば、読み込み時に動作中であることをユーザに伝えることができる。</p>

<p>Chrome開発チームには現在、約200人程度のエンジニアがいる。そしてその多くは、パフォーマンスを改善するために働いている。モバイルを良くしようと、様々な取り組みを行っている。その全てを深く語るには、時間が足りなさ過ぎている。一つだけ紹介すると、例えば「スケジューラー」。これはパフォーマンスを劇的に変えたと思っている。タスクの優先度が変わったことで、スクロールのパフォーマンスが大きく改善されたのだ。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/2076431dc9f44f8267098fa9046d04a7.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/2076431dc9f44f8267098fa9046d04a7.jpg" alt="スクリーンショット 2015-06-23 18.11.15" width="640" height="338" class="alignnone size-full wp-image-15684" srcset="/wp-content/uploads/2015/06/2076431dc9f44f8267098fa9046d04a7.jpg 640w, /wp-content/uploads/2015/06/2076431dc9f44f8267098fa9046d04a7-300x158.jpg 300w, /wp-content/uploads/2015/06/2076431dc9f44f8267098fa9046d04a7-207x109.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>パフォーマンス改善は、とても難しいことにみえるかもしれない。しかし臆することはない。博士号なんか取得していなくても、ちゃんとできる。Chrome Dev Toolを使って、サードパーティスクリプトであったり、リソースのパフォーマンスを計測して、問題を探るのだ。そして、RAILをゴールとして、パフォーマンス改善を行っていけばよいだろう。</p>

<h1>Engagement</h1>

<p>モバイルWebに欠けていたのは、エンゲージメントだ。しかし今、Webにはエンゲージメントを助けるたくさんの機能がある。ただ同時にそれは、セキュリティ面に大きな課題を抱えている。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/25f283076e8f93dddd3e89c5ee16f730.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/25f283076e8f93dddd3e89c5ee16f730.jpg" alt="スクリーンショット 2015-06-23 19.29.26" width="640" height="344" class="alignnone size-full wp-image-15690" srcset="/wp-content/uploads/2015/06/25f283076e8f93dddd3e89c5ee16f730.jpg 640w, /wp-content/uploads/2015/06/25f283076e8f93dddd3e89c5ee16f730-300x161.jpg 300w, /wp-content/uploads/2015/06/25f283076e8f93dddd3e89c5ee16f730-207x111.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>例えば、background sync(Service Worker)なんかは、Webページを閉じていても簡単にコンテンツの読み込みや送信ができてしまう。あなたが一ヶ月に100のサイトへアクセスするとして、その全てでbackground syncが有効になることは望まないだろう。質の悪いWebページにアクセスしようものなら、Background syncが裏で動き続け、バッテリはどんどん消耗されるなんてこともある。バッテリー効率の悪いネットワーク処理を、ガンガン動かすことが可能だからだ。</p>

<p>誰しも、初対面の相手は簡単には信頼しない。Webサイトオーナーとユーザーとの関係は、ゆっくりと築かれる。ネイティブはアプリのコピーがWebほど簡単ではない。ストアがいて、その開発元も明かされているからだ。しかしWebはオープンだ。パーミッション機能は慎重に作られていなくてはいけない。ユーザに確認して、パーミッションをWebサイト側へ与えることで、初めてリスクの高い機能は使えるようにしている。</p>

<p>さて、これらの機能のうち、有益なものを2つ紹介しよう。</p>

<p>一つ目が「Add to homescreen」だ。例えば興味をもったWebサイトがあったとする。そこに手軽にアクセスしたい。そういう時に、ホームスクリーン上へアイコンを配置しておき、ネイティブアプリのように手軽にアクセスできるようにしておくと、簡単にWebサイトへ飛べる。</p>

<p>実は、古くからそのような機能がブラウザについているのだけれど、設定メニューの中に隠れていたため、手軽では使えなかった。しかし今は、それができるAPIを提供している。これをWebサイト上から呼び出せば、以前より手軽になるだろう。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/a841e301993f92e87426d0e92e435a861.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/a841e301993f92e87426d0e92e435a861.jpg" alt="スクリーンショット 2015-06-23 20.17.32" width="640" height="344" class="alignnone size-full wp-image-15699" srcset="/wp-content/uploads/2015/06/a841e301993f92e87426d0e92e435a861.jpg 640w, /wp-content/uploads/2015/06/a841e301993f92e87426d0e92e435a861-300x161.jpg 300w, /wp-content/uploads/2015/06/a841e301993f92e87426d0e92e435a861-207x111.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>モバイルWebでユーザ体験を高める場合、ネイティブアプリのような、オフライン対応も重要になる。以前は、「App Cache」がその役割を担っていた。しかしそれは、始めること自体は簡単なのだけれど、メンテナンスにやっかいな問題を抱えている。失敗すると、Webサイトは簡単に動かなってしまう。これを改善し、柔軟なコントロールが行えるようにしたのが「Service Worker」だ。</p>

<p>Service Workerはオフラインで動くスクリプトで、Webサイトにアクセスするとまずそこに問い合わせが行われる。Service Workerは何をすべきか判断し、必要であればネットワークを通じてリソースを取得し、キャッシュへ置くことができる。その振る舞いから、クライアントサイドのJavaScriptプロキシなんて呼ばれていたりする。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/369ba25ed1f880652f2c6faf0cfd3efc.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/369ba25ed1f880652f2c6faf0cfd3efc.jpg" alt="スクリーンショット 2015-06-23 20.30.12" width="640" height="343" class="alignnone size-full wp-image-15701" srcset="/wp-content/uploads/2015/06/369ba25ed1f880652f2c6faf0cfd3efc.jpg 640w, /wp-content/uploads/2015/06/369ba25ed1f880652f2c6faf0cfd3efc-300x161.jpg 300w, /wp-content/uploads/2015/06/369ba25ed1f880652f2c6faf0cfd3efc-207x111.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>Google I/OのWebサイトなんかが良い例だ。Service Workerを使って、必要な全てのリソースをキャッシュに読み込んでいる。Gulpに「<a href="https://github.com/GoogleChrome/sw-precache" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">sw-precache</a>」というプラグインがある。それを使えば、簡単にService Workerのインテグレーションを、あなたの現場のワークフローへ組み込めるだろう。</p>

<p>Service Workerは、Webページが複数のタブが開かれていても、その全てと通信できる。また逆に、一つも開かれていなくても内部で生存している。それはランダムに起き上がって動くようなことはせず、基本的にはイベント駆動だ。ネットワークなどのイベントを検知して、スクリプトはストレージ内からメモリ上へ移される。だいたい50ミリ秒程度だろうか。その後、Service Workerの処理が実行される。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/07a91e6bb098b31501d1a459fe6f3f2e.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/07a91e6bb098b31501d1a459fe6f3f2e.jpg" alt="スクリーンショット 2015-06-23 20.45.46" width="640" height="345" class="alignnone size-full wp-image-15702" srcset="/wp-content/uploads/2015/06/07a91e6bb098b31501d1a459fe6f3f2e.jpg 640w, /wp-content/uploads/2015/06/07a91e6bb098b31501d1a459fe6f3f2e-300x162.jpg 300w, /wp-content/uploads/2015/06/07a91e6bb098b31501d1a459fe6f3f2e-207x112.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>モバイルであれば、ネイティブアプリのようにプッシュ通知を扱いたい考える事は必然であろう。Anish AcharyaはTechCrunchで「Notification Are The Next Platform(次のプラットフォームは通知だ)」と語っている。通知機能は、エンゲージメントを改革するのだ。</p>

<p>人々がアプリに長く時間を使うのは、人々が通知を受け取るからだ。モバイルの画面を見て、通知を受け取っているのを見て、そこでアプリを使う決断をする。ニュースサイト「<a href="http://www.theguardian.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">The Guardian</a>」はネイティブアプリを提供しているのだが、彼らは事件が起きた時に、そのニュースをプッシュ通知を通じて伝えると、40%のユーザがそこからやってきたそうだ。これはとても多い人数だ。</p>

<p>そんなプッシュ通知だが、今はブラウザから実行できるようになっている。一つの例として、The Guardianのある記事へアクセスした時に、その記事の更新をプッシュ通知を受け取ってみる。</p>

<p>通知の許可を、Webサイト上で行うことができる。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/52aab70da8979c5ed6c1d05556516172.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/52aab70da8979c5ed6c1d05556516172.jpg" alt="スクリーンショット 2015-06-23 20.57.29" width="640" height="342" class="alignnone size-full wp-image-15704" srcset="/wp-content/uploads/2015/06/52aab70da8979c5ed6c1d05556516172.jpg 640w, /wp-content/uploads/2015/06/52aab70da8979c5ed6c1d05556516172-300x160.jpg 300w, /wp-content/uploads/2015/06/52aab70da8979c5ed6c1d05556516172-207x111.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>その後、Chromeを閉じ、ユーザは作業を再開する。そして、記事が更新されると・・・この通り！プッシュ通知が飛んでくる。これは他のネイティブアプリと、同じように扱われている。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/fc0b304a5503fa4bae235cdc919e92e7.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/fc0b304a5503fa4bae235cdc919e92e7.jpg" alt="スクリーンショット 2015-06-23 21.02.02" width="640" height="344" class="alignnone size-full wp-image-15705" srcset="/wp-content/uploads/2015/06/fc0b304a5503fa4bae235cdc919e92e7.jpg 640w, /wp-content/uploads/2015/06/fc0b304a5503fa4bae235cdc919e92e7-300x161.jpg 300w, /wp-content/uploads/2015/06/fc0b304a5503fa4bae235cdc919e92e7-207x111.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>じつは、今サンプルとして紹介したThe Guardianは、今後本当にプッシュ通知を対応させる予定だ。SNSのFacebookや、商品を扱っているebayやticketmasterでも対応する予定だ。今後も増えていくことだろう。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/ce366b694a44a99489bf655e5c4cad83.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/ce366b694a44a99489bf655e5c4cad83.png" alt="スクリーンショット 2015-06-23 21.18.04" width="640" height="344" class="alignnone size-full wp-image-15708" srcset="/wp-content/uploads/2015/06/ce366b694a44a99489bf655e5c4cad83.png 640w, /wp-content/uploads/2015/06/ce366b694a44a99489bf655e5c4cad83-300x161.png 300w, /wp-content/uploads/2015/06/ce366b694a44a99489bf655e5c4cad83-207x111.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<h1>最後に</h1>

<p>いかがでしたか？</p>

<p>Reach、Performance、Engagementは非常に重要であり、これらが効果を上げれば、モバイルWebは上手くいく、というのがGoogleらの答えなようです。</p>

<p>「Web vs ネイティブ」という議論は散々行われてきましたが、彼らはそういう見方をしていないようですね。モバイルの本質を考え、そこからWebの立ち位置を明確化してきたように見えます。</p>

<p>よくよく考えてみたら、モバイルのホームスクリーンはブラウザのブックマーク機能と、そのユースケースに大きな違いはありません。そして、最近のプッシュ通知もまた、アプリの状態を表示するものというよりも、エンゲージメントの高い情報を目立つ所にリスト化しているだけのようにみえます。それはWebのサービスにおいて、メールの通知によって補っていた機能です。いまさら、驚くようなことでもありません。従来デスクトップでもやっていたことを、モバイルのユーザビリティに合わせてきたと捉えられます。</p>

<p>この考え方が、一日でも速く現場にも浸透してほしいですね。そのためにも、「Windows XPの悲劇の再来」にも見えるAndroidのフラグメント化が、一日でもはやく改善してくれることを祈っています。</p>
]]></content:encoded>
		
		<series:name><![CDATA[Google I/O 2015 特集]]></series:name>
	</item>
		<item>
		<title>HTML5が変える、エンタープライズITの可能性とこれから</title>
		<link>/furoshiki/9136/</link>
		<pubDate>Tue, 19 Aug 2014 00:00:16 +0000</pubDate>
		<dc:creator><![CDATA[川田寛]]></dc:creator>
				<category><![CDATA[システム開発]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[エンタープライズ]]></category>
		<category><![CDATA[モバイル]]></category>

		<guid isPermaLink="false">/?p=9136</guid>
		<description><![CDATA[連載： エンタープライズ開発特集 (1)こんにちは、川田です。今日からHTML5 Experts.jpでは「エンタープライズ開発特集」を始めます。第一弾の今回は、HTML5とエンタープライズITについてのオーバービューを...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/enterprise/" class="series-197" title="エンタープライズ開発特集" data-wpel-link="internal">エンタープライズ開発特集</a> (1)</div><p>こんにちは、川田です。今日からHTML5 Experts.jpでは「エンタープライズ開発特集」を始めます。第一弾の今回は、HTML5とエンタープライズITについてのオーバービューを語ります。サーバサイドのお話はわりとよく見ますが、フロントエンドにフォーカスしているというのは珍しいようにも思えますね。</p>

<p>IT自体が幅広い分野のビジネスや製品に変わりつつある昨今、「エンタープライズITの話をするぞ！」と言うと、いろんな方面の人からこう問われます。</p>

<h2>「そもそも、エンタープライズって何？」</h2>

<p>エンタープライズ、正式には「エンタープライズシステム」になりますが、直訳すれば「企業向けシステム」。一言で言うなら「企業のビジネスを支えるための仕組み」を意味します。企業の業務の効率化を進めたり、経営戦略や問題解決を進めるためのワークプロセス(仕事の進め方)と道具(アプリやインフラ)のことです。</p>

<p>エンタープライズのエンジニアの仕事は、技術的な観点から、経営を良くする方法を提案したり、業務の進め方を設計したり、そのために必要な道具(アプリやインフラ)も調達したり、なければ自分たちで開発したり。サーバからクライアントまで、必要なら机の配置の一つまでデザインする(ネットワークも！)。ぶっちゃけ、ITじゃない方が合理的なら、IT化しないなんてのも提案する。スーパーのレジだって「効率化とかどうでもいいから最安値で作って」と言われたら、ソロバンを薦めてしまうという。それが私たちの仕事です。「SCM」とか「CRM」というキーワードで検索すると、そのニュアンスが伝わるかもしれません。</p>

<p>さて、ここで定義したエンタープライズ（システム）において常に関心が高いテーマとしては、「1.システムの運用」「2.業務の効率化」「3.アーキテクチャ」が挙げられると思います。これらの観点から、「HTML5」という技術要素が、これから先の企業のITをどのように良くしていけるのかをみてみましょう。</p>

<h2>1. 「システムの運用」はどう変わるのか？</h2>

<p>古今東西、エンタープライズは、システムをできる限りいじらずに、長く運用させることがビジネスとして成立する市場です。欧米においても、古いものは企業と政府に最後まで残り続ける傾向にあるというのが、共通の認識になっています。日本ではInternet Explorer（以下、IE）が高い影響力を持っており、多くの企業がIEの特定のバージョンをサポート期間ギリギリまで使い倒すという方法に走りがちです。しかし、今それが変わることを求められています。</p>

<p>マイクロソフトのサポートは基本は最低10年というルールですが、IEにおいてはもはやそのルールは全く通用しません。昨年、<a href="http://support.microsoft.com/lifecycle/search/?sort=PN&amp;alpha=Windows+8&amp;Filter=FilterNO" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Windows8.1発売時にWindows 8版IE10のサポート期間が短縮化</a>され、そして今年の7月にはとうとう、<a href="http://blogs.msdn.com/b/ie/archive/2014/08/07/stay-up-to-date-with-internet-explorer.aspx" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">2016年1月12日以降、最新のバージョン以外はサポート対象外とするというアナウンス</a>を行いました。これは、Google Chromeと同じアップデートのポリシーで、システムはこれからIEの最新バージョンがリリースされる都度、IEのバージョンを上げ続けることが求められています。現時点では、約1.5年周期ぐらいになりそうです。</p>

<p>マイクロソフトは、エンタープライズもコンシューマーも、どちらであってもIEが常に最新のバージョンで運用されるよう改善を進めてきています。その成果として、現在の最新のIEはHTML5に準拠し、高い相互運用性を確保しました。これはつまり、バージョン間の動作の違いが非常に小さいということを意味します。彼らとしては、<strong>ブラウザの「バージョンアップ」が、従来の「サービスパック適用」や「セキュリティアップデート」程度のものとして扱われれば</strong>という狙いがあるようです。</p>

<p>Windows XPのSP2は、元々Vistaになる予定の全く別ものなOSと言われていたのですが、それが運用の中でうまく適用できたというのであれば、これはほんの些細な問題なのかもしれません。運用の進め方さえうまく定着すれば、<strong>業務システムのクライアント部分は、OSやミドル、ハードウェアのライフサイクルから開放され、セキュリティ・信頼性・パフォーマンスが最適化された状態で、長期に渡り利用することが可能となります。</strong>これはエンタープライズITにとって、HTML5がもたらす大きな価値の一つと言えるでしょう。</p>

<p>最新のIEへの移行、HTML5化を進めるには、以下の機能・ツールが有用です。欧米ではユーザー企業だけで音頭を取って進めていけるため、そのモチベーションは非常にシンプルです。しかし、日本はSIerがシステム開発の中心にいるため、調整にはかなり苦戦するかもしれません。2016年1月までと非常に期間は短いのですが、ユーザー企業・SIerの両方が一丸となりこの取り組みを進め、ユーザー企業のシステム費用の最適化と成長に貢献できればよいですね。</p>

<ul style="border:1px solid silver;background-color:#EEE;padding:5px">
<li><a href="https://html5experts.jp/osamum_ms/4401/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">modern.IE</a>：IEのマルチバージョンテストや、問題点を検出するツール。無償のものが多い。何千台も端末がある場合、段階的に最新バージョンのIEへ移行を進めていくにあたり、このツールが有用になる。</li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/dn640687.aspx" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Enterprise Mode</a>：IE11以上で、暫定的にIE7/8の動作をエミュレートさせる機能。最新のIEに移行した後も、古いIE特化のアプリを動かすことができる。</li>
<li><a href="http://furoshiki.hatenadiary.jp/entry/2014/01/06/030742" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Compat Inspector</a>：IE8以下の依存性の高い作り込みを検出するツール。Enterprise Modeも長くはサポートされる保証がないため、最新のIEへ移行した後、このツールを活用して改修を進め、Enterprise Modeをなくしていくことが求められる。</li>
</ul>

<h2>2. 「業務の効率化」はどう変わるのか？</h2>

<p>近年、デスクトップPC以外のコンピュータのポテンシャルが注目を集めています。ノートPCにタブレット、スマートフォンにウェアラブルと、デスクトップPCにはない機能、ワークフローのモデルを持ったコンピューターを活用することで、従来の業務をより効率的に変えていこうという考え方が、欧米で広がりをみせています。最近のアンケート結果を見ていると、日本でもモバイルの業務活用に抵抗感がなくなりつつあるようですので、恐らくこれから広がっていくことでしょう。</p>

<p>例えば、ホワイトカラーの場合、マネージャーの決裁をリアルタイム化させるという用途が有名です。スマートフォンに決裁イベントの発生を通知させ、内容を表示し、タッチで完了させるというワークフローを実現させるというものです。部下にも使えるものだと、スケジューラとの連携です。これからミーティングが始まるということを、移動時間も含めて計算し、事前に通知するという仕組みです。このような、様々な種類のデバイスを連動させた業務の設計方法を「モビリティ」と呼びます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/08/a.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/08/a.png" alt="モビリティという新たな業務の組み立て方の一例" width="630" height="527" class="alignnone size-full wp-image-9940" style="border:1px solid silver" srcset="/wp-content/uploads/2014/08/a.png 630w, /wp-content/uploads/2014/08/a-300x250.png 300w, /wp-content/uploads/2014/08/a-207x173.png 207w" sizes="(max-width: 630px) 100vw, 630px" /></a></p>

<p>モビリティは、単純にWebアプリをタブレットやスマートフォンで見えるようにするだけでは意味がありません。コンピューターが持つ特性に合わせて、設計することが求められます。例えば、先ほどの決裁のシステムにおいて、「通知」という機能がなかったらどうなるでしょうか？タッチ操作に最適化されていなかったらどうなるでしょうか？</p>

<p>使いにくくて、結局デスクトップ型やノートPC型のコンピュータを使うようになるのがオチです。<strong>UXへの理解がないことには、導入がうまくいかないのがモビリティ</strong>なので、モバイルの活用とUXは、多くの場合セットとして扱われているはずです。業務系のUXは、Webのサービスのようにリピーターを増やすためのものではなく、毎日使う道具を効率化させることに意味があり、このあたりの評価軸の違いにも注目すべきでしょう。</p>

<p>また、スマートフォンやタブレットといった道具側にも工夫が必要です。企業向けとして利用する場合、セキュリティの考え方、開発効率にも意識しなくてはいけません。セキュリティについては「<a href="http://searchconsumerization.techtarget.com/tutorial/Mobile-enterprise-application-platforms-A-primer" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">MEAP(Mobile Enterprise Application Platform)</a>」が、「<a href="http://www-03.ibm.com/software/products/en/worklight-foundation" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">IBM Worklight</a>」「<a href="http://global.sap.com/campaigns/digitalhub-mobile-platform/index.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">SAP Mobile Platform</a>」「<a href="http://www.oracle.com/technetwork/jp/developer-tools/adf-mobile/overview/index.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Oracle ADF Mobile</a>」などなど、数えきれない程の製品によって、実用化もコモディティ化も進んでいます。一方で開発効率については、HTML5によるハイブリッドアプリケーション開発が注目を集め、これを実装するための「<a href="http://cordova.apache.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Apache Cordova</a>」がMEAP製品の間でも独占的シェアを得ています。HTML5自体、そもそもモバイルから注目を集め出したわけで、そこまで想像に難くないはずです。</p>

<h2>3. 「アーキテクチャ」はどう変わるのか？</h2>

<p>最後に、統合化を目指したアーキテクチャについてです。ここでのアーキテクチャとは、個別のシステムにおけるものではなく、全体最適化の観点におけるアーキテクチャです。一つの業務をこなすのに、いくつものログインを繰り返す煩わしさ、複数のシステムに同じ情報を投入しなくてはいけない状況など、連携できていない状況の改善という意味です。</p>

<p>以下3つのポイントが、これからのアーキテクチャを決定付けているように思えます。</p>

<ul style="border:1px solid silver;background-color:#EEE;padding:5px">
<li><strong>業務ロジックがAPIを持ち始めている：</strong>出足はやや遅れましたが、私の感覚として日本の企業でもパッケージの活用が進んでいるように見えます。パッケージ製品は、<a href="http://scn.sap.com/community/netweaver" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">SAP NetWeaver</a>や<a href="https://developer.salesforce.com/page/Salesforce_APIs" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Salesforce APIs</a>といったAPIを持つのがもはや当たり前で、標準としては<a href="http://www.odata.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">OData</a>が広がっています。インフラも<a href="http://aws.amazon.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">AWS</a>のAPIがデファクト標準化しつつあり、認証基盤ですらも<a href="http://saml.xml.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">SAML</a>や<a href="http://openid.net/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">OAuth(OpenID Connect)</a>のような標準のAPIへとシフトしています。<a href="http://www.gsma.com/oneapi/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">OneAPI</a>やBONDIみたいなモバイル向けアプリ開発の世界観も気になるところです。スクラッチ開発においても、ライブラリ/フレームワークも豊富になり、REST(like)を中心としてAPIの実装コストも落ちていくことでしょう。</li>
<li><strong>APIを活用する製品が増えている：</strong><a href="http://www-01.ibm.com/software/analytics/cognos/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">IBM Cognos</a>や<a href="http://www.oracle.com/us/solutions/business-analytics/business-intelligence/overview/index.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Oracle BI</a>などのBIツールや、<a href="http://camel.apache.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Apache Camel</a>のようなルーティングエンジン、<a href="http://backbonejs.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Backbone.js</a>や<a href="https://angularjs.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">AngularJS</a>といったJavaScriptフレームワークでさえもREST(like)に対応するのが当たり前という状況です。サーバでAPIを繋げる<a href="http://apigee.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Apigee</a>や、クライアントでAPIを繋げる<a href="https://ifttt.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">IFTTT</a>なんかも面白い傾向です。例えスクラッチ開発であっても、アプリは標準的なAPIで繋げた方が、長期的に見てできる事の幅が広がっている時代に突入しています。</li>
<li><strong>開発ツールがモバイルファースト化している：</strong>モバイルはネットワーク環境が不安定であることが前提であり、サーバサイドとは疎結合にしてクライアントで処理をすることが求められています。こうした中、マイクロソフトの「<a href="http://blogs.msdn.com/b/somasegar/archive/2014/05/12/mobile-first-cloud-first-development-visual-studio-apache-cordova-tooling-and-cloud-optimized-net-futures.aspx" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Mobile-first, Cloud-first Development</a>」、IBMの「<a href="https://www.ibm.com/mobilefirst/us/en/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Mobile First</a>」と、各製品ベンダの開発ツールがどんどんモバイルファースト前提に変わっています。個人的には、<a href="http://www.oracle.com/us/solutions/business-analytics/business-intelligence/mobile/overview/index.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Oracle BI Mobile</a>みたいな、完成された製品でさえもモバイル前提なことに、未来を感じさせられます。</li>
</ul>

<p>このような状況を鑑みると、世の中のアプリケーションはC/Sモデルへと回帰しているように見えます。クライアントは多くの場合、やはりHTML5のエコシステムの恩恵を受けたくなるはずです。本メディアでも過去に取り上げたような、<a href="https://html5experts.jp/albatrosary/3191/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">佐川夫美雄氏の考えるWebベースのリッチアプリケーション開発</a>もその一つと言えます。現在はまだ、APIの集約はBIツールなどを活用してサーバサイドで行うのが一般的なようですが、これから先は、徐々にクライアント側へと移っていくことも想像に難くないはずです。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/08/d6940b0c38258d9311986c932cbe9406.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/08/d6940b0c38258d9311986c932cbe9406.png" alt="APIの集約化がクライアントへと進出する" width="631" height="353" class="alignnone size-full wp-image-9919" style="border:1px solid silver" srcset="/wp-content/uploads/2014/08/d6940b0c38258d9311986c932cbe9406.png 631w, /wp-content/uploads/2014/08/d6940b0c38258d9311986c932cbe9406-300x167.png 300w, /wp-content/uploads/2014/08/d6940b0c38258d9311986c932cbe9406-207x115.png 207w" sizes="(max-width: 631px) 100vw, 631px" /></a></p>

<p>「あの企業みたいに、こういう経営情報を可視化したい！」「こういうコスト削減を目指したい！」となった時に、「世の中の道具が全く何も使えない！」なんてことにならないためにも、少しずつでよいので世の中の流れに乗っていけるといいですね。素直に新しいベンダ製品を活用していたら、勝手にこんな作りになるわけですが、いかんせんOSSによるコスト最適化、マルチベンダ化、大量のレガシー資産などの要因が邪魔して、そうも簡単にいかないというのが厄介なところでしょう。</p>

<p>さてさて、今回「UX」に「MEAP/ハイブリッドアプリ開発」に「業界標準フォーマット」に「ツール/フレームワーク」と、フロントエンドに関わるいろんなキーワードが出てきましたが、これらをより深堀りしたものが、本メディアにて「エンタープライズ特集」として取り上げられます。企業のビジネスを技術面から良くする、ヒントを与えてくれるに違いありません。</p>

<p>どうぞ、お楽しみに！</p>
]]></content:encoded>
		
		<series:name><![CDATA[エンタープライズ開発特集]]></series:name>
	</item>
		<item>
		<title>Googleはなぜモバイルに力を入れるのか？これからのWebパフォーマンスで注力すべきポイント</title>
		<link>/furoshiki/8582/</link>
		<pubDate>Fri, 25 Jul 2014 04:00:17 +0000</pubDate>
		<dc:creator><![CDATA[川田寛]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Google I/O 2014]]></category>
		<category><![CDATA[パフォーマンス]]></category>
		<category><![CDATA[モバイル]]></category>

		<guid isPermaLink="false">/?p=8582</guid>
		<description><![CDATA[連載： Google I/O 2014 特集 (4)こんにちは、川田です。Googleはここ最近、デスクトップ向けWebに対して、ほとんどの関心を失っているように見えます。HTML5ブームも過ぎて、やることがなくなってし...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/google-io-2014-2/" class="series-191" title="Google I/O 2014 特集" data-wpel-link="internal">Google I/O 2014 特集</a> (4)</div><p>こんにちは、川田です。Googleはここ最近、デスクトップ向けWebに対して、ほとんどの関心を失っているように見えます。HTML5ブームも過ぎて、やることがなくなってしまったのでしょうか？……いえいえ、そうでもありません。昨今の待ったなしで進む技術革新の中で、彼らは「ある問題」と戦っているようです。</p>

<h2>Webは「モバイル」中心の時代へ移っていく</h2>

<div style="float:right;margin-left:20px;margin-bottom:20px"><a href="https://html5experts.jp/wp-content/uploads/2014/07/f82880303ce2a094f6748c71ccd9e08c.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/f82880303ce2a094f6748c71ccd9e08c-300x187.png" alt="スクリーンショット 2014-07-10 11.33.15" width="300" height="187" class="alignnone size-medium wp-image-8596" srcset="/wp-content/uploads/2014/07/f82880303ce2a094f6748c71ccd9e08c-300x187.png 300w, /wp-content/uploads/2014/07/f82880303ce2a094f6748c71ccd9e08c-207x129.png 207w, /wp-content/uploads/2014/07/f82880303ce2a094f6748c71ccd9e08c.png 470w" sizes="(max-width: 300px) 100vw, 300px" /></a><br /><a href="http://investor.google.com/pdf/2014Q1_google_earnings_data.pdf" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google Inc. First Quarter 2014 Results</a></div>

<p>すでにご存知の方も多いと思いますが、GoogleのビジネスモデルはWebに強く依存しています。2014年1Qの決算で、Googleは全売上の約68%が自社のWeb系サービスの広告収入であり、約22%はAdsenseなどの他のWebサイト向けの広告であると報告しました。Webに依存したビジネスが実に9割を占め、1日に約120億円の収入をWebから得ています。もっと簡単に言えば、<strong style="font-size:130%">Webだけで、タイの国民全員の給料分ぐらい稼いじゃってます。</strong>当然、Webの進化をやめてしまうなんてことは、考えにくいでしょう。</p>

<p>彼らにとって、利用者がどこからWebにアクセスするのかは、とても重要な情報となります。むしろ、Googleに限らず、Webでサービスを提供している全ての人にとっても重要なことでしょう。人々は普段、どんなコンピュータを使っているのか？どのようなデバイスからインターネットにアクセスするのか？そのことが、私たちのビジネスにとって大きな意味を持ちます。</p>

<p>そしてここ最近、Googlerがいろいろな発表の場でよく口にしているのが「<strong>モバイル</strong>」というキーワードです。これから先、Webの利用者はモバイルからやってくると、Googleは考えているようです。そのことを証明するかのように、現場の開発者からマーケティング・経営者まで一丸となって、これからやって来るモバイルの時代に向けた取り組みをアピールしています。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/07/709f657b9e0fe7c6dc483643a3c959b2.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/709f657b9e0fe7c6dc483643a3c959b2.png" alt="Global Smartphone Shipment" class="alignnone size-medium wp-image-8640" srcset="/wp-content/uploads/2014/07/709f657b9e0fe7c6dc483643a3c959b2.png 640w, /wp-content/uploads/2014/07/709f657b9e0fe7c6dc483643a3c959b2-300x189.png 300w, /wp-content/uploads/2014/07/709f657b9e0fe7c6dc483643a3c959b2-207x130.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><em>&#8220;AndroidとChrome、2つの巨大なオープンプラットフォームについて。スマートフォンは2013年4Qに、3.15億台の出荷があった。Androidは毎年利用者が倍増しており、現在は10億ものアクティブユーザがいる。将来的にはAndroidを、50億人にリーチしたいと考えている。&#8221; &#8212;&#8212; Google 経営者 Sundar Pichai </em>(<a href="https://www.google.com/events/io" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google I/O 2014 &#8211; 2014.06.25</a>)</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/07/b6a9cba44576ea4e41bc39b49ba81fe01.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/b6a9cba44576ea4e41bc39b49ba81fe01.png" alt="デスクトップよりモバイルの方が売れているし、使われている" class="alignnone size-medium wp-image-8303" srcset="/wp-content/uploads/2014/07/b6a9cba44576ea4e41bc39b49ba81fe01.png 640w, /wp-content/uploads/2014/07/b6a9cba44576ea4e41bc39b49ba81fe01-300x221.png 300w, /wp-content/uploads/2014/07/b6a9cba44576ea4e41bc39b49ba81fe01-207x152.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><em>&#8220;2014年1月に、ChromeのレンダリングエンジンであるBlinkをどう変えていこうかという話し合いをした。結果としては『モバイルが大事』ということになった。デスクトップよりもモバイルの方が売れているし使われる。しかし開発者の立場から見ると、残念ながらWebよりネイティブの方が多いという状況だ。我々はHTML5の問題点をヒアリングし、改善を進めている。&#8221; &#8212;&#8212; Google Chrome開発者 及川卓也 </em>(<a href="http://atnd.org/events/51627" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML5 Night &#8211; 2014.06.14</a>)</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/07/1186279c58f3a02a633b4f41b3d2b4a81.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img style="border:1px solid gray" src="/wp-content/uploads/2014/07/1186279c58f3a02a633b4f41b3d2b4a81.png" alt="Mobile % of Total Global Internet Traffic(Mobile Web performance auditing - Paul Lewis)" class="alignnone size-medium wp-image-8406" srcset="/wp-content/uploads/2014/07/1186279c58f3a02a633b4f41b3d2b4a81.png 640w, /wp-content/uploads/2014/07/1186279c58f3a02a633b4f41b3d2b4a81-300x168.png 300w, /wp-content/uploads/2014/07/1186279c58f3a02a633b4f41b3d2b4a81-1024x576.png 1024w, /wp-content/uploads/2014/07/1186279c58f3a02a633b4f41b3d2b4a81-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><em>&#8220;アメリカの成人の34%にとって、主要のインターネットアクセスはスマートフォンだ。モバイルのトラフィックは増加しており、来年にも過半数のユーザがモバイルでインターネットを利用することになる。&#8221; &#8212;&#8212; Google Webコンテンツ開発者 Paul Lewis </em>(<a href="https://www.google.com/events/io" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google I/O 2014 &#8211; 2014.06.26</a>)</p>

<h2>モバイルであることが前提の、Webとパフォーマンス</h2>

<div style="float:right;margin-left:20px;margin-bottom:20px"><a href="https://html5experts.jp/wp-content/uploads/2014/07/IMGP0407.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/IMGP0407-300x168.jpg" alt="Device Lab" width="300" height="168" class="alignnone size-medium wp-image-8765" srcset="/wp-content/uploads/2014/07/IMGP0407-300x168.jpg 300w, /wp-content/uploads/2014/07/IMGP0407-207x116.jpg 207w, /wp-content/uploads/2014/07/IMGP0407.jpg 640w" sizes="(max-width: 300px) 100vw, 300px" /></a></div>

<p>モバイルは、Web開発者/制作者にとっては厄介な存在です。動作環境が増えるのですから、デザインにコーディング、動作テストと、やらなくてはいけない作業も増えてしまいます。Googleは、その手間をできる限り省き、コンテンツ制作に専念できるようにしようと考えています。その成果の一つが、「Material Design(マテリアル・デザイン)」です。</p>

<p>UXの向上を図る上で、デザインは重要です。ただ、デザインだけではどうにもなりません。「パフォーマンス」も欠かすことのできない重要な要素なのです。Google I/Oでは、多くのエンジニアが「Polymer」「Material Design」「Android」など、宝物のような名前がついたキーワードに目を奪われました。実際にメディアでも、これらのキーワードが大きく取り上げられています。しかし、冷静に見るとそれなりの数の「パフォーマンス」をテーマとしたセッションが開かれています。パフォーマンス改善はすごく地味だけど、すごく重要な取り組みと彼らは認識しているのです。</p>

<p>Googleでは「<a href="http://developers.google.com/speed/pagespeed/insights/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">PageSpeed Insights</a>」と呼ばれるサービスを提供しています。イベントに参加していると、割と頻繁に目に入りました。Paul Lewis氏のセッション「Mobile Web performance auditing」では、その活用方法についてかなり具体的なアイデアと共に紹介しています。その内容を見てみましょう。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/07/b5fbca375e400b80887bba4bbc6307eb.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img style="border:1px solid gray" src="/wp-content/uploads/2014/07/b5fbca375e400b80887bba4bbc6307eb.png" alt="PageSpeed Insightsサンプル" class="alignnone size-medium wp-image-8441" srcset="/wp-content/uploads/2014/07/b5fbca375e400b80887bba4bbc6307eb.png 640w, /wp-content/uploads/2014/07/b5fbca375e400b80887bba4bbc6307eb-300x195.png 300w, /wp-content/uploads/2014/07/b5fbca375e400b80887bba4bbc6307eb-207x134.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>「<a href="http://developers.google.com/speed/pagespeed/insights/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">PageSpeed Insights</a>」とは、Webに公開しているページのURLを与えると、そのページの問題点、改善方法を提案してくれるGoogleのサービスです。競合するものとして、マイクロソフトの「<a href="https://www.modern.ie/ja-jp" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">modern.IE site scan</a>」が挙げられますが、こちらはWebコンテンツのポータビリティを評価する方向に力を入れています。パフォーマンス改善という観点では、Google側の方がより尖っているという印象です。タブが「Mobile」が最初になっている点からも、彼らの作るツールがモバイルファーストの思考で動いているというのを感じとれます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/07/6098ddfd0579ccd63cf201a9ff334c15.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/6098ddfd0579ccd63cf201a9ff334c15.png" alt="PageSpeed Insights" class="alignnone size-medium wp-image-8763" srcset="/wp-content/uploads/2014/07/6098ddfd0579ccd63cf201a9ff334c15.png 640w, /wp-content/uploads/2014/07/6098ddfd0579ccd63cf201a9ff334c15-300x177.png 300w, /wp-content/uploads/2014/07/6098ddfd0579ccd63cf201a9ff334c15-207x122.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>さっそく、<a href="http://furoshiki.hatenadiary.jp/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">私がはてなで運営しているブログ</a>をPageSpeed Insightsで評価してみたところ、Mobile-60点/Desktop-28点/UX-99点という結果でした。Paul Lewis氏いわく、それでは全然ダメとのこと。PageSpeed Insightsでのスコアは、大体目安として、Mobile-85点以上/Desktop-90点以上/UX-100点が望ましいそうです。いくつか日本のブログサービスでテストしてみたのですが、この条件が満足できているのを見つけることができませんでした。それどころか、Google自身が提供しているサービス「Blog Spot」ですら、この条件を満足できていません。そこまで頑張らなきゃいけないのかと、その必要性に疑いの目を持ってしまいます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/07/1240ea7bf50ab91bbaae245f2b9422d2.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/1240ea7bf50ab91bbaae245f2b9422d2.png" alt="200ミリ秒の遅延が0.3%の機会損失につながる。" class="alignnone size-medium wp-image-8409" srcset="/wp-content/uploads/2014/07/1240ea7bf50ab91bbaae245f2b9422d2.png 640w, /wp-content/uploads/2014/07/1240ea7bf50ab91bbaae245f2b9422d2-300x168.png 300w, /wp-content/uploads/2014/07/1240ea7bf50ab91bbaae245f2b9422d2-1024x575.png 1024w, /wp-content/uploads/2014/07/1240ea7bf50ab91bbaae245f2b9422d2-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>ところが、Paul Lewis氏いわく、200ミリ秒の遅延が0.3%の機会損失に繋がると。パフォーマンスの改善が、そのまま収益に結びつくのだと強く主張しています。Webは速ければ速いほど、価値を発揮するのです。もちろん、それを実現するにはそれなりにコンピュータ科学の知識を必要とするわけですが、私たちエンジニアによる純粋な技術による改善で、利用者の増加に貢献できることが残されているというのは、大変喜ばしいことでしょう。</p>

<p>パフォーマンスの問題について、Paul Lewis氏は「Page Speed」と「Runtime」の2つの観点から、その対策方法について紹介がありました。この2つを軸に、他のGoogle I/Oのセッションの内容も交えながらその考え方について見つめてみましょう。</p>

<h2>Page Speedはどのように改善するのか？</h2>

<p>Page Speedの改善とは何か？単純に言えば「<strong>Webページの表示を3秒以下に抑えよう</strong>」ということです。そのための方法として、Paul Lewis氏は以下の方法を提案しています。</p>

<p><a style="float:right;width:200px" href="/wp-content/uploads/2014/07/585037d616244be479e892792bc9e4f3.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img style="border:1px solid gray;width:200px" src="/wp-content/uploads/2014/07/585037d616244be479e892792bc9e4f3.png" alt="スクリーンショット 2014-07-11 16.23.05" class="alignnone size-medium wp-image-8802" srcset="/wp-content/uploads/2014/07/585037d616244be479e892792bc9e4f3.png 400w, /wp-content/uploads/2014/07/585037d616244be479e892792bc9e4f3-300x171.png 300w, /wp-content/uploads/2014/07/585037d616244be479e892792bc9e4f3-207x118.png 207w" sizes="(max-width: 400px) 100vw, 400px" /></a></p>

<h3>1. リソースを最適化せよ(Optimize resources.)</h3>

<p>Webページを構成するデータのうち、平均63%が画像ファイルです。最適化が必要となります。画像ファイルの圧縮を改善すると、データ量は大きく削減されます。CSS/JavaScriptについても、不要なスペースなどを削って圧縮(Minify)するとよいでしょう。</p>

<p>(補足：のちに説明がありますが、これらはプリプロセッサーの活用を習慣付けるとよいでしょう。人間の手でやっていてはキリがないので、徹底的に自動化させてしまうことです。)</p>

<p><a style="float:right;width:200px" href="/wp-content/uploads/2014/07/5a025405c534207eb4e5aa1effb4b7bd.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img style="border:1px solid gray;width:200px" src="/wp-content/uploads/2014/07/5a025405c534207eb4e5aa1effb4b7bd.png" alt="スクリーンショット 2014-07-11 16.39.04" width="300" height="156" class="alignnone size-medium wp-image-8816" srcset="/wp-content/uploads/2014/07/5a025405c534207eb4e5aa1effb4b7bd.png 400w, /wp-content/uploads/2014/07/5a025405c534207eb4e5aa1effb4b7bd-300x156.png 300w, /wp-content/uploads/2014/07/5a025405c534207eb4e5aa1effb4b7bd-207x107.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<h3>2. リクエスト数を減らせ(Reduce the number of requests.)</h3>

<p>リクエストはWebページの表示をブロックさせることがあります。リクエスト数が減るとそれだけ表示が速くなことを意味します。</p>

<p>(補足：SPDYやHTTP2.0が関わってくると、リクエスト数だけでなく、コネクション数も重要になってきたりしますね。いずれにせよ、少ないことはよいことです)</p>

<p><a style="float:right;width:200px" href="/wp-content/uploads/2014/07/b464cb3d6f72936e5bab22190a4ba8cd.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img style="border:1px solid gray;width:200px" src="/wp-content/uploads/2014/07/b464cb3d6f72936e5bab22190a4ba8cd-300x168.png" /></a></p>

<h3>3. リダイレクトをやめろ(Avoid redirects.)</h3>

<p>リダイレクトにはDNSの名前解決、TCPコネクションの接続など、Webページの表示までに要する時間が長くなります。パフォーマンスを意識するなら、リダイレクトさせてはいけません。</p>

<p>(補足：モバイルの場合、よくあるのは「m.〜〜」というURLにリダイレクトされるケースです。当然ですが、その処理を行うためにWebページ読み込みのパフォーマンスは劣化することになります。日本の場合は、モバイル網のDNSサーバのパフォーマンスが問題となることも少なくありません)</p>

<p><a style="float:right;width:200px" href="/wp-content/uploads/2014/07/871614cfadc9da747294435964582b2a.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img style="border:1px solid gray;width:200px" src="/wp-content/uploads/2014/07/871614cfadc9da747294435964582b2a-300x167.png" alt="スクリーンショット 2014-07-11 16.34.24" width="300" height="167" class="alignnone size-medium wp-image-8813" srcset="/wp-content/uploads/2014/07/871614cfadc9da747294435964582b2a-300x167.png 300w, /wp-content/uploads/2014/07/871614cfadc9da747294435964582b2a-207x115.png 207w, /wp-content/uploads/2014/07/871614cfadc9da747294435964582b2a.png 400w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<h3>4. レンダリングの順序に優先度をつけろ(Prioritize for the critical rendering path.)</h3>

<p>Webページ全てを読み込んだ時間よりも、見えている領域の読み込み完了(Visually Complete)に、利用者は関心を示します。そこに優先度を高く持っていくべきです。</p>

<p>(※補足：実際に、W3CのWeb-perf WGでも、Resource Prioritiesという仕様の検討が進められていますね。jQueryだと、LazyLoadプラグインがあり、画像ファイルの読み込み順序をコントロールすることができます)</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/07/66714330ca5b3d556b9626ef265fa9371.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img style="border:1px solid gray" src="/wp-content/uploads/2014/07/66714330ca5b3d556b9626ef265fa9371.png" alt="GruntとGulp" class="alignnone size-medium wp-image-8818" /></a></p>

<p>一連の作業は、GruntやGulpが助けてくれます。利用してみるとよいでしょう。</p>

<h2>Runtimeはどのように改善するのか？</h2>

<p>Runtimeの改善とは何か？単純に言えば「<strong>Webページを60FPSで動かそう</strong>」ということです。一般的なディスプレイ(スクリーン)は約1/60秒周期で内容が更新されるため、アニメーションなどの処理はその特性に合わせていくことで、滑らかな動きを実現することができます。そのための方法として、Paul Lewis氏、Paul Irish氏は以下の方法を提案しています。</p>

<p><a style="float:right;width:200px" href="/wp-content/uploads/2014/07/b9a4c28453333283c8bb8f4e7ebdd9df.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img style="width:200px;border:solid 1px gray" src="/wp-content/uploads/2014/07/b9a4c28453333283c8bb8f4e7ebdd9df-300x129.png" alt="スクリーンショット 2014-07-11 17.59.45" width="300" height="129" class="alignnone size-medium wp-image-8836" srcset="/wp-content/uploads/2014/07/b9a4c28453333283c8bb8f4e7ebdd9df-300x129.png 300w, /wp-content/uploads/2014/07/b9a4c28453333283c8bb8f4e7ebdd9df-207x89.png 207w, /wp-content/uploads/2014/07/b9a4c28453333283c8bb8f4e7ebdd9df.png 400w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<h3>1. 変形や透過によるアニメーションは制限しろ(Restrict animations to transforms and opacity.)</h3>

<p>処理コストの高い描画計算処理は控えるべきです。DOMの形状が変わるとLayout処理のコストは増大するし、透過処理などはPaint処理をコスト増大させます。このような「Expensive Animations」は、約1/60秒以下での処理に収まらないことがあり、注意する必要があります。</p>

<p><a style="float:right;width:200px" href="/wp-content/uploads/2014/07/5a99bab98fe4b6a0118fc89419d18245.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img style="width:200px;border:solid 1px gray" src="/wp-content/uploads/2014/07/5a99bab98fe4b6a0118fc89419d18245-300x118.png" alt="スクリーンショット 2014-07-11 19.14.30" width="300" height="118" class="alignnone size-medium wp-image-8838" srcset="/wp-content/uploads/2014/07/5a99bab98fe4b6a0118fc89419d18245-300x118.png 300w, /wp-content/uploads/2014/07/5a99bab98fe4b6a0118fc89419d18245-207x81.png 207w, /wp-content/uploads/2014/07/5a99bab98fe4b6a0118fc89419d18245.png 600w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<h3>2. requestAnimationFrameを使え(Use requestAnimationFrame.)</h3>

<p>画面のリフレッシュレートに合わせて、アニメーション処理は実行させるようにしましょう。例えば、setIntervalなどを利用し、16ms周期でコールバックさせ擬似的にリフレッシュレートを合わせようとすると、タイミングがズレて無駄が起きます。画面のリフレッシュレートに合わせるには、requestAnimationFrameと呼ばれるAPIを利用する必要があります。</p>

<p><a style="float:right;width:200px" href="/wp-content/uploads/2014/07/0e865121fe9e28053257f81acab3b006.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img style="width:200px;border:solid 1px gray" src="/wp-content/uploads/2014/07/0e865121fe9e28053257f81acab3b006-300x162.png" alt="スクリーンショット 2014-07-11 17.45.05" width="300" height="162" class="alignnone size-medium wp-image-8839" srcset="/wp-content/uploads/2014/07/0e865121fe9e28053257f81acab3b006-300x162.png 300w, /wp-content/uploads/2014/07/0e865121fe9e28053257f81acab3b006-207x111.png 207w, /wp-content/uploads/2014/07/0e865121fe9e28053257f81acab3b006.png 640w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<h3>3. レイアウトの値を読み込んでから書き出せ(Read layout values, then write.)</h3>

<p>レイアウト(DOM)の値は変数のように扱ってはいけません。横幅などの取得が必要であれば、最初に取り出してキャッシュしておきましょう。読→書→読→書を繰り返すと、無駄なLayout処理が何度も発生するという「Layout Thrashing」という現象が起きます。読→読→書→書が理想です。</p>

<p><a style="float:right;width:200px" href="/wp-content/uploads/2014/07/afea6f5f4d6d46f7c0c2d6c63cf1eeb6.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img style="width:200px;border:solid 1px gray" src="/wp-content/uploads/2014/07/afea6f5f4d6d46f7c0c2d6c63cf1eeb6-300x133.png" alt="スクリーンショット 2014-07-11 17.53.25" width="300" height="133" class="alignnone size-medium wp-image-8840" srcset="/wp-content/uploads/2014/07/afea6f5f4d6d46f7c0c2d6c63cf1eeb6-300x133.png 300w, /wp-content/uploads/2014/07/afea6f5f4d6d46f7c0c2d6c63cf1eeb6-207x91.png 207w, /wp-content/uploads/2014/07/afea6f5f4d6d46f7c0c2d6c63cf1eeb6.png 600w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<h3>4. メモリ効率の高いJavaScriptを(Write fast, memory-efficiant Javascript.)</h3>

<p>メモリを消費するようなJavaScriptの記述方法は、Garbage Collection処理が発生し、1/60秒以内での処理が完結しなくなることがあります。JavaScriptの書き方に、工夫が必要です。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/07/0f091ce80cbc1c82251d2239150ba188.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/0f091ce80cbc1c82251d2239150ba188.png" alt="スクリーンショット 2014-07-11 19.40.31" class="alignnone size-medium wp-image-8843" srcset="/wp-content/uploads/2014/07/0f091ce80cbc1c82251d2239150ba188.png 640w, /wp-content/uploads/2014/07/0f091ce80cbc1c82251d2239150ba188-300x169.png 300w, /wp-content/uploads/2014/07/0f091ce80cbc1c82251d2239150ba188-1024x577.png 1024w, /wp-content/uploads/2014/07/0f091ce80cbc1c82251d2239150ba188-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>モバイルChromeの解析は、「chrome://inspect/」でできます。お試し下さい。</p>

<h2>難しくなってきている、なんて思いませんか？</h2>

<p>これまではデスクトップPCが一つあればなんとかなっていたWeb開発も、作るための環境と動かすための環境が分離されて、どんどん複雑になってきているなぁという感触を得ています。プレゼンの時も、わざわざカメラを切り替えてモバイルのスクリーンを表示したりなんかしてて「エレガントさに欠るなぁ」「面倒くさいことやってるなぁ」なんて思ったりもしました。もっと言えば、デモしている姿を見てて<strong style="font-size:130%">「モバイル、めちゃくちゃ使いにくそうに扱ってますよね！」「本当はPCでやりたいとか思っていませんか？」</strong>なんてことも、率直な印象として感じました。</p>

<p>こういう不満を感じられることは、本当の本当に幸せに思えたりもします。Googleが悪いとかAppleが悪いとかMicrosoftが悪いとかじゃなく、IT業界全体として、まだまだ発展途上にいると感じさせられるのです。これからもっとよくしようと、動き出せるきっかけがいくらでもあるように思えるのです。もっともっと、進化しますよ！</p>

<p>みなさんはどう思いますか？私はWebの未来に、夢を見過ぎでしょうか？</p>
]]></content:encoded>
		
		<series:name><![CDATA[Google I/O 2014 特集]]></series:name>
	</item>
		<item>
		<title>Navigation Timingだからできる、Webアプリを俯瞰したパフォーマンス計測(3/3)</title>
		<link>/furoshiki/6335/</link>
		<pubDate>Fri, 09 May 2014 00:00:31 +0000</pubDate>
		<dc:creator><![CDATA[川田寛]]></dc:creator>
				<category><![CDATA[システム開発]]></category>
		<category><![CDATA[Navigation Timing]]></category>
		<category><![CDATA[パフォーマンス]]></category>

		<guid isPermaLink="false">/?p=6335</guid>
		<description><![CDATA[連載： パフォーマンスチューニング (11)いよいよHTMLドキュメントのダウンロードと、画面上への表示です。この動作の仕組みから、TATの「終了」がいつなのかを追ってみましょう。「終了」についてはかなり奥が深く、Web...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/performance-tech/" class="series-149" title="パフォーマンスチューニング" data-wpel-link="internal">パフォーマンスチューニング</a> (11)</div><p>いよいよHTMLドキュメントのダウンロードと、画面上への表示です。この動作の仕組みから、TATの「終了」がいつなのかを追ってみましょう。「終了」についてはかなり奥が深く、Web標準でもそのプロセスを「<a href="http://www.w3.org/TR/html5/syntax.html#the-end" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">The End</a>」として定義はしていますが、それだけでは語りきれない難しさがあります。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/05/05.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/05.png" alt="05" class="alignnone size-medium wp-image-6353" srcset="/wp-content/uploads/2014/05/05.png 640w, /wp-content/uploads/2014/05/05-300x262.png 300w, /wp-content/uploads/2014/05/05-207x180.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<h2>4. TCP接続、5. HTTPリクエスト/レスポンス</h2>

<p>名前解決で得られたIPアドレスを使って、HTMLドキュメントが置かれたサーバへ「4. TCP接続」します。いわゆる、<a href="http://ja.wikipedia.org/wiki/3%E3%82%A6%E3%82%A7%E3%82%A4%E3%83%BB%E3%83%8F%E3%83%B3%E3%83%89%E3%82%B7%E3%82%A7%E3%82%A4%E3%82%AF" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">3ウェイハンドシェーク</a>というものです。サーバとの接続交渉が終わると、HTTPリクエストをサーバへ送信し、HTTPレスポンスを受け取ります。</p>

<p>HTTPレスポンスの結果からリダイレクトであることが発覚した場合、「2. キャッシュ確認」からやり直しです。この、リダイレクト動作にかかった時間もNavigation Timingでは取得でき、「<a href="http://www.w3.org/TR/navigation-timing/#dom-performancetiming-redirectstart" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">redirectStart</a>」「<a href="http://www.w3.org/TR/navigation-timing/#dom-performancetiming-redirectend" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">redirectEnd</a>」の各プロパティを通じて取得することができます。</p>

<p>HTTPレスポンスから得られたデータは、いったん蓄積され、この後のDOMの生成で利用されることになります。</p>

<h2>6. DOM生成</h2>

<p>さて、ここからがブラウザの一番の見せ場、サーバから受信したHTMLドキュメントからDOMを生成し、描画を行うフェーズです。</p>

<p>HTML5のスペック「<a href="http://www.w3.org/TR/html5/syntax.html#parsing" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">8.2章 Parsing HTML documents</a>」に内部的な動作が定義されており、これに従い計測値が取得されます。このフェーズで意識すべきなのが、「①. HTMLドキュメント自体の読み込みを行っている段階(domLoading)」と「②. HTMLドキュメントの読み込みが完了し非同期に取得できる画像などのリソースを読み込んでいる段階(domInteractive)」の、2段階のステージです。</p>

<p>1段回目、domLoadingの段階。HTMLドキュメントの読み込みには、8KBというマジックナンバーが隠されています。これは、ブラウザがHTMLドキュメントの内容をパースする際に、一括で読み込みを行う単位と考えると良いでしょう。ブラウザはサーバから受信したHTMLドキュメントを、8KBずつ逐次パースし、DOM Contentを作っていきます。</p>

<p>JavaScript/CSSのような即時で反映する必要があるファイルの参照があった場合、HTMLドキュメントの受信は継続しますが、HTMLパース処理は停止し、JavaScript/CSSのコンパイルと実行を優先します。</p>

<p>DOM Contentの生成が終わった状態を、HTML5のスペックでは「interactive」と定義しています。JavaScriptにて「<a href="http://www.w3.org/TR/html5/index.html#events-0" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">DOMContentLoadedイベント</a>」を登録していた場合は、このタイミングで発火します。</p>

<h2>7. リソース読み込み</h2>

<p>ここからは、2段階目の説明に入ります。HTMLドキュメントが全て読み込まれ、画像などの非同期で読み込めるリソースを読み込んでいる段階です。先ほども説明しましたが、Web標準ではこの段階のことをinteractive(対話可能)と呼んでおり、名前の通り、画像の読み込み完了を待たずしてユーザからの入力を受付けることができます。</p>

<p>実は、ブラウザはHTMLドキュメントを読み込みつつリアルタイムに画面上へ表示する(ChromeはHTMLドキュメントのダウンロード完了時に表示する)という実装なため、「6. DOM生成」の段階でも既に入力可能だったりします。どちらをTATの開始と呼ぶべきか、非常に悩ましいところです。</p>

<p>画像の読み込みが完了し、Webページが完成したタイミングで「complete」という状態に推移します。completeへ推移すると、JavaScriptのloadイベントが発火します。ここで再び、ブラウザはJavaScriptの処理を動かすために、入力をブロックさせたりします。場合によっては、この段階でユーザからの入力を受け付けるために必要な、初期化処理を行なったりもします。例えば、jQueryの有名なプラグインであるDatePickerなんかは、loadイベント内で設定することが多く、ここに来るまでフォーカスを当ててもカレンダが表示されません。interactiveなんて言われていますが、実際にはloadイベントを実行するまではTATの終了とは言えないような気もしますね。ここまでくると、もはや終了の概念そのものをどう定義すべきかが、だんだんわからなくなってきました。</p>

<p>loadイベントの処理が完了すると、Navigation Timingで計測できる全ての処理が完了です。</p>

<p>なお、ここまでの過程で、JavaScriptやCSS、画像などの外部ファイルの読み込みを行っていますが、これら単独リソースごとの性能計測は、Web標準として少し扱いが異なります。詳しくは、「<a href="http://www.w3.org/TR/2014/CR-resource-timing-20140325/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Resource Timing</a>」を参照すると良いでしょう。</p>

<h2>何をもってTATとするか？</h2>

<p>ブラウザの仕組みについて一通り紹介したところで、TATを構成する要素が以下に分類できることが理解頂けたでしょう。この中のどこかに開始を作り、どこかに終了を作れば、あなたの求めるTATになるはずです！</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/05/08.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/08.png" /></a></p>

<p>開始候補、終了候補、なんて言葉を使ってみましたが、ここまでくるともはや、TATを取得することに意味があるのか？なんて思われても仕方ありません。実際のところ本当にその通りで、TATだけをピンポイントで取得しても、あまり役に立たなかったりします。</p>

<p>Navigation Timingはそもそも、ナビゲーションの動作の中から、性能のボトルネックを探すためのものです。生きた計測値を得るためのものです。ブラウザはナビゲーションを開始すると、様々なキャッシュを駆使して最小限で動作することを追求し、そして終了に向けて、DOM生成やリソースの取得、JavaScriptの初期実行を行い、最大限のポテンシャルを発揮しようとします。こうしたブラウザのメカニズムの中から、ボトルネックを探さなくてはいけないのですから、Navigation TimingはWebページの特性に合わせて、有用な情報を拾えるようにしなくてはいけません。</p>

<p>リソースの取得については「<a href="http://www.w3.org/TR/2014/CR-resource-timing-20140325/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Resource Timing</a>」、JavaScriptの性能に影響を与えるような処理に対しては、「<a href="http://www.w3.org/TR/hr-time/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">High Resolution Time</a>」のnow()なんかを利用して、計測を行うことが求められるでしょう。</p>

<p>パフォーマンスの改善は、まさに総合競技です。JavaScriptやCSS単独の高速化手法だけ知っててもダメだし、DBのパラメータチューニングだけできてもダメです。JavaやASP.NETやRuby On Railsも、全体から見ればほんの一部でしかありません。DNSやWebサーバ、APミドルなどのインフラも重要な構成要素ですし、私のようにイントラ向けのシステム開発を行なっている方はネットワーク装置の一台まで面倒を見ていることもあるでしょう。最近はクラウドも絡んできたりして、バックプレーンを共有する他社のWebアプリが性能に影響を与えるなんてのも聞いたことがあります。複雑化が進んでおり、ますます全体を見る目が求められているように思えます。</p>

<p>ところが、パフォーマンスの問題にぶつかると、どうしても自分の専門分野で見てしまい、DBだけを良くしようとしたり、JavaScriptだけを高速化しようと先走ってしまうことがあります。</p>

<p>Navigation Timingを入り口にして、生の測定値に基づき分析し、ブレークダウンしてみて下さい。きっとそれは、改善の近道となり、費用対効果の高い手段を見つけるヒントとなるでしょう。そしてWebアプリは、最高のパフォーマンスを得ることができるはずです。</p>

<ul>
<li><a href="https://html5experts.jp/furoshiki/6242/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Navigation Timingだからできる、Webアプリを俯瞰したパフォーマンス計測(1/3)</a></li>
<li><a href="https://html5experts.jp/furoshiki/6299/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Navigation Timingだからできる、Webアプリを俯瞰したパフォーマンス計測(2/3)</a></li>
</ul>
]]></content:encoded>
		
		<series:name><![CDATA[パフォーマンスチューニング]]></series:name>
	</item>
		<item>
		<title>Navigation Timingだからできる、Webアプリを俯瞰したパフォーマンス計測(2/3)</title>
		<link>/furoshiki/6299/</link>
		<pubDate>Thu, 08 May 2014 00:00:27 +0000</pubDate>
		<dc:creator><![CDATA[川田寛]]></dc:creator>
				<category><![CDATA[システム開発]]></category>
		<category><![CDATA[Navigation Timing]]></category>
		<category><![CDATA[パフォーマンス]]></category>

		<guid isPermaLink="false">/?p=6299</guid>
		<description><![CDATA[連載： パフォーマンスチューニング (10)前回の記事でもお伝えしたとおり、ブラウザのメカニズムが、TATの計測を複雑にしています。その事情について、まずTATの「開始」をどこにするかについて考え、紐解いてみましょう。W...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/performance-tech/" class="series-149" title="パフォーマンスチューニング" data-wpel-link="internal">パフォーマンスチューニング</a> (10)</div><p><a href="https://html5experts.jp/furoshiki/6242/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">前回の記事</a>でもお伝えしたとおり、ブラウザのメカニズムが、TATの計測を複雑にしています。その事情について、まずTATの「開始」をどこにするかについて考え、紐解いてみましょう。Web標準で定義するところのブラウザの動作について、少しだけデフォルメさせた処理モデルを使って、全体の流れを解説します。以下の図の赤字はtimingオブジェクト配下にあるプロパティ、数字が振ってある矢印は処理の流れです。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/05/c9e0e6e4f4b94208f34ad39a0948069f.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/c9e0e6e4f4b94208f34ad39a0948069f.png" alt="スクリーンショット 2014-05-02 5.23.34" class="alignnone size-medium wp-image-6320" srcset="/wp-content/uploads/2014/05/c9e0e6e4f4b94208f34ad39a0948069f.png 640w, /wp-content/uploads/2014/05/c9e0e6e4f4b94208f34ad39a0948069f-300x165.png 300w, /wp-content/uploads/2014/05/c9e0e6e4f4b94208f34ad39a0948069f-207x114.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<h2>0. ナビゲーション開始</h2>

<p>Webページの読み込み動作を、「ナビゲーション」と呼びます。ブラウザは、ネットワーク上のHTMLドキュメントにアクセスすると、Webページを構成する様々な情報を削除(アンロード)します。そして、新しくHTMLドキュメントを読み込み、DOMを構成し、JavaScriptやCSS、画像などのリソースを取得しながらWebページの描画を進めていきます。この一連の動作が、ナビゲーションです。</p>

<p>近年は、「<a href="http://en.wikipedia.org/wiki/Single-page_application" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">SPA(Single-page Application)</a>」と呼ばれるアーキテクチャがあり、DOM操作により画面遷移を擬似的に表現する手法もありますが、この仕組みではナビゲーションを開始できません。あくまで、JavaScript APIやプラグインの力を借りず、ブラウザの機能を使ってWebページを遷移させることで、ナビゲーションは開始されます。</p>

<p>ナビゲーションは、ハイパーリンクのクリックもあれば、Formを使ってサブミットすることでも発生します。戻る/進むボタンやリロードボタンを押下した際も、同様です。こうした、様々なナビゲーションを発生させるアクションは、ブラウザのキャッシュの動作、ナビゲーション全体の動作への影響が大きいため、<a href="http://www.w3.org/TR/navigation-timing/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Navigation Timing</a>を扱う際に理解することが求められます。</p>

<p>Web標準では、こうしたナビゲーションの種類を「<a href="http://www.w3.org/TR/navigation-timing/#sec-navigation-info-interface" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">PerformanceNavigation</a>」として以下のように分類しています。まずは、この定義を中心としてその違いを把握してみましょう。</p>

<ul style="border: silver 1px solid;padding:10px">
<li><a href="http://www.w3.org/TR/navigation-timing/#dom-performancenavigation-typenavigate" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TYPE_NAVIGATE</a> : ハイパーリンクのクリック、ブックマーク等。</li>
<li><a href="http://www.w3.org/TR/navigation-timing/#dom-performancenavigation-typereload" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TYPE_RELOAD</a> : ブラウザのリロードボタン押下。</li>
<li><a href="http://www.w3.org/TR/navigation-timing/#dom-performancenavigation-typebackforward" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TYPE_BACK_FORWARD</a> : ブラウザの戻る/進むボタン押下。</li>
<li><a href="http://www.w3.org/TR/navigation-timing/#dom-performancenavigation-typereserved" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TYPE_RESERVED</a> : 未定義のWebページ読み込みアクション。</li>
</ul>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/05/04a.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/04a.png" alt="04a" class="alignnone size-medium wp-image-6310" srcset="/wp-content/uploads/2014/05/04a.png 546w, /wp-content/uploads/2014/05/04a-300x141.png 300w, /wp-content/uploads/2014/05/04a-207x97.png 207w" sizes="(max-width: 546px) 100vw, 546px" /></a></p>

<p>「TYPE_NAVIGATE」は、ハイパーリンクをクリックした際や、フォームをサブミットした際に発生する、一般的なナビゲーション動作です。ナビゲーションバーへURLを入力しEnterキーを押下した際、ブックマークを開いた際もこの動作であり、基本はこのアクションが選択されると想定すべきでしょう。後に説明する、「<a href="http://www.ietf.org/rfc/rfc2616.txt" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">RFC 2616</a>」のHTTP Cacheが最大限に活用されるのも、このナビゲーション動作です。</p>

<p>「TYPE_BACK_FORWARD」は、基本的には「戻る/進む」ボタンを押下した際に発生します。Web標準で言うところの「<a href="http://www.w3.org/TR/html5/browsers.html#history-traversal" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">履歴移動(History Traversal)</a>」により発生したナビゲーションです。ただ、「<a href="http://www.w3.org/TR/html5/browsers.html#scroll-to-fragid" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">フラグメント識別子(Fragment Identifier)</a>」を利用したURLを扱った場合、ナビゲーションを伴わないWebページ内の移動を行うことがあります。また、Webページが一定の条件を満足すると、ナビゲーション発生時に、前のWebページ全体をそのままキャッシュさせることで、戻るボタンのパフォーマンスを改善しようとします。このような動作を行なった場合、戻るボタンを押下してもナビゲーションは発生しません。</p>

<p>「TYPE_RELOAD」は、「リロードボタン(再読み込み)」を押下した際に発生します。ブラウザによってCtrl/Shiftとリロードボタンを同時押しすることで、HTTP Cacheの一切を破棄しWebページの再読み込みを行う「スーパーリロード(強制再読み込み)」と呼ばれる機能があります。Navigation Timingではこれを区別することなく「TYPE_RELOAD」として扱いますが、実際のキャッシュの動作は大きく異なるものとなるため、明確に区別する必要があります。</p>

<p>「TYPE_RESERVED」については未定義であり、ブラウザでWebページを扱っている範囲では、あまり意識する必要はありません。</p>

<h2>1. アンロード</h2>

<p>ナビゲーションが開始され、標準的なブラウザはまず「1. <a href="http://www.w3.org/TR/html5/browsers.html#unloading-documents" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">アンロード</a>」という処理を行います。ブラウザは、今表示しているWebページのリソースを破棄し、次のWebページを表示する準備をするわけです。DOMの情報を持つDOM Contentや、JavaScriptの機能の初期化を行います。</p>

<p>Web標準では、この処理を「<a href="http://www.w3.org/TR/html5/webappapis.html#handler-window-onunload" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">unloadイベント</a>」として捕捉でき、Navigation Timingを利用してイベント発生前後の時間を取得することができます。ただ、<em>このタイミングは常に一定しているとは限りません。<sup>(※ <a href="#01" data-wpel-link="internal">注１</a>)</sup></em>表面的には、アンロードはこのタイミングで発生しているように見せてはいますが、実装ではブラウザのレンダリングエンジンによってバラツキがあり、この処理の負荷が、この後説明するDOM読み込みのタイミングに大きな影響を与えることがあります。</p>

<p>また、「戻る/進む」ボタンを押下した場合の動作も独特です。先ほども少し説明しましたが、Webページは一定の条件を満足すると、アンロードを行わずメモリ上にWebページをまるごとキャッシュさせます。この動作は、例えばIE11だと<a href="http://msdn.microsoft.com/ja-jp/library/ie/dn265017(v=vs.85).aspx" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">デベロッパーセンター</a>、Firefoxだと<a href="https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">MDN</a>のドキュメントに仕組みが掲載されており、ブラウザごとにやや異なる思想を持っていることも把握できるはずです。HTML5の「<a href="http://www.w3.org/TR/html5/browsers.html#event-pageshow" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">pageshow</a>/<a href="http://www.w3.org/TR/html5/browsers.html#event-pagehide" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">pagehide</a>」イベントで捕捉でき、ある程度の制御が可能なわけですが、基本的にこの動作、ナビゲーションが発生しないのですから、Navigation Timingのプロパティの値も更新されません。</p>

<h2>2. キャッシュ確認</h2>

<p>標準的なブラウザがアンロードを終わらせると、「2. キャッシュ確認」を行います。Webページの表示に必要なHTMLドキュメントを、キャッシュの中から探すわけです。キャッシュと言っても、ブラウザのみで有効性判断ができるものあれば、サーバに問い合わせを行わないと判断できないものもります。ここでチェックされるのは、あくまで前者のみです。HTML5の「<a href="http://www.w3.org/TR/2011/WD-html5-20110525/offline.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">AppCache</a>」や、「<a href="http://www.ietf.org/rfc/rfc2616.txt" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">RFC 2616</a>(13.5)」で定義されたHTTPヘッダのプロパティ「Expires(14.2)」「Cache-Control max-age(14.9)」によるHTTP Cacheなんかは古くから活用されているため、ご存知の方も多いでしょう。</p>

<p>AppCacheは、常にこの段階で読み込みが行われます。しかし、HTTP Cache(Expires)により得られるゆるいキャッシュは、TYPE_NAVIGATEの場合のみ、ブラウザ内のキャッシュを利用します。この仕様は動作チェックの際に問題となることがあり、誤ってリロードボタンを押下してテストしようものなら、テスト担当者は一日を無駄に過ごすことになります。(※ アドレスバーにフォーカスを当ててEnterキーを押下、がキャッシュのテストの鉄則です！)</p>

<p>Chromeだけは、やや動作が例外的です。Chromeは、HTMLドキュメント内から参照されるJS/CSS/画像ファイルのようなリソースでも無い限り、HTTP Cacheによるブラウザ内のキャッシュを利用してくれません。XHR(XMLHTTPRequest)についても同様で、Chromeだけは必ずサーバへのアクセスを伴います。そもそも、Webページはサーバサイドのプログラムで動的に生成するのが殆どなので、HTMLドキュメントのキャッシュは期待できないものと見なすべきでしょう。</p>

<h2>3. 名前解決</h2>

<p>標準的なブラウザは、有効なキャッシュを発見できなかった場合、HTMLドキュメントが置かれているサーバの場所を特定するため「3. 名前解決」を行います。</p>

<p>名前解決については、Linux/OS X/iOS上のブラウザについては、基本的にDNS名として扱い名前解決を行います。しかし、Windows OS上のブラウザは、微妙に同じ動作にはなりません。Windows OS上のブラウザは、ドメイン名をフルコンピュータ名というやや特殊な概念として扱い、<a href="http://technet.microsoft.com/ja-jp/library/cc728142" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">NetBIOS(WINS)名とDNS名の2つの名前の概念を扱うハイブリッドな名前解決を行います</a>。</p>

<p>これは、ブラウザの仕様というより、OSの持つTCP/IPモジュールの仕様の違いです。IEとFirefox/Chromeとで異なるAPIをコールしていますが、どちらも最終的には同じ<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms740673(v=vs.85).aspx" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">WinSock2</a>の名前解決のメカニズムを利用します。名前解決を行うリゾルバにも、OSによる動作の違いがありますが、DNSを使っている限り、機能面において、ブラウザからはあまり意識する必要がありません。</p>

<p>インターネット向けでは、各プロバイダが提供するDNSサーバの性能が関わってくることもあります。DNSもやはり、キャッシュが要です。DNSを構成する各ノードのキャッシュの動作次第で、性能は大きく変化します。TTL設定のチューニング、DNS Prefetchを活用して対策してみると良いでしょう。</p>

<h2>キャッシュだらけ！</h2>

<p>ナビゲーションの動作のうち、どこをTATの開始とすべきか？もうお分かりと思いますが、キャッシュだらけで、前提条件から疑いにかからなくてはいけません！Webページ自体の(アンロード絡み)のキャッシュ、HTML5 AppCacheやRFC 2616によるブラウザ側のキャッシュ、名前解決絡みのキャッシュと、まだWebサーバにアクセスしていないというのに、これだけのキャッシュが絡んでいます。</p>

<p>最初にご紹介した「navigationStart」は、こうした前の画面の動作を含んだ計測値です。アンロードや、この後説明するリダイレクトを含めるとなると、開始をどこに置くのかというのもまた難しくなってきます。</p>

<p>TATの本当に難しさはここだけではありません。TATの「終了」の扱い、これも難しかったりします。ブラウザのメカニズムを掘り下げて追ってみましょう。</p>

<p>「Navigation Timingだからできる、Webアプリを俯瞰したパフォーマンス計測(3/3)」に続きます。(※5/9公開予定)</p>

<ul>
<li><a href="https://html5experts.jp/furoshiki/6242/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Navigation Timingだからできる、Webアプリを俯瞰したパフォーマンス計測(1/3)</a></li>
<li><a href="https://html5experts.jp/furoshiki/6335/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Navigation Timingだからできる、Webアプリを俯瞰したパフォーマンス計測(3/3)</a></li>
</ul>

<div style="line-height:110%"><a name="01" data-wpel-link="internal"></a><small>※注1 : 実装では、Chromeのアンロードはこのタイミングには行われていません。気になる方は、Chronium35であれば<a href="https://chromium.googlesource.com/chromium/blink/+/master/Source/core/loader/DocumentLoader.cpp" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">./core/loader/DocumentLoader.cpp(startLoadingMainResource)</a>を確認してみると良いでしょう。PerformanceTiming::markNavigationStart()の後にPerformanceTiming::markFetchStart()を呼び出しており、アンロードは遅延して実行していることが読み取れます。なお、Chromeのアンロードは、HTMLドキュメントのHTTP受信完了時に発生します。このあたりは、<a href="https://chromium.googlesource.com/chromium/blink/+/master/Source/core/loader/DocumentLoader.cpp" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">./core/loader/DocumentLoader.cpp(finishedLoading)</a>あたりが動作を理解するのに適しており、commitIfReady()の実装を掘っていくと、./core/loader/FrameLoader.cpp FrameLoader::commitProvisionalLoad→FrameLoader::closeURL…と進み、最終的にunloadイベント発火のタイミングをマークしている処理に到達します。</small></div>
]]></content:encoded>
		
		<series:name><![CDATA[パフォーマンスチューニング]]></series:name>
	</item>
		<item>
		<title>Navigation Timingだからできる、Webアプリを俯瞰したパフォーマンス計測(1/3)</title>
		<link>/furoshiki/6242/</link>
		<pubDate>Fri, 02 May 2014 03:00:11 +0000</pubDate>
		<dc:creator><![CDATA[川田寛]]></dc:creator>
				<category><![CDATA[システム開発]]></category>
		<category><![CDATA[Navigation Timing]]></category>
		<category><![CDATA[パフォーマンス]]></category>

		<guid isPermaLink="false">/?p=6242</guid>
		<description><![CDATA[連載： パフォーマンスチューニング (9)こんにちは、html5jパフォーマンス部、スタッフの川田です。5月8日ですが、私たちのコミュニティ主催で勉強会を開催することになりました！！ そして、残念なお知らせです。募集した...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/performance-tech/" class="series-149" title="パフォーマンスチューニング" data-wpel-link="internal">パフォーマンスチューニング</a> (9)</div><p>こんにちは、html5jパフォーマンス部、スタッフの川田です。5月8日ですが、私たちのコミュニティ主催で<a href="http://atnd.org/events/50159" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">勉強会</a>を開催することになりました！！</p>

<p><a href="http://atnd.org/events/50159" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/aeaf4d319ffa73eab4f8b831cc4b1850.png" alt="スクリーンショット 2014-05-02 3.49.38" class="alignnone size-medium wp-image-6268" srcset="/wp-content/uploads/2014/05/aeaf4d319ffa73eab4f8b831cc4b1850.png 640w, /wp-content/uploads/2014/05/aeaf4d319ffa73eab4f8b831cc4b1850-300x156.png 300w, /wp-content/uploads/2014/05/aeaf4d319ffa73eab4f8b831cc4b1850-1024x535.png 1024w, /wp-content/uploads/2014/05/aeaf4d319ffa73eab4f8b831cc4b1850-207x108.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>そして、残念なお知らせです。募集した直後に、席が埋まってしまいました！せっかく、これだけ多くの方にパフォーマンスへ興味を持っていただいたのに、このままじゃもったいない！</p>

<p>なので本記事では、この勉強会で語られない、別の切り口からパフォーマンスについて語ってみようかと思います。内容は、私が技術評論社「<a href="http://gihyo.jp/magazine/SD" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Software Design 2014年5〜7月号</a>」にて連載しております、「Web標準技術で行う、Webアプリのパフォーマンス改善」で扱っているテーマの一部を、Web向けに書き直したものです。</p>

<h2>Webアプリのパフォーマンス計測は簡単なのか？</h2>

<p>パフォーマンスは、メモリを節約するものからCPUコストを下げるものまで、様々な種類があります。本記事では「ターンアラウンドタイム(TAT)」という指標値について考えてみましょう。</p>

<p><a style="float:left;margin-right:30px" href="/wp-content/uploads/2014/05/00.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/00-300x168.png" alt="00" width="300" height="168" class="alignnone size-medium wp-image-6245" srcset="/wp-content/uploads/2014/05/00-300x168.png 300w, /wp-content/uploads/2014/05/00-207x116.png 207w, /wp-content/uploads/2014/05/00.png 502w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>TATとは、アプリケーションの応答速度を表す指標の一つです。厳密には、あるアプリケーション・サーバに対して、ユーザが何かしらの操作・入力を行ってから、アプリが反応し終わり、ユーザが再び入力を受け付けることができるような状態になるまでの時間、と定義されています。Webページが遷移する時間を、定量的に評価できる指標値ということになります。</p>

<p>このTATという考え方、そんなにマニアックなものというものでもなく、レスポンスタイムやスループット、アベイラビリティなどと同様に、古くから存在する非機能要求の項目です。IPAの情報処理試験でもよく見かける、有名なキーワードに思えるでしょう。ところが、これをWebを検索しても、なかなかしっくりくる計測手段が見つかりません！この問題、特にWebに限定した話というものでもないはずです。GUIレベルでの性能計測は、昔からある悩みの一つで、アナログにストップウォッチの力を借りるなんてことも割とよく聞く話です。筆者もIE6全盛のWebアプリ開発で、同じ悩みを抱えたことがあります。</p>

<p>今回、そんなTATをめぐる悩みに対して、ちょっとしたヒントをご紹介します。ブラウザの仕組みを探り、WebアプリのTATとは何かを探り、そして標準的な手段の中からその計測方法について探ってみましょう。「そもそも、そんな指標で評価することに価値があるのか！？」なんて議論も生じていたりするのですが、その点は一番最後に触れるとして、今回はTATという切り口からWebページの性能について考えてみます。</p>

<h2>TATの計測で、Webサーバのログはアテになるのか？</h2>

<p>SPDYなどの新しいプロトコルのことは一旦忘れて、シンプルなHTTP1.Xを前提に考えてみて下さい。HTTP1.Xは、HTMLドキュメント取得し、HTMLドキュメント内で参照されている必要なJavaScript/CSS/画像などの外部リソースを、逐次取得し表示していくという仕組みです。サーバサイドで動的にHTMLを生成するようなアプリだと、画面を遷移する都度、最低でもHTMLドキュメント程度はサーバ側から取得することになります。</p>

<p>この動きに注目し、計測で非常によく利用されるのが、Webサーバログの「リクエスト処理時間(Time taken to process the request)」です。Apache HTTP Serverのアクセスログのフォーマットオプション「<a href="http://httpd.apache.org/docs/2.2/mod/mod_log_config.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">%D</a>」あたりは有名でしょう。このオプションは、HTTPリクエストを受け付けた瞬間から、サーバで処理が行われ、データを出力し終わるまでの時間を、マイクロ秒単位で計測する機能です。<a href="https://tomcat.apache.org/tomcat-8.0-doc/config/valve.html#Access_Log_Valve/Attributes" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Tomcat</a>や<a href="http://docs.jboss.org/jbossweb/7.0.x/config/valve.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">JBoss</a>のようなJavaミドル、Microsoftの<a href="http://msdn.microsoft.com/ja-jp/library/cc338080.aspx#W3CExtendedLoggingDefinitions" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">IIS(Internet Information Services)</a>でも、リクエスト処理時間をミリ秒で計測できる機能を実装しており、大抵のWebアプリでは活用できるコモディティ化した機能と言えます。</p>

<p>リクエスト処理時間は、実際にサーバ上の問題を発見するのに価値が高い計測値です。運用時には、キャパシティプランニングの目安や、障害発生時の解析に活用されたりします。また、お客様と品質保証の明確な基準を決める「<a href="http://ja.wikipedia.org/wiki/%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E6%B0%B4%E6%BA%96%E5%90%88%E6%84%8F" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">SLA(Service-Level Agreement)</a>」でも、アクセスの何％を保障するかという「<a href="http://ja.wikipedia.org/wiki/%E5%88%86%E4%BD%8D%E6%95%B0#.E3.83.91.E3.83.BC.E3.82.BB.E3.83.B3.E3.82.BF.E3.82.A4.E3.83.AB" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">パーセンタイル</a>」を配慮した形で活用することがあります。どこにでも目にするこの計測値、一見すると使い道が広く、万能な値に見えるでしょう。</p>

<p>ところが残念なことに、リクエスト処理時間は、キャッシュされていないごく一部のファイル/プログラム単位の性能しか評価できません。サーバがどの程度のリクエストを捌けるのかを判断する「<a href="http://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%AB%E3%83%BC%E3%83%97%E3%83%83%E3%83%88" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">スループット(＝処理能力)</a>」の指標値として扱うには高い価値を発揮しますが、TATの指標値として扱うには、対象が局所的で、不足が大きすぎます。サーバから見ると性能は高いのに、クライアントで見ると画面はいつになっても白いまま！なんてことになりかねません。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/05/01.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/01.png" alt="01" class="alignnone size-medium wp-image-6289" srcset="/wp-content/uploads/2014/05/01.png 640w, /wp-content/uploads/2014/05/01-300x146.png 300w, /wp-content/uploads/2014/05/01-1024x501.png 1024w, /wp-content/uploads/2014/05/01-207x101.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>では、TATを計測するにはどうすればよいのでしょうか？画面を表示する際のもっさり感の原因は、どのように探ればよいのでしょうか？このあたり、最近のWeb標準がかなり力を入れています。2012年12月にW3C勧告となった「<a href="http://www.w3.org/TR/navigation-timing/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Navigation Timing(ver.1)</a>」がまさにその代表的なスペックです。</p>

<p>Navigation Timingを含むWebのパフォーマンスに関する仕様は、2010年にW3Cで設立された「<a href="http://www.w3.org/2010/webperf/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Performance Working Group(WebPerf WG)</a>」で議論され、IE9+、Firefox、Chromeなどのブラウザにその成果が反映されています。Facebookのザッカーバーグ氏がHTML5に失望し、同社のアプリをネイティブに書き換えるという有名な事件がありますが、そんな彼らも同WGの設立直後すぐに反応し、WGの議論に参加しています。2013年には「Web vs ネイティブ」という議論が盛り上がりましたが、WebPerf WGの取り組みは、現在のWebが抱える性能という問題を見つめていく上で、注目すべき重要なポイントと言えるでしょう。</p>

<h2>Navigation Timingの使い方、TATの計測方法</h2>

<p>Navigation Timingでは、ハイパーリンクをクリックした瞬間からWebページが利用できるようになるまでを、ブラウザの内部的な動作である「<a href="http://www.w3.org/TR/navigation-timing/#processing-model" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">処理モデル(Processing Model)</a>」として定義し、その経過時間を取得することができます。</p>

<p>ブラウザ自体にも「開発者ツール」として計測のためのツールが備わっていますが、ブラウザごとに考え方も違うし、活用できる場も開発時のみと非常に限定的です。Navigation TimingはWeb標準なので、ブラウザに依存しない共通の考え方で計測値を扱え、また運用時にもJavaScript上で生のデータを収集することができる点で、開発者ツールより高いポテンシャルを得ています。</p>

<p>実際のJavaScriptの仕様を見ながら確認してみましょう。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/05/4e7e8507cc1b623c22b6842557767406.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/4e7e8507cc1b623c22b6842557767406.png" alt="02" width="300" height="99" class="alignnone size-medium wp-image-6295" /></a></p>

<p>windowオブジェクト配下にある「performance」は、パフォーマンス関連のJavaScript APIにアクセスするための入り口となるオブジェクトです。そのさらに下に、WebPerf WGの成果である様々なスペックの実装が分類別で並んでいます。そのうちのひとつである「timing」の配下には、ハイパーリンクをクリックしてから応答するまでの間に発生する、様々な動作発生時のタイムスタンプを取得できるプロパティが並んでいます。</p>

<p>TATを取得しコンソールに表示させる、シンプルなコードを確認し、使い方を掴んでみましょう。</p>

<p></p><pre class="crayon-plain-tag">/* timingオブジェクトの取得 */
var timing = ( window.performance || {} ).timing;
/* TATの計測 */
timing &amp;&amp; window.addEventListener( "load", function() {
    setTimeout( function() {
        var tat = timing.loadEventEnd - timing.navigationStart;
        console.log( "TAT = " + tat );
    },1);
},false);</pre><p></p>

<p>「timing.navigationStart」はハイパーリンクがクリックされた直後の時間、「timing.loadEventEnd」はWebページが表示されJavaScriptのloadイベントの処理が完了した直後の時間が取得できるプロパティです。サンプルでは、この2つの単純な差分を、仮にTATとしてみました。setTimeoutで実行時間を遅延させているのは、loadEventEndがloadイベント中だと未計測の状態「0」を返してしまうという問題への対策です。</p>

<p>このサンプルで得られる計測値が、TATとして「ほぼ正解」の値ということになります。ただ、ほぼ正解であって、完全な正解とは言えません。このあたりの理由については、ブラウザの内部のメカニズムによるところが大きかったりします。具体的には何が原因なのか、これから見ていきましょう。</p>

<ul>
<li><a href="https://html5experts.jp/furoshiki/6299/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Navigation Timingだからできる、Webアプリを俯瞰したパフォーマンス計測(2/3)</a></li>
<li><a href="https://html5experts.jp/furoshiki/6335/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Navigation Timingだからできる、Webアプリを俯瞰したパフォーマンス計測(3/3)</a></li>
</ul>

<p><em>※ 修正 2014.5.11：<a href="https://html5experts.jp/myakura/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">矢倉 眞隆</a>さんからのご指摘により、サンプルのwindow.performanceのベンダプレフィクスは削除しました。IE9+を含む近年のブラウザでは、3年近く前にベンダプレフィクスが消えており、無意味であると判断できたためです。</em></p>
]]></content:encoded>
		
		<series:name><![CDATA[パフォーマンスチューニング]]></series:name>
	</item>
	</channel>
</rss>
