<?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="/tag/高速化/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>HTML5 Experts.jpはなぜこんなにパフォーマンスが悪いのか…全てお見せします！ーWebパフォーマンス改善企画（改善編）</title>
		<link>/yoshikawa_t/14608/</link>
		<pubDate>Wed, 22 Apr 2015 00:00:46 +0000</pubDate>
		<dc:creator><![CDATA[吉川 徹]]></dc:creator>
				<category><![CDATA[サイト制作]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[パフォーマンス]]></category>
		<category><![CDATA[高速化]]></category>

		<guid isPermaLink="false">/?p=14608</guid>
		<description><![CDATA[Webパフォーマンス改善企画（改善編）は、実際の改善内容とその結果をお伝えします！パフォーマンス分析を行った解析編は、こちらからご覧ください。本記事はHTML5 Experts.jpがいかにして速くなったのかを包み隠さず...]]></description>
				<content:encoded><![CDATA[<p>Webパフォーマンス改善企画（改善編）は、実際の改善内容とその結果をお伝えします！パフォーマンス分析を行った解析編は、<a href="https://html5experts.jp/yusuke-naka/13671/" target="_blank" data-wpel-link="internal">こちら</a>からご覧ください。本記事はHTML5 Experts.jpがいかにして速くなったのかを包み隠さずお伝えします！</p>

<h2>今回の前提条件と改善ポイント</h2>

<p>実際の改善を行う前にいくつか前提条件を説明しなければいけません。まず動作環境ですが、HTML5 Experts.jpは、WordPress上で動作しており、改善内容はプラグインの導入やPHPのコード修正が主になっています。ただ、そういったWordPressの泥臭いチューニングは本題ではないので、細かく解説するのではなく大まかな改善内容とその方針を説明したいと思います。また、改善内容に関しても費用対効果がある程度高いものを優先しているため、まだまだ改善できるというところも、あえてそのままにしているところもあります。</p>

<p>今回の改善内容は、前回の分析結果から以下のようになっています。その分析内容などについては<a href="https://html5experts.jp/yusuke-naka/13671/" target="_blank" data-wpel-link="internal">解析編</a>をご確認ください。以下の改善ポイントとその順番に沿って解説していきます。（順番は、改善内容の導入のしやすさや影響の大きさなどを考慮して実際に実施した順序になっています）</p>

<h3>改善ポイント</h3>

<ol>
<li>ソーシャルメディア系サービス（シェアボタンなど）のパフォーマンスを改善する</li>
<li>実際の表示サイズより大きな画像は適正なサイズに変更する</li>
<li>マークアップを改善する（書き方やJSのミニファイ等）</li>
<li>WordPressのキャッシュを導入する</li>
<li>Keep Aliveが全ての環境で効いているか、設定時間は適切かを確認し、コンテンツダウンロード時間を最適化する</li>
</ol>

<h2>ソーシャルメディア系サービスのパフォーマンスを改善する</h2>

<p>まず最初に着手したのは、ソーシャルメディア系のガジェットなどです。HTML5 Experts.jpでは、トップページにはTwitterのタイムラインとFacebookのウィジット、記事ページには、各種シェアボタンとFacebookのコメントを埋め込んでいました。これらのソーシャル系のガジェットは、多数のリソースを読み込んだり、スクリプトによるメインスレッドのブロッキングなどでユーザーの体感スピードを劣化される主たるものです。まずは、不要なガジェットの整理ということで、ほぼ利用がなく効果が不明なTwitterのタイムライン、Facebookのウィジット、Facebookのコメントは完全に削除することにしました。これだけで、トップページからはソーシャル系のガジェットが完全になくなることになります。次に記事ページのソーシャルボタンですが、ソーシャルボタンのスクリプトを読み込まないように自作することにしました。現在（改善後）のソーシャルボタンは次のようになっているはずです。</p>

<div style="overflow:hidden">

<div id="attachment_14614" style="width: 310px" class="wp-caption alignleft"><a href="https://html5experts.jp/wp-content/uploads/2015/04/1.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/04/1-300x111.png" alt="PC版ソーシャルボタン" width="300" height="111" class="size-medium wp-image-14614" srcset="/wp-content/uploads/2015/04/1-300x111.png 300w, /wp-content/uploads/2015/04/1.png 640w, /wp-content/uploads/2015/04/1-207x77.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a><p class="wp-caption-text">PC版ソーシャルボタン</p></div>

<div id="attachment_14612" style="width: 310px" class="wp-caption alignright"><a href="https://html5experts.jp/wp-content/uploads/2015/04/2.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/04/2-300x188.png" alt="モバイル版のソーシャルボタン" width="300" height="188" class="size-medium wp-image-14612" srcset="/wp-content/uploads/2015/04/2-300x188.png 300w, /wp-content/uploads/2015/04/2.png 640w, /wp-content/uploads/2015/04/2-207x129.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a><p class="wp-caption-text">モバイル版のソーシャルボタン</p></div>

</div>

<p>これらのソーシャルボタンでは、例えばTwitterのツイートなどを直接リンクで指定しており、onclickで小さいウィンドウが開くように変更しています。そのため、APIを利用しなければ実現できないFacebookの「いいね」と、Google+の「+1ボタン」は、いずれもシェアボタンに変更しています。各ボタンのカウント数については、サーバー側でキャッシュして表示する「<a href="https://wordpress.org/plugins/sns-count-cache/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">SNS Count Cache</a>」というプラグインを導入して利用しています。</p>

<p>ソーシャルメディア系のガジェットの改善は非常に効果が大きく、以下のようにPC版の記事ページでは、ページの読み込み時間が5秒近辺だったものが、2.5秒のほどに劇的に改善しています。また、バラツキがあった計測時間が小さい範囲に収まるように収束しています。</p>

<div id="attachment_14637" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/04/1f383cad650cc18c4117859a5dd8b09a.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/04/1f383cad650cc18c4117859a5dd8b09a.png" alt="PC版記事ページの読み込み時間（折れ線グラフ）" width="640" height="276" class="size-full wp-image-14637" srcset="/wp-content/uploads/2015/04/1f383cad650cc18c4117859a5dd8b09a.png 640w, /wp-content/uploads/2015/04/1f383cad650cc18c4117859a5dd8b09a-300x129.png 300w, /wp-content/uploads/2015/04/1f383cad650cc18c4117859a5dd8b09a-207x89.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">PC版記事ページの読み込み時間（折れ線グラフ）</p></div>

<div id="attachment_14639" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/04/f9d6dee4735766d6f598297f7eea2ff8.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/04/f9d6dee4735766d6f598297f7eea2ff8.png" alt="PC版記事ページの読み込み時間（スキャッタプロット）" width="640" height="305" class="size-full wp-image-14639" srcset="/wp-content/uploads/2015/04/f9d6dee4735766d6f598297f7eea2ff8.png 640w, /wp-content/uploads/2015/04/f9d6dee4735766d6f598297f7eea2ff8-300x143.png 300w, /wp-content/uploads/2015/04/f9d6dee4735766d6f598297f7eea2ff8-207x99.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">PC版記事ページの読み込み時間（スキャッタプロット）</p></div>

<h2>実際の表示サイズより大きな画像は適正なサイズに変更する</h2>

<p>次は画像サイズの縮小です。HTML5 Experts.jpでは既に画像の最適化を行う「<a href="https://wordpress.org/plugins/ewww-image-optimizer/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">EWWW Image Optimizer</a>」プラグインを導入済みでしたが、画像のサイズ自体はあまりケアしていませんでした。そのため、記事によっては原寸サイズの画像を貼り付けているものもあり、ダウンロード容量が非常に多いページもありました（WordPressの場合、画像を挿入する際にサイズを選択できます）。また、お恥ずかしながら、アイキャッチ画像を設定している記事については、記事一覧でサムネイルに原寸サイズの画像が表示されるというバグも見つかりました。そこで、以下のように対応することに決めました。</p>

<ul>
<li>画像の最大サイズをPC版記事ページの横幅に合わせ640pxとする</li>
<li>画像の最大サイズより大きな画像がアップロードされた場合、強制的にリサイズする</li>
<li>記事一覧で、適切なサイズのサムネイル画像を表示するように変更</li>
</ul>

<div style="overflow:hidden">

<div id="attachment_14634" style="width: 310px" class="wp-caption alignleft"><a href="https://html5experts.jp/wp-content/uploads/2015/04/2f9ed77130ae7997b32a9c805d94efd8.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/04/2f9ed77130ae7997b32a9c805d94efd8-300x230.png" alt="画像の最大サイズ" width="300" height="230" class="size-medium wp-image-14634" srcset="/wp-content/uploads/2015/04/2f9ed77130ae7997b32a9c805d94efd8-300x230.png 300w, /wp-content/uploads/2015/04/2f9ed77130ae7997b32a9c805d94efd8.png 640w, /wp-content/uploads/2015/04/2f9ed77130ae7997b32a9c805d94efd8-207x159.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a><p class="wp-caption-text">画像の最大サイズ</p></div>

<div id="attachment_14635" style="width: 310px" class="wp-caption alignright"><a href="https://html5experts.jp/wp-content/uploads/2015/04/51388cdcdf3a9a76de3d0c7ddccd3b17.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/04/51388cdcdf3a9a76de3d0c7ddccd3b17-300x287.png" alt="記事一覧のサムネイル画像" width="300" height="287" class="size-medium wp-image-14635" srcset="/wp-content/uploads/2015/04/51388cdcdf3a9a76de3d0c7ddccd3b17-300x287.png 300w, /wp-content/uploads/2015/04/51388cdcdf3a9a76de3d0c7ddccd3b17.png 640w, /wp-content/uploads/2015/04/51388cdcdf3a9a76de3d0c7ddccd3b17-207x198.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a><p class="wp-caption-text">記事一覧のサムネイル画像</p></div>

</div>

<p>まず初めに、画像の最大サイズを変更します。WordPressでは画像のサイズを設定画面で変更することができ、デフォルトでは「大サイズ」の設定値は1024&#215;1024に設定されている部分を640&#215;640に変更します。しかし、これだけでは編集者が誤ってフルサイズの画像を挿入することができてしまうため、それより大きい画像がアップロードされた場合に強制的に640&#215;640にリサイズするようにします。これは、「<a href="https://wordpress.org/plugins/imsanity/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Imsanity</a>」というプラグインを導入することで解決しました。</p>

<p>次に、記事一覧で適切なサイズのサムネイル画像を表示するように変更します。PC版の場合、サムネイル画像の表示サイズは幅207pxとなっていたため、それに合わせて画像をアップロードする際に自動的に幅207pxのサムネイル画像を作成するように変更しました。同時に、記事一覧を出力する際にサイズを指定して画像を表示するようにコードを修正しています。（これらの詳細なコードは例示しませんが、<code>add_image_size</code> <code>the_post_thumbnail</code> <code>wp_get_attachment_image_src</code> 等のキーワードを調べていただければ見つかるかと思います）</p>

<p>ここでモバイル版について考慮されていないと気がついた方がいらっしゃるかもしれません。モバイル版のサムネイル画像のサイズは、幅93pxとなっていましたが、これをこのまま適用してしまうと高精細なディスプレイではぼやけてしまうため、そのままPC版と同じものを表示するようにしました。本来であれば、レスポンシブイメージを採用するのが理想だと思いますが、この時点ではリソースの問題から断念しています。</p>

<p>最後に、既存の画像ファイルに対して、これらの変更を反映する必要があります。最大サイズの変更と新たなサムネイル画像の表示サイズの追加については、「<a href="https://wordpress.org/plugins/ajax-thumbnail-rebuild/" target="_blnak" data-wpel-link="external" rel="follow external noopener noreferrer">AJAX Thumbnail Rebuild</a>」というプラグインを使ってバックグラウンドですべて処理しました。その後、「Imsanity」、「EWWW Image Optimizer」プラグインについても、既存の画像に対するオプション機能を使って再処理を実施しました。これで、すべての画像は適正なサイズに変更されたことになります。</p>

<h2>マークアップを改善する（書き方やJSのミニファイ等）</h2>

<p>ここで実施するのは、不要なスクリプトやスタイルを整理したり、ファイルの結合やミニファイなど、一般的なWebパフォーマンスのベストプラクティスに近いものです。しかしながら、WordPressではすべてのページでjQueryを読み込んでいたり、いろいろなプラグインがそれぞれファイルを読み込んでいたりと、かなり奔放な状況です。そのため、実際の作業はここが一番泥臭く、複雑なものになりました。改善内容は、主に以下のようなものです。</p>

<ol>
<li>すべてのページで読み込んでいるスクリプト、スタイルを調査する</li>
<li>不要なスクリプト、スタイルを削除する</li>
<li>スクリプト、スタイルの移動、結合とミニファイ（「<a href="https://wordpress.org/plugins/autoptimize/" target="_blnak" data-wpel-link="external" rel="follow external noopener noreferrer">Autoptimize</a>」プラグイン）</li>
</ol>

<p>まず、1番と2番ですが、初めにすべてのページで読み込んでいるスクリプト、スタイルを調べます。HTML5 Experts.jpの場合、主にトップページ、記事ページ、その他のページの3種類になります。その他のページにもいくつか種類がありますが、スクリプト・スタイル構成は似たようなものになるので、ここでは省略しています。また、上記3種類がそれぞれPC版、モバイル版とあるので計6種類ということになります。これらの各ページでは、HTMLソースコード内のべた書き（scriptタグなど）やWordPress上で読み込まれているリソース、実際にブラウザに表示されているページ上で読み込まれているファイルなどを調べます。（WordPress上では、<code>wp_enqueue_scripts</code>をフックしてそれぞれのハンドル名を表示します）</p>

<p>その後に、どのプラグインが読み込んでいるのか、それらは本当に必要かどうかを判断します。プラグイン自体が不要であればプラグインを削除し、スクリプトやスタイルの読み込みのみを止めたいのであれば設定変更で対応可能か判断し、最終的にはWordPress上で個別の種類のページに対してスタイルを削除します。例えば、「<a href="https://wordpress.org/plugins/facebook/" target="_blnak" data-wpel-link="external" rel="follow external noopener noreferrer">Facebook</a>」公式プラグインは、すべてのページでFacebookのスクリプトを読み込むようになっており、ソーシャルボタンを廃止した関係もあって完全に削除しています。その際にプラグインが提供していたOGP設定などは手動で追加しています。また、モバイル版のトップページではjQueryは不要のため、トップページでのみjQueryを読み込まないといった形になっています。（WordPress上では、<code>wp_enqueue_scripts</code>をフックしてif文でそれぞれのページ上で<code>wp_dequeue_script</code>や<code>wp_dequeue_style</code>などでスクリプトやスタイルを読み込まないようにしています）</p>

<p>そして肝心の改善結果ですが、実は問題があり、ページのHTTPリクエストから最初のデータが返ってくるまでの時間（TTFB: Time To First Byte）が遅延するという事象が発生しました。これは、元々WordPressではDBアクセスなどがあり、時間がかかっていた箇所でしたが、加えて今回のAutoptimizeがファイルの結合、ミニファイを行うためにバッファを読み込んで処理している関係でさらにTTFBが伸びるという結果になりました。そのため、スクリプト・スタイルのファイル数とサイズが減ったにも関わらず、結果としてパフォーマンスは相殺され、逆にロード時間が若干長くなるという状態になりました。そのため、Autoptimizeを導入する場合は、基本的には後述するキャッシュを導入する必要があるという結論となりました。</p>

<div id="attachment_14698" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/04/06f12203127cb2f6f66297b4c0302326.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/04/06f12203127cb2f6f66297b4c0302326.png" alt="TTFBの遅延（ウォーターフォール図）" width="640" height="293" class="size-full wp-image-14698" srcset="/wp-content/uploads/2015/04/06f12203127cb2f6f66297b4c0302326.png 640w, /wp-content/uploads/2015/04/06f12203127cb2f6f66297b4c0302326-300x137.png 300w, /wp-content/uploads/2015/04/06f12203127cb2f6f66297b4c0302326-207x95.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">TTFBの遅延（ウォーターフォール図）*青い部分がTTFB</p></div>

<h2>WordPressのキャッシュを導入する</h2>

<p>WordPressは、簡単にページを構成して表示できる反面、PHPの処理やDBアクセスが発生するため、TTFBが遅くなりがちです。そのため、HTML5 Experts.jpのような、ある程度表示内容が変わらないサイトの場合はキャッシュプラグインを導入するのが望ましいでしょう。今回、キャッシュプラグインには、ページキャッシュ、オブジェクトキャッシュ、DBキャッシュの3つが可能な「<a href="https://wordpress.org/plugins/w3-total-cache/" target="_blnak" data-wpel-link="external" rel="follow external noopener noreferrer">W3 Total Cache</a>」と、WordPressのUIの日本語化のための翻訳ファイルをキャッシュする「<a href="https://wordpress.org/plugins/mo-cache/" target="_blnak" data-wpel-link="external" rel="follow external noopener noreferrer">MO Cache</a>」を導入しました。いくつかあるキャッシュプラグインのうち、W3 Total Cacheを採用した理由は、現在PC版、モバイル版のテーマを「<a href="https://wordpress.org/plugins/multi-device-switcher/" target="_blnak" data-wpel-link="external" rel="follow external noopener noreferrer">Multi Device Switcher</a>」でブラウザ（UA）によって切り替えていますが、W3 Total CacheにはUser Agent Groupごとにキャッシュできる仕組みがあることです。</p>

<p>これにより、現在はアクセスのある記事ページなどは、キャッシュが1時間保持されるような設定になっています。キャッシュは記事が公開されるとクリアされ、再度アクセスがあるとキャッシュされるようになっています。そのため最初に記事にアクセスした人は若干遅いと感じることがあるかもしれません。また、ソーシャルボタンなどのカウント数も即時には反映されなくなっています。</p>

<p>キャッシュを導入した結果、なんと2〜3秒かかっていたTTFBが100ms前後にまで改善しました。体感速度でもかなり快適に表示されるように、非常に高い効果がありました。</p>

<div id="attachment_14705" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/04/f78ae094a542122a7b48050891f1887e.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/04/f78ae094a542122a7b48050891f1887e.png" alt="TTFBの改善（ウォーターフォール図）" width="640" height="277" class="size-full wp-image-14705" srcset="/wp-content/uploads/2015/04/f78ae094a542122a7b48050891f1887e.png 640w, /wp-content/uploads/2015/04/f78ae094a542122a7b48050891f1887e-300x130.png 300w, /wp-content/uploads/2015/04/f78ae094a542122a7b48050891f1887e-207x90.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">TTFBの改善（ウォーターフォール図）</p></div>

<h2>Keep Aliveが全ての環境で効いているか、設定時間は適切かを確認し、コンテンツダウンロード時間を最適化する</h2>

<p>モバイルでKeep Aliveが効いていない問題については、結論からいうと、HTML5 Experts.jpで利用しているHTTPサーバーであるnginxの仕様が問題となっていました。元々、SafariにはKeep-Aliveが効いていると、ファイルがアップロードできないというバグ（該当のissueは<a href="https://bugs.webkit.org/show_bug.cgi?id=5760" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">こちら</a>）があり、それに対応する形でnginx側はSafariに対してデフォルトでKeep-Aliveを無効にするという対策を取っています（<a href="http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_disable" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><code>keepalive_disable</code></a>の設定）。HTML5 Experts.jpでは、ユーザーがファイルをアップロードするユースケースはないので、nginxの設定に&#8221;keepalive_disable none;&#8221;を指定してKeep-Aliveの無効を取り消しています。また同時に、Keep-Aliveのタイムアウトをデフォルトの75秒から20秒に変更しています。これは、現状の読み込み完了までの時間が20秒を超えることはほぼないためです。</p>

<p>その結果、モバイルでも同時接続数分のコネクション（別ドメインの接続を除く）を確保した以降は、Initial Connectionが消え、全体で2秒近く高速になりました。これを見ると、別ドメインへのアクセスを整理することによってもう少し効率化できそうではありますが、今回はここまでとしました。</p>

<div id="attachment_14713" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/04/92aca65bdef067d637b7d516a27affac.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/04/92aca65bdef067d637b7d516a27affac.png" alt="モバイルのタイムライン（ウォーターフォール図）" width="640" height="410" class="size-full wp-image-14713" srcset="/wp-content/uploads/2015/04/92aca65bdef067d637b7d516a27affac.png 640w, /wp-content/uploads/2015/04/92aca65bdef067d637b7d516a27affac-300x192.png 300w, /wp-content/uploads/2015/04/92aca65bdef067d637b7d516a27affac-207x133.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">モバイルのタイムライン（ウォーターフォール図） *Initial Connecctionはオレンジ色の部分</p></div>

<h2>まとめ</h2>

<p>これまで5つの改善ポイントについて、記事中の通り改善を実施してきました。これによってどのようにパフォーマンスが改善したのかを、この企画における全期間中のパフォーマンストレンドの推移でご覧いただきたいと思います。</p>

<div id="attachment_14760" style="width: 610px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/04/11164093_10205366450694456_612702970_n.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/04/11164093_10205366450694456_612702970_n.jpg" alt="全期間中のパフォーマンストレンドの推移（PC版）" width="600" height="300" class="size-full wp-image-14760" srcset="/wp-content/uploads/2015/04/11164093_10205366450694456_612702970_n.jpg 600w, /wp-content/uploads/2015/04/11164093_10205366450694456_612702970_n-300x150.jpg 300w, /wp-content/uploads/2015/04/11164093_10205366450694456_612702970_n-207x104.jpg 207w" sizes="(max-width: 600px) 100vw, 600px" /></a><p class="wp-caption-text">全期間中のパフォーマンストレンドの推移（PC版）</p></div>

<div id="attachment_14761" style="width: 610px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/04/11118066_10205366461014714_1779935700_n.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/04/11118066_10205366461014714_1779935700_n.jpg" alt="全期間中のパフォーマンストレンドの推移（モバイル版）" width="600" height="400" class="size-full wp-image-14761" srcset="/wp-content/uploads/2015/04/11118066_10205366461014714_1779935700_n.jpg 600w, /wp-content/uploads/2015/04/11118066_10205366461014714_1779935700_n-300x200.jpg 300w, /wp-content/uploads/2015/04/11118066_10205366461014714_1779935700_n-207x138.jpg 207w" sizes="(max-width: 600px) 100vw, 600px" /></a><p class="wp-caption-text">全期間中のパフォーマンストレンドの推移（モバイル版）</p></div>

<p>いずれも大きく改善され、PC版では5秒台から2秒以下に、モバイル版では20秒前後で大きく揺れていたものが安定して8秒近辺に落ち着いています。これらの結果を受けて、解析編で掲げた改善目標が達成されているかどうかを、個別のデータで確認していきたいと思います。</p>

<h3>改善目標</h3>

<ol>
<li>Total Time（サイトにアクセスした時点からブラウザ上でコンテンツ表示が完了するまでの時間）は2秒を切る</li>
<li>アクセスした際のTotal Timeに関する品質を一定にする（ばらつきをなくして一定にする）</li>
<li>3G回線からのTotal Timeに関するアクセス品質をブロードバンド回線のそれに近づける</li>
</ol>

<p>まずは、改善後のPC版の各ブラウザの計測結果を見ていきましょう。 次のグラフは、トップページの1日の計測結果です。（時間帯によってはネットワーク品質に揺れがあり、計測結果が多少上下します。）</p>

<div id="attachment_14731" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/04/6ff19498d0260feeede914b24cb57df6.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/04/6ff19498d0260feeede914b24cb57df6.png" alt="PC版のTotal Time（折れ線グラフ） *Chrome、Firefox、IE" width="640" height="359" class="size-full wp-image-14731" srcset="/wp-content/uploads/2015/04/6ff19498d0260feeede914b24cb57df6.png 640w, /wp-content/uploads/2015/04/6ff19498d0260feeede914b24cb57df6-300x168.png 300w, /wp-content/uploads/2015/04/6ff19498d0260feeede914b24cb57df6-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">PC版のTotal Time（折れ線グラフ） *Chrome:黄色、Firefox:青、IE:赤</p></div>

<p>それぞれの平均Total Timeは、Chromeが1.59秒、Firefoxが1.657秒、IEが1.125秒という結果となりました。<strong>当初目標の「Total Timeは2秒を切る」という点では、余裕を持ってクリアしています</strong>。特にIEの場合、1秒を切るケースもあり非常に高速です。次に同じデータをスキャッタプロットで分布を見てみましょう。</p>

<div id="attachment_14739" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/04/685b2b40e0bf4944bb04731ed376bf7f.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/04/685b2b40e0bf4944bb04731ed376bf7f.png" alt="PC版のTotal Time（スキャッタプロット） *Chrome:薄緑、Firefox:オレンジ、IE:青" width="640" height="312" class="size-full wp-image-14739" srcset="/wp-content/uploads/2015/04/685b2b40e0bf4944bb04731ed376bf7f.png 640w, /wp-content/uploads/2015/04/685b2b40e0bf4944bb04731ed376bf7f-300x146.png 300w, /wp-content/uploads/2015/04/685b2b40e0bf4944bb04731ed376bf7f-207x101.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">PC版のTotal Time（スキャッタプロット） *Chrome:薄緑、Firefox:オレンジ、IE:青</p></div>

<p>スキャッタプロットで見ると、各点がきちんと下に寄っているのがわかります。はずれ値も少し見られますが、およそ95%の計測値が2.5秒以下の範囲に収まっています。そのため、<strong>「アクセスした際のTotal Timeに関する品質を一定にする」も達成している</strong>と言えるでしょう。</p>

<p>最後に改善後のモバイル版のトップページの計測結果を見ていきます。次の2つのグラフは、3G回線でのXperiaとiPhone6S、参考としてLAN環境でのiPhone6を加えたものです。</p>

<div id="attachment_14744" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/04/67ecdef4d389322afe8d57b9909c9ee5.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/04/67ecdef4d389322afe8d57b9909c9ee5.png" alt="モバイル版のTotal Time（折れ線グラフ） *Xperia(3G):オレンジ、iPhone6S(3G):赤、iPhone6(LAN):青" width="640" height="356" class="size-full wp-image-14744" srcset="/wp-content/uploads/2015/04/67ecdef4d389322afe8d57b9909c9ee5.png 640w, /wp-content/uploads/2015/04/67ecdef4d389322afe8d57b9909c9ee5-300x167.png 300w, /wp-content/uploads/2015/04/67ecdef4d389322afe8d57b9909c9ee5-207x115.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">モバイル版のTotal Time（折れ線グラフ） *Xperia(3G):オレンジ、iPhone6S(3G):赤、iPhone6(LAN):青</p></div>

<p>モバイルの場合、ネットワーク品質の揺れ幅が大きくなりますが、平均ではXperiaが12.863秒、iPhone6Sが8.601秒となっています。参考値であるLAN環境のiPhone6が平均0.486秒であることを考えると、3G回線がパフォーマンスに大きく影響していることがわかります。これは、画像ファイルの数、ダウンロード容量が多いためで、ネットワークに遅延が発生すると大きく影響します。この時の画像ファイル数は38で、サイト全体の容量は400KB程度になっています。これは、HTML5 Experts.jpのメディアの特性を考えると、ある程度はやむ得ないと思いますが、もう少し減らせるように工夫すべきかもしれません。救いとしては、遅延の原因が画像ファイルにあるので、ファーストビューへの影響は比較的少なく、体感速度は数値よりも早く感じるという点でしょうか。</p>

<div id="attachment_14745" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/04/ba7509afad0430b432f7d6b553130234.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/04/ba7509afad0430b432f7d6b553130234.png" alt="モバイル版のTotal Time（スキャッタプロット） *Xperia(3G):薄緑、iPhone6S(3G):オレンジ、iPhone6(LAN):オレンジ" width="640" height="315" class="size-full wp-image-14745" srcset="/wp-content/uploads/2015/04/ba7509afad0430b432f7d6b553130234.png 640w, /wp-content/uploads/2015/04/ba7509afad0430b432f7d6b553130234-300x148.png 300w, /wp-content/uploads/2015/04/ba7509afad0430b432f7d6b553130234-207x102.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">モバイル版のTotal Time（スキャッタプロット） *Xperia(3G):薄緑、iPhone6S(3G):オレンジ、iPhone6(LAN):オレンジ</p></div>

<p>スキャッタプロットのほうを見ると、3G回線のために値の範囲が広がっていますが、概ね下に寄っているように見えるので許容範囲内であると言えるかと思います。しかしながら、前述の問題から<strong>「3G回線からのTotal Timeに関するアクセス品質をブロードバンド回線のそれに近づける」については、大きく改善してはいるものの課題が残っている</strong>という結論としたいと思います。</p>

<p>皆さん、いかがでしたでしょうか。本記事で改善した結果は是非、皆さんの手で体感していただければと思います。HTML5 Experts.jpでは、これからもパフォーマンス改善を続けていきますので、HTML5 Experts.jpを今後とも宜しくお願いいたします。また、この企画に大変なご協力をいただいた<a href="http://spelldata.co.jp/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">株式会社Spelldata</a>の<a href="https://html5experts.jp/takehora/" target="_blank" data-wpel-link="internal">竹洞陽一郎さん</a>にこの場を借りて厚くお礼申し上げます。ありがとうございました！！</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/04/DSC00750.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/04/DSC00750.jpg" alt="" width="640" height="480" class="aligncenter size-full wp-image-14767" srcset="/wp-content/uploads/2015/04/DSC00750.jpg 640w, /wp-content/uploads/2015/04/DSC00750-300x225.jpg 300w, /wp-content/uploads/2015/04/DSC00750-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<h3>補足事項</h3>

<p>本記事で扱っている計測結果は、改善実施直後の数値です。現在の数値とは異なることがあることをご了承ください。特に本記事の内容より以降に、HTTPS（SPDY対応）化を実施しており、Total Timeは全体的に伸びています。そのあたりの対応についても、別の機会で紹介できればと思います。</p>
]]></content:encoded>
			</item>
		<item>
		<title>HTML5 Experts.jpはなぜこんなにパフォーマンスが悪いのか…全てお見せします！ーWebパフォーマンス改善企画（解析編）</title>
		<link>/yusuke-naka/13671/</link>
		<pubDate>Tue, 21 Apr 2015 00:41:59 +0000</pubDate>
		<dc:creator><![CDATA[仲 裕介]]></dc:creator>
				<category><![CDATA[サイト制作]]></category>
		<category><![CDATA[パフォーマンス]]></category>
		<category><![CDATA[高速化]]></category>

		<guid isPermaLink="false">/?p=13671</guid>
		<description><![CDATA[　HTML5 Experts.jp編集部の企画会議で、ある日、編集部員からこんな発言がー。「HTML5 Experts.jpのサイトってなんとなく遅くないですか？レスポンスとか」そうすると、執筆者の方からもそのような話を...]]></description>
				<content:encoded><![CDATA[<p>　HTML5 Experts.jp編集部の企画会議で、ある日、編集部員からこんな発言がー。<strong>「HTML5 Experts.jpのサイトってなんとなく遅くないですか？レスポンスとか」</strong>そうすると、執筆者の方からもそのような話を聞くことがあるなど、パフォーマンスの話題は盛り上がり、<strong>「よし、Webサイトのパフォーマンス改善をやろう！」</strong>ということになりました。（かなり中身省略してますが）この連載では、HTML5 Experts.jpのパフォーマンス改善の模様を包み隠さずレポートします！</p>

<h2>24時間365日計測してますか？</h2>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/takehora1.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/takehora1-300x200.jpg" alt="takehora1" width="300" height="200" class="alignright size-medium wp-image-13998" srcset="/wp-content/uploads/2015/03/takehora1-300x200.jpg 300w, /wp-content/uploads/2015/03/takehora1.jpg 640w, /wp-content/uploads/2015/03/takehora1-207x138.jpg 207w" sizes="(max-width: 300px) 100vw, 300px" /></a>
まずは、有識者の方にいろいろとアドバイスをもらったほうがいいよね、ということで、<a href="http://spelldata.co.jp/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">株式会社Spelldata</a>の代表取締役社長でありWebパフォーマンスに精通する、エキスパートの<a href="https://html5experts.jp/takehora/" target="_blank" data-wpel-link="internal">竹洞陽一郎さん</a>に今回の企画の頭出しをしました。</p>

<p><style>
.post-detail-contents p {
  text-indent:0
}
</style></p>

<p><strong>仲</strong>：そんなわけで、HTML5 Experts.jpのパフォーマンスになんとなく不満を抱く声があるため、それを改善したいと思ってるんですよ。そして、その模様を赤裸々に記事として公開するというなんともマゾな企画を考えているのですが…ご協力いただけますか？</p>

<p><strong>竹洞</strong>：もちろんです。協力しますよ！</p>

<p>ーあっさりOKが！</p>

<p><strong>仲</strong>：ありがとうございます！じゃあ、手始めに今のサイトの状態を見てもらいましょうか。</p>

<p>そうして、私はおもむろにPCを広げて、Webサイトをプロジェクターに写そうとしました…。</p>

<p><strong>竹洞</strong>：<big>ちょっと待って下さい！</big>
<a href="https://html5experts.jp/wp-content/uploads/2015/03/takehora2.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/takehora2.jpg" alt="takehora2" width="640" height="427" class="aligncenter size-full wp-image-14001" srcset="/wp-content/uploads/2015/03/takehora2.jpg 640w, /wp-content/uploads/2015/03/takehora2-300x200.jpg 300w, /wp-content/uploads/2015/03/takehora2-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>竹洞さんから待ったが！！！</p>

<p><strong>竹洞</strong>：そうやって場当たり的にやっても、Webパフォーマンスの改善は意味がありません。まずは、現状を見極めるためにしばらくデータ計測する必要があります。さらに言うと、24時間365日、つまりは定常的に計測していくことが、Webパフォーマンスの改善には何より重要なんです。</p>

<p><strong>仲</strong>：定常的な計測が必要な理由って？</p>

<p><strong>竹洞</strong>：Webパフォーマンスに影響を及ぼす要因には様々なモノがあります。HTMLの書き方やWebサイトの作りなどコンテンツ面の要因もあれば、サイトをホスティングしているサーバの要因、サイト閲覧者が利用しているインターネット回線の要因、サイト閲覧者の端末要因等…挙げたら切りがありません。そして、それはら、日々変化しています。その一瞬だけを切り取って、パフォーマンスがいいとか悪いとか言っても、それは本質ではないんです。</p>

<p><strong>仲</strong>：なるほどー。</p>

<p>この辺りの詳しい解説は、竹洞さんのインタビュー記事をご覧ください！
<a href="https://html5experts.jp/shumpei-shiraishi/11599/" target="_blank" data-wpel-link="internal"><a href="https://html5experts.jp/shumpei-shiraishi/11599/"><img src="/wp-content/uploads/2015/03/sc3.png" alt="sc3" width="640" height="222" class="aligncenter size-full wp-image-14022" srcset="/wp-content/uploads/2015/03/sc3.png 640w, /wp-content/uploads/2015/03/sc3-300x104.png 300w, /wp-content/uploads/2015/03/sc3-207x72.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p class="aligncenter">「UXとWebパフォーマンス、そののっぴきならない関係 – 竹洞陽一郎ロングインタビュー」</p>

<p></a></p>

<p><strong>竹洞</strong>：まずは短期間ではありますがデータを計測しますので、その計測データを基に、現状整理をしましょう。</p>

<p>それから、Webパフォーマンス改善にあたって１つ確認があります。必ずと言っていいほど皆さんが引っかかることなのですが、Webサイトの構築運用に関する様々なしがらみを徹底的に排除できますか？</p>

<p><strong>仲</strong>：ーしがらみですか？うーん、HTML5 Experts.jpは、<strong>限りなく非営利</strong>で、<strong>限りなく中立に近い</strong>メディアを目指しています。しがらみは少ないほうだと思いますよ。大丈夫です！（この自信はあとであっけなく崩れ去る…）</p>

<p>こうして、竹洞さんのご好意で、<a href="http://www.keynote.com/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Keynote Systems社</a>が提供するSynthesis Monitoring(合成計測)サービスにて、サイトのデータ計測が始まりました。</p>

<p>まずは計測対象の選定です。HTML5 Experts.jpでは、トップページと個別の記事ページの２種類が主なアクセス先になるため、以下のとおり、その2つを測定することにしました。</p>

<div style="width:300px; float:left;">
<p class="aligncenter">トップページ</p>
<a href="https://html5experts.jp/wp-content/uploads/2015/03/sc1.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/sc1-300x300.png" alt="sc1" width="300" height="300" class="aligncenter size-medium wp-image-14014" srcset="/wp-content/uploads/2015/03/sc1-300x300.png 300w, /wp-content/uploads/2015/03/sc1-150x150.png 150w, /wp-content/uploads/2015/03/sc1.png 640w, /wp-content/uploads/2015/03/sc1-207x207.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a>
<p class="aligncenter"><small>＊画像は記事執筆時にキャプチャしたものです</small></p>
</div>

<div style="width:300px; float:right;">
<p class="aligncenter">個別記事（竹洞さんのインタビュー記事）</p>
<a href="https://html5experts.jp/wp-content/uploads/2015/03/sc2.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/sc2-300x298.png" alt="sc2" width="300" height="298" class="aligncenter size-medium wp-image-14015" srcset="/wp-content/uploads/2015/03/sc2-300x298.png 300w, /wp-content/uploads/2015/03/sc2-150x150.png 150w, /wp-content/uploads/2015/03/sc2.png 640w, /wp-content/uploads/2015/03/sc2-207x207.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a>
</div>

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

<p>それぞれのページの計測条件は以下のとおりです。尚、スマートフォンデバイスは、実機ではなくシミュレータを利用します。これは、ハードウェアのスペックを統一することで、ハードウェアの性能差による遅延等の要因を排除するためです。</p>

<table>
<thead>
<tr>
  <th>端末</th>
  <th>利用ブラウザ、端末等</th>
  <th>回線</th>
</tr>
</thead>
<tbody>
<tr>
  <td>PC1</td>
  <td>Chrome 31.0.1650.63</td>
  <td>LAN（ブロードバンド回線）</td>
</tr>
<tr>
  <td>PC2</td>
  <td>Firefo 14.0.1</td>
  <td>LAN（ブロードバンド回線）</td>
</tr>
<tr>
  <td>PC3</td>
  <td>Internet Explorer 9</td>
  <td>LAN（ブロードバンド回線）</td>
</tr>
<tr>
  <td>Android1</td>
  <td>Sony SO-04D（Android 4.0.4の標準ブラウザ）</td>
  <td>3G回線</td>
</tr>
<tr>
  <td>iPhone1</td>
  <td>iPhone6（Mobile Safari）</td>
  <td>LAN（ブロードバンド回線）</td>
</tr>
<tr>
  <td>iPhone2</td>
  <td>iPhone6（Mobile Safari）</td>
  <td>3G回線</td>
</tr>
<tr>
  <td>iPhone3</td>
  <td>iPhone6S（Mobile Safari）</td>
  <td>3G回線</td>
</tr>
</tbody>
</table>

<p>ちなみに後日談…計測対象の個別記事ですが、計測のためのアクセスがかなりの頻度あるため、PVランキングでは常に1位を独占していました（笑）。また、Google Analyticsについても、計測開始前に除外設定しておかないと、正確なデータが得られなくなりますので、ご注意下さい。</p>

<h2>計測して問題点を洗い出す</h2>

<h3>ファーストバイトダウンロードタイムの遅延問題</h3>

<p>ということで、竹洞さんに一定期間サイトのパフォーマンスデータを計測してもらいました。その結果を見ながら、早速現在のHTML5 Experts.jpの問題点を洗い出します。</p>

<p><strong>竹洞</strong>：これがある日の、ブロードバンド回線でChromeを用いてアクセスした時の計測結果です。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/Chrome_hx1.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/Chrome_hx1.png" alt="Chrome_hx1" width="640" height="248" class="aligncenter size-full wp-image-13687" srcset="/wp-content/uploads/2015/03/Chrome_hx1.png 640w, /wp-content/uploads/2015/03/Chrome_hx1-300x116.png 300w, /wp-content/uploads/2015/03/Chrome_hx1-207x80.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>見ての通り、ID1のhtmlの取得にすごく時間がかかっていることがわかります。この水色は、ファーストバイトダウンロードタイム（Time To First Byte、以下、TTFB）といって、サーバへのイニシャル接続からコンテンツの１バイト目が到着するまでの時間になります。このHTMLのTTFBの遅延は、計測期間全体を通して見られる傾向です。まずは、ここを短縮させるために、原因の調査、対策を行う必要がありますね。</p>

<p><strong>仲</strong>：確かに、サイトアクセス時やサイト内でリンクをクリックした時に、一瞬ブラウザが固まったようになることが多々あるんですよね。何か引っ掛かってるなーって感じで。原因はこれでしたか。</p>

<p><strong>竹洞</strong>：TTFBに時間が掛かる一般的な要因については、次のサイトの情報が参考になります。<a href="http://www.websiteoptimization.com/speed/tweak/time-to-first-byte/" targe="_blank" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Diagnosing Slow Web Servers with Time to First Byte</a></p>

<p>よくあるパターンとしては、動的にHTMLを生成する処理に時間がかかっている場合が多いのですが、それには例えばこんな要因が挙げられますね。心当たりはありますか？ちなみに、3と4については、サーバサイドでレンダリングされるコンテンツ以外（たとえば、JavaScript）にも遅延が出ているので、今回に限って言えば、直接的な要因とは考えにくいです。</p>

<ol>
<li>Memory leaks（メモリ不足）</li>
<li>Too many processes/connections（CPU性能不足）</li>
<li>Inefficient SQL Queries（SQLが最適化されていない）  </li>
<li>Slow database call（データベースアクセスに時間が掛かる）  </li>
</ol>

<p><strong>仲</strong>：HTML5 Experts.jpはNTTコミュニケーションズの<a href="http://www.ntt.com/cloudn/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Cloudn</a>というパブリック・クラウド・サービスを利用しています。VMのプランとしてはv8プラン（仮想CPU８コア、メモリ16GB）を選んでいます。今現在、メモリとCPUの使用状況を見る限り、そこまで枯渇しているとは思えないですね。</p>

<p><strong>竹洞</strong>：なるほど。とはいえ、サーバサイド（ネットワーク環境含めて）のどこかにボトルネックがあることは確かなので、設定などを細かく見ていくしかないですね。あとは、サーバ側でキャッシュを効かせるのも手ですね。サーバサイドの処理に時間がかかっているとすれば、WordPressなどでキャッシュを効かせると、静的コンテンツをダウンロードするのとほとんど変わらなくはずなので、間違いなく効果は出ますね。</p>

<p><strong>仲</strong>：WordPressのキャッシュはパフォーマンス改善では鉄板ですね。とはいえ、HTML5 Experts.jpでは導入できてないわけですが…。検討します！</p>

<h3>コンテンツダウンロード時間の遅延</h3>

<p><strong>竹洞</strong>：次に、このデータを見て下さい。これはある日の、iPhone6を用いて3G回線でアクセスした時の計測結果です。情報メディアなので画像が多いのは仕方ないと思うんですが、ダウンロードに時間がかかりすぎてますね。だいたい50ms以下で終わるぐらいじゃないと体感的には遅く感じてしまうかなと思います。jsファイルも然りですね。3G回線なので回線状況によりけりですが。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/iphone63g1.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/iphone63g1.png" alt="iphone63g1" width="640" height="272" class="aligncenter size-full wp-image-14032" srcset="/wp-content/uploads/2015/03/iphone63g1.png 640w, /wp-content/uploads/2015/03/iphone63g1-300x128.png 300w, /wp-content/uploads/2015/03/iphone63g1-207x88.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><strong>仲</strong>：ダウンロード時間の遅延要因として、サーバサイドで気をつけることって何かありますか？</p>

<p><strong>竹洞</strong>：そうですねー。画像データとかはCDNサービス（コンテンツデリバリネットワークサービス）を用意してそこから配信していますか？</p>

<p><strong>仲</strong>：いえ、CDNは今は使っていません。全て同じサーバから配信しています。</p>

<p><strong>竹洞</strong>：であれば、サーバのディスクスペックが影響しているんじゃないでしょうか？ディスクからのデータの読み出し速度ですね。オススメは、SSD等の高速なディスクを用意することです。また、できれば、画像データ等は専用サーバから配信した方がよいです。ハードディスクアクセスの競合を避けられて、負荷分散にもなります。大規模アクセスサイトでは、一般的に使われる手法です。</p>

<p>仮にそれが厳しいようであれば、サーバをもっとスペックアップするという手立てもありますが、クラウドサービス全盛の時代で、ディスク性能なんて大体のクラウドサービスでは開示されていないですよね。なので、画像に関しては、以下の様な対策を打つのはどうでしょうか？</p>

<ol>
<li>そもそも画像の数を減らす（テキスト＋CSSやSVGで置き換えられるものは極力外す）</li>
<li>実際の表示サイズより大きな画像は適正なサイズに変更する</li>
<li>Expiresヘッダ、Cache-Controlヘッダを付与してブラウザ側でキャッシュを効かせる（これはそもそもサーバアクセスしないので、一番効果が有ります）</li>
</ol>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/naka1.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/naka1-300x200.jpg" alt="naka1" width="300" height="200" class="alignright size-medium wp-image-14038" srcset="/wp-content/uploads/2015/03/naka1-300x200.jpg 300w, /wp-content/uploads/2015/03/naka1.jpg 640w, /wp-content/uploads/2015/03/naka1-207x138.jpg 207w" sizes="(max-width: 300px) 100vw, 300px" /></a>
<strong>仲</strong>：なるほど、なるほど。うーん、実はCloudnには<a href="https://www.ntt.com/cloudn/data/cdn.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">CDNサービス</a>もあるんですよね。それの利用も少し検討したんですが、1つ問題があってですねー。HTML5 Experts.jpはCMSとしてWordPressを利用しているのですが、管理画面はSSLアクセスにしています。そして、CloudnのCDNがSSLに対応していないんですよ…。弊社（私はNTTコミュニケーションズ社員です）としては、社外のCDNを利用するにも、機能改善を要望するにも部署が違ってちょっとすぐには…あ、聞かなかったことにして下さい（笑）。</p>

<p><strong>竹洞</strong>：Webパフォーマンスを継続的に改善していく上で、重要なことが1つあるのですが、知ってますか？</p>

<p><strong>仲</strong>：え、なんですか？？？</p>

<p><strong>竹洞</strong>：それは、前回の打ち合わせ申し上げましたが、様々なしがらみを断ち切ることです。</p>

<p><strong>仲</strong>：あ……。</p>

<p><strong>竹洞</strong>：今回みたいに、使えるサービスに制約があったり、社内で部署をまたがって運営していていたりする場合の責任のなすりつけ合いとかも、ある意味しがらみですよね。その他よくある事例としては、</p>

<p>「ECサイトなのに下手にパフォーマンス計測すると、悪い点部分がお客さんにわかってしまって逆効果になりかねないので…」</p>

<p>「お金かかりますよね、パフォーマンス向上に伴う費用対効果を説明できないので無理ですねー」</p>

<p>「パフォーマンスが重要ってのはわかってるんですが、構築から運用までSierさんに任せてるんで、ちょっと無理ですね…」</p>

<p>などがありますね。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/takehora3.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/takehora3-300x200.jpg" alt="takehora3" width="300" height="200" class="alignright size-medium wp-image-14040" srcset="/wp-content/uploads/2015/03/takehora3-300x200.jpg 300w, /wp-content/uploads/2015/03/takehora3.jpg 640w, /wp-content/uploads/2015/03/takehora3-207x138.jpg 207w" sizes="(max-width: 300px) 100vw, 300px" /></a>
そもそも、日本は、欧米に比べて、ソフトウェア品質が悪いんですよ。Webに関して言えば、その品質の悪さはさらに悪化します。そして、テスト系のソリューションやサービスが売れない市場としても、その業界では有名な話なんですよね。もちろん、各社それぞれの事情があることは承知しているのですが、聞いているだけで暗くなります。なので、できる範囲で頑張ってくれるだけでも、簡単にすごく品質が向上すると思います。それによる効果は必ず現れてきますよ。いかがでしょうか？</p>

<p><strong>仲</strong>：わ、わかりました！できる範囲で頑張ります！<big>さすが、HTML5 Experts.jpだ</big>！というところを見せてやりますよ。</p>

<p><strong>竹洞</strong>：さすが！（笑）。</p>

<p><strong>白石（編集長）</strong>：話を戻して、クライアント側でのキャッシュですが、画像データの名称を全てユニークにしてExpiresヘッダーの時間を1年以上とかに設定するかんじでしょうかね。ただ、これは運用が難しいですね。画像を後から差し替える際は都度ファイル名を変更するなどの、工夫が必要ですから。特にHTML5 Experts.jpは記事をエキスパートやコントリビューターの皆さんに書いてもらうかたちを取っているので、きちんと運用を回すのは苦労しそう。</p>

<p><strong>仲</strong>：そうですね。1についても、感覚的には置き換えできそうなところは限られてますので、まずは2の対策を検討しましょう。WordPress側のキャッシュと組み合わせるとかなり効果が出るかもしれません。</p>

<h3>パフォーマンスには悪でしかないソーシャルメディア系サービスの導入</h3>

<p><strong>竹洞</strong>：次のデータはこちらです。これらも先ほどと同様に、iPhone6で3G回線を用いてアクセスした結果ですが、何が言いたいかといいますと、ソーシャル系サービスのシェアボタンやコメント機能などを埋め込んでいるため、それらに関係するファイルのダウンロードに多くの時間をとられています、ということなんですね。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/sns1.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/sns1-640x59.png" alt="sns1" width="640" height="59" class="aligncenter size-large wp-image-14042" srcset="/wp-content/uploads/2015/03/sns1.png 640w, /wp-content/uploads/2015/03/sns1-300x28.png 300w, /wp-content/uploads/2015/03/sns1-207x19.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/sns2.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/sns2-640x70.png" alt="sns2" width="640" height="70" class="aligncenter size-large wp-image-14043" srcset="/wp-content/uploads/2015/03/sns2.png 640w, /wp-content/uploads/2015/03/sns2-300x33.png 300w, /wp-content/uploads/2015/03/sns2-207x23.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/sns3.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/sns3-640x52.png" alt="sns3" width="640" height="52" class="aligncenter size-large wp-image-14044" srcset="/wp-content/uploads/2015/03/sns3.png 640w, /wp-content/uploads/2015/03/sns3-300x24.png 300w, /wp-content/uploads/2015/03/sns3-207x17.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/sns4.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/sns4-640x57.png" alt="sns4" width="640" height="57" class="aligncenter size-large wp-image-14045" srcset="/wp-content/uploads/2015/03/sns4.png 640w, /wp-content/uploads/2015/03/sns4-300x27.png 300w, /wp-content/uploads/2015/03/sns4-207x18.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/sns5.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/sns5-640x52.png" alt="sns5" width="640" height="52" class="aligncenter size-large wp-image-14046" srcset="/wp-content/uploads/2015/03/sns5.png 640w, /wp-content/uploads/2015/03/sns5-300x24.png 300w, /wp-content/uploads/2015/03/sns5-207x17.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/sns6.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/sns6-640x78.png" alt="sns6" width="640" height="78" class="aligncenter size-large wp-image-14047" srcset="/wp-content/uploads/2015/03/sns6.png 640w, /wp-content/uploads/2015/03/sns6-300x37.png 300w, /wp-content/uploads/2015/03/sns6-207x25.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>特に回線が貧弱な3G回線でのアクセスの場合、これらのせいで本来見たいはずのコンテンツがなかなか表示されずに、サイト訪問者をイライラさせることはざらにあります。もちろん、マークアップの仕方次第である程度は改善されますけど、抜本的な改善にはなりませんね。</p>

<p><strong>仲</strong>：うーん、なるほど。とはいえ、ソーシャル系サービスでの拡散って、我々のような情報メディアには必須なんですよね。これを全部なくすのは痛いですよ、痛すぎます。</p>

<p><strong>竹洞</strong>：<big>全部なくしてください！</big>と、本来は言いたいところですが（笑）、今は自作のソーシャルボタンを導入しているサイトも結構ありますから、ソーシャルボタンを載せつつ、パフォーマンスを改善する手立てはあると思いますよ。</p>

<p><strong>仲</strong>：ありがとうございます！わかりました、改善を検討します。</p>

<h3>パフォーマンスを考慮していないWeb制作</h3>

<p><strong>竹洞</strong>：次はこちら。これは、比較的パフォーマンスがよいInternet Explorerによるアクセス結果です。何が言いたいかといいますと、だいたい分かるかとは思いますが、JavaScriptやCSSの数が多すぎですね。CSSはリファクタリングしてまとめましょう。JavaScriptは、サイトの運営上、本当に必要なものだけに絞りこみましょう。HTML5 Experts.jpともあろうメディアがこれじゃダメですよ…。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/sc4.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/sc4.png" alt="sc4" width="640" height="400" class="aligncenter size-full wp-image-14055" srcset="/wp-content/uploads/2015/03/sc4.png 640w, /wp-content/uploads/2015/03/sc4-300x188.png 300w, /wp-content/uploads/2015/03/sc4-207x129.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><strong>仲</strong>：す、すみません…そのとおりですね。</p>

<p><strong>竹洞</strong>：こちらも見てみて下さい。これはChromeでトップページにアクセスした際の、TCPコネクションの数を可視化したConnection Viewというものです。1コネクションを維持する時間はサーバ側のKeep Aliveの設定時間次第ですが、その時間内で最大セッション数に達するまで通信を行うことで、ダウンロード時間を最小にするための努力をします。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/connection_view_chrome.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/connection_view_chrome.jpg" alt="connection_view_chrome" width="325" height="640" class="aligncenter size-full wp-image-14164" srcset="/wp-content/uploads/2015/03/connection_view_chrome.jpg 325w, /wp-content/uploads/2015/03/connection_view_chrome-152x300.jpg 152w, /wp-content/uploads/2015/03/connection_view_chrome-105x207.jpg 105w" sizes="(max-width: 325px) 100vw, 325px" /></a></p>

<p>画像を見ると、黒い帯の途中赤い帯が入っていますよね。黒い帯は1つのTCPコネクションを示していて、その中で並列ダウンロードが行われているのですが、途中でまったく別のTCPコネクション（赤い帯）が入ってきているため、無駄なオーバーヘッドが発生しています。この部分含めて、恐らく、マークアップのやり方などを工夫すると、あと6本程度はコネクションを削減することができると思われます。</p>

<p><strong>仲</strong>：ほー。これはわかりやすいですね。あの赤い帯は、HTML5 Experts Worksのウィジェットに関する通信ですね。</p>

<p><strong>竹洞</strong>：とはいえ、HTML5 Experts.jpについてはWordPressでHTMLを動的生成していますよね。そのため、マークアップの最適化については限界があると思います。そこは、トレードオフで問題ありません。当たり前のことですが、パフォーマンス・チューニングでは、費用・品質・期間のトレードオフは重要です。</p>

<p>また、ChromeやFirefoxの場合は、SPDY（HTTP2になればIEも対応予定）を活用することで、このTCPコネクションによるオーバーヘッドを最小限に押さえることが可能です。その代わり、SPDYを入れることのデメリット（オーバーヘッド）も発生するため、ターゲットブラウザなどを考慮して慎重に判断して下さい。</p>

<p><strong>仲</strong>：ありがとうございます！運用上、WordPressをやめて全てスタティックなWebサイトに変えるのは、HTML5 Experts.jpとしては現実的ではないですね。まずは、できる限り、マークアップの見直しを検討してみたいと思います。</p>

<h3>モバイル環境でKeep Aliveが効いていない</h3>

<p><strong>竹洞</strong>：次にKeep Aliveについて確認していただきたいことがあります。こちらをご覧ください。これは、iPhone6で3G回線を用いてアクセスした結果です。各オブジェクトのタイムラインのグラフにオレンジ色の帯が見えますよね。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/sc8.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/sc8.png" alt="sc8" width="640" height="283" class="aligncenter size-full wp-image-14165" srcset="/wp-content/uploads/2015/03/sc8.png 640w, /wp-content/uploads/2015/03/sc8-300x133.png 300w, /wp-content/uploads/2015/03/sc8-207x92.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><strong>仲</strong>：そうですね。これ、たしか、PCからのアクセス結果にはありませんでした。</p>

<p><strong>竹洞</strong>：はい、モバイルアクセス特有の結果です。これは、Initial Connectionが毎回走っていることを示しています。Initial Connectionとは、いわゆる、TCP/IPの3way handshakesを指しています。新しいオブジェクトをダウンロードする度に、毎回TCPコネクションのオーバーヘッドが発生していることになります。先ほど、Keep Aliveの設定時間次第という話をしましたが、そもそも効いていない可能性があるため、必ず確認をお願いします。</p>

<p><strong>仲</strong>：なんと…。分かりました。確認します。</p>

<h3>Internet Explorerは優秀なやつ</h3>

<p><strong>仲</strong>：前のお話でターゲットブラウザを考慮してというコメントがありましたが、ブラウザごとの差異を見ることって可能ですか？</p>

<p><strong>竹洞</strong>：はい、可能です。これは、トップページの表示開始時間の変化を一定期間、折れ線グラフにしたものです。Internet Explorerは赤紫色、Firefoxはオレンジ色、Chromeは緑色の線でそれぞれ描かれています。回線はブロードバンド回線を利用しています。縦軸がTotal Timeになっていて、短いほど好成績です。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/sc5.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/sc5.png" alt="sc5" width="640" height="313" class="aligncenter size-full wp-image-14063" srcset="/wp-content/uploads/2015/03/sc5.png 640w, /wp-content/uploads/2015/03/sc5-300x147.png 300w, /wp-content/uploads/2015/03/sc5-207x101.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>表示開始時間というのは、ブラウザ画面上でコンテンツが表示開始されるまでの時間です。この時間はユーザエクスペリエンスに影響してきます。ちなみに、人間がモノを認識するまでがだいたい200msと言われています。Microsoftは表示開始時間500msを推奨しています。感覚的にはテニスのサーブを打って打ち返してくるまでの時間ですね。決めの問題ですが、私の経験上、いきなり500msは無理としても、最低2秒は切ってほしいなと思います。</p>

<p><strong>仲</strong>：2秒…。</p>

<p><strong>竹洞</strong>：それから、グラフをみて分かる通り、Internet ExplorerやFirefoxが、Chromeに比べ健闘していることがわかります。こういうデータ計測を行うと、経験上、Internet Explorerが一番成績が良くなることが多いですね。</p>

<p><strong>仲</strong>：こんなに差が出るんですかー。同じコンテンツなのに驚きました。それにしても、なぜChromeだけこんなに違うんですか？</p>

<p><strong>竹洞</strong>：Chromeがなぜこんなに時間がかかっているかというと、前処理（ex DOM構築や、プリフェッチ、並列ダウンロードとか）が長いためだと思います。</p>

<p><strong>仲</strong>：表示開始時間なので、テキストコンテンツだけでも先に表示されていればこれはこれはクリアできるんですよね？</p>

<p><strong>竹洞</strong>：そうです、その通りです。ブラウザごとの差異もありますが、コンテンツの作り方次第では、高速化できる可能性もあります。繰り返しになりますが、2秒は最低でも切ってほしいですね。ちなみに、ブラウザ同士の比較であれば、正規分布にしてみてもいいです。これも先ほどの折れ線グラフと同じデータから生成しています。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/Distribution_Chrome.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/Distribution_Chrome-300x280.png" alt="Distribution_Chrome" width="300" height="280" class="aligncenter size-medium wp-image-14066" srcset="/wp-content/uploads/2015/03/Distribution_Chrome-300x280.png 300w, /wp-content/uploads/2015/03/Distribution_Chrome-207x193.png 207w, /wp-content/uploads/2015/03/Distribution_Chrome.png 531w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p class="aligncenter">Chromeの結果</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/Distribution_FF.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/Distribution_FF-300x276.png" alt="Distribution_FF" width="300" height="276" class="aligncenter size-medium wp-image-14067" srcset="/wp-content/uploads/2015/03/Distribution_FF-300x276.png 300w, /wp-content/uploads/2015/03/Distribution_FF-207x191.png 207w, /wp-content/uploads/2015/03/Distribution_FF.png 535w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p class="aligncenter">FireFoxの結果</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/Distribution_IE.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/Distribution_IE-300x274.png" alt="Distribution_IE" width="300" height="274" class="aligncenter size-medium wp-image-14068" srcset="/wp-content/uploads/2015/03/Distribution_IE-300x274.png 300w, /wp-content/uploads/2015/03/Distribution_IE-207x189.png 207w, /wp-content/uploads/2015/03/Distribution_IE.png 537w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p class="aligncenter">Internet Explorerの結果</p>

<p>比較すると、Chromeの裾野の広さは否めませんね。裾野が広いということは、それだけ表示開始時間にばらつきがあるということなので、品質の悪さにつながります。ちなみに、Internet Explorerのバージョンは9です。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/takehora-shiraishi.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/takehora-shiraishi-300x200.jpg" alt="takehora-shiraishi" width="300" height="200" class="alignright size-medium wp-image-14074" srcset="/wp-content/uploads/2015/03/takehora-shiraishi-300x200.jpg 300w, /wp-content/uploads/2015/03/takehora-shiraishi.jpg 640w, /wp-content/uploads/2015/03/takehora-shiraishi-207x138.jpg 207w" sizes="(max-width: 300px) 100vw, 300px" /></a>
<strong>白石（編集長）</strong>：9でこの違いですか！開発者目線だとどうしてもChromeやFirefoxを前提に考えちゃいますし、Internet Explorerよりも早いだろうという先入観で見ちゃうんですよね。Chromeも最初に出てきた頃は間違いなく最速でしたし、その後、ブラウザベンダ各社速度競争になって、気づいたらこういう結果になっていたということでしょうか。なんだか、IEが可愛そうになってきました、風評被害ですね（笑）。</p>

<h3>全体的なトレンドを分析し改善目標を設定する</h3>

<p><strong>竹洞</strong>：これまで個別に改善ポイントを探ってきましたが、最後に改善目標を決めましょう。こちらのデータをご覧ください。これはトップページに関する全ての計測データを基にした、パフォーマンストレンドのデータです。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/sc6.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/sc6.png" alt="sc6" width="371" height="402" class="aligncenter size-full wp-image-14077" srcset="/wp-content/uploads/2015/03/sc6.png 371w, /wp-content/uploads/2015/03/sc6-277x300.png 277w, /wp-content/uploads/2015/03/sc6-191x207.png 191w" sizes="(max-width: 371px) 100vw, 371px" /></a></p>

<p class="aligncenter"><small>＊記事執筆時にシステムより全データを抜き出し打ち合わせ当時のデータのみ切り出しています</small></p>

<p>縦軸はWebサイトアクセスにかかるトータルタイム（サイトにアクセスした時点から、ブラウザ上でコンテンツ表示が完了するまでの時間）を表しています。時間がかかっている2本は3G回線からのアクセスになります。先ほど表示開始時間は2秒を切ってほしいというお願いをしましたが、こちらで2秒を切れるのであれば、尚良いです。</p>

<p><strong>仲</strong>：最終的にパフォーマンストレンドが2秒を切れるように、改善を行うというというかんじになりますかね。</p>

<p><strong>竹洞</strong>：そうですね。それがいいと思います。こちらもご覧ください。これは、先ほどのデータをスキャッタープロットという形で表したものです。縦軸はTotal Timeのデータ分布を表していて、どのくらいの位置にデータが集中しているのかを見ることができます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/sc7.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/sc7.png" alt="sc7" width="640" height="281" class="aligncenter size-full wp-image-14080" srcset="/wp-content/uploads/2015/03/sc7.png 640w, /wp-content/uploads/2015/03/sc7-300x132.png 300w, /wp-content/uploads/2015/03/sc7-207x91.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>本来は全ての計測値が下の方に寄っているべきなのですが、かなりばらついて、上の方にも出ているのがわかります。オレンジ色と水色は3G回線のデータです。前半上手くデータが取れていないため、最後のほうで一気にデータが増えていますが、3G回線による計測点が集まっている場所のレンジは、ブロードバンド回線によるそれに比べ、かなり幅が大きいように見えます。回線状況にも影響されるとは思いますが、結論としては、3G回線の品質が悪いということが言えますね。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/03/naka.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/03/naka-300x200.jpg" alt="naka" width="300" height="200" class="alignright size-medium wp-image-14091" srcset="/wp-content/uploads/2015/03/naka-300x200.jpg 300w, /wp-content/uploads/2015/03/naka.jpg 640w, /wp-content/uploads/2015/03/naka-207x138.jpg 207w" sizes="(max-width: 300px) 100vw, 300px" /></a>
<strong>仲</strong>：確かに、くっきりと違いが見えますね。</p>

<p><strong>竹洞</strong>：改善目標としては、全体的にばらつきをなくして品質を一定にすることと、3G回線によるアクセス品質をブロードバンド回線にのそれに極力近づけるという、2つも加えてみてはいかがでしょうか？</p>

<p><strong>仲</strong>：助言ありがとうございます！その3点を改善目標としては、改善を進めたいと思います。</p>

<h2>まとめ</h2>

<p>ということで、竹洞さんに助言をもらいつつ改善ポイントや改善目標を議論してきました。最後に、どのような改善を行うのかをまとめてみます。</p>

<h3>改善目標</h3>

<p><strong>
1. Total Time（サイトにアクセスした時点からブラウザ上でコンテンツ表示が完了するまでの時間）は2秒を切る
</strong></p>

<p><strong>
2. アクセスした際のTotal Timeに関する品質を一定にする（ばらつきをなくして一定にする）
</strong></p>

<p><strong>
3. 3G回線からのTotal Timeに関するアクセス品質をブロードバンド回線のそれに近づける
</strong></p>

<h3>改善ポイント</h3>

<p><strong>
1. WordPressのキャッシュを導入する
</strong></p>

<p><strong>
2. 実際の表示サイズより大きな画像は適正なサイズに変更する
</strong></p>

<p><strong>
3. Keep Aliveが全ての環境で効いているか、設定時間は適切かを確認し、コンテンツダウンロード時間を最適化する
</strong></p>

<p><strong>
4. ソーシャルメディア系サービス（シェアボタンなど）のパフォーマンスを改善する
</strong></p>

<p><strong>
5. マークアップを改善する（書き方やJSのミニファイ等）
</strong></p>

<p>以上です。次回の記事では、実際にどのように改善したのかをご紹介し、パフォーマンスがどう改善したのかをご報告します。</p>

<p>お楽しみに！！！！</p>

<p><a href="https://html5experts.jp/yoshikawa_t/14608/" data-wpel-link="internal">HTML5 Experts.jpはなぜこんなにパフォーマンスが悪いのか…全てお見せします！ーWebパフォーマンス改善企画（改善編）</a></p>
]]></content:encoded>
			</item>
		<item>
		<title>イベント生中継！ html5j パフォーマンス部 第一回勉強会の模様をライブでお届けします</title>
		<link>/yusuke-naka/6410/</link>
		<pubDate>Thu, 08 May 2014 09:58:13 +0000</pubDate>
		<dc:creator><![CDATA[仲 裕介]]></dc:creator>
				<category><![CDATA[システム開発]]></category>
		<category><![CDATA[イベント]]></category>
		<category><![CDATA[パフォーマンス]]></category>
		<category><![CDATA[高速化]]></category>

		<guid isPermaLink="false">/?p=6410</guid>
		<description><![CDATA[連載： イベントレポート (16)この記事では、html5j パフォーマンス部 第一回勉強会の模様をライブでお届けします。勉強会に参加したくても参加できなかった方は必見です！ はじめに html5jでは部活動という形で様...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/eventarchives/" class="series-159" title="イベントレポート" data-wpel-link="internal">イベントレポート</a> (16)</div><p>この記事では、<a href="http://atnd.org/events/50159" title="atnd" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">html5j パフォーマンス部 第一回勉強会</a>の模様をライブでお届けします。勉強会に参加したくても参加できなかった方は必見です！</p>

<p><span id="more-6410"></span></p>

<h2>はじめに</h2>

<p>html5jでは部活動という形で様々な分野の勉強会が活発に行われています。今回の勉強会を主催するパフォーマンス部もその一つで、昨年暮れに構想が持ち上がり、今回第一回目の勉強会開催となりました。今回の会場はDeNAさんの会議室です。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/05/photo1.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/photo1.jpg" alt="photo1" width="576" height="324" class="size-full wp-image-6417" srcset="/wp-content/uploads/2014/05/photo1.jpg 576w, /wp-content/uploads/2014/05/photo1-300x168.jpg 300w, /wp-content/uploads/2014/05/photo1-207x116.jpg 207w" sizes="(max-width: 576px) 100vw, 576px" /></a></p>

<p>本日の勉強会はWebパフォーマンスの最前線でどのような事が行われているのか、３名のスペシャリストが余すことなくしゃべります！</p>

<h2>開会の挨拶＆5jcupの告知</h2>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8700.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8700-300x200.jpg" alt="白石さん" width="300" height="200" class="alignright size-medium wp-image-6426" srcset="/wp-content/uploads/2014/05/IMG_8700-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8700-207x138.jpg 207w, /wp-content/uploads/2014/05/IMG_8700.jpg 640w" sizes="(max-width: 300px) 100vw, 300px" /></a>
はじめに、html5j管理人の白石さんから、開会の挨拶と今絶賛開催中の<a href="https://5jcup.org/" title="5jcup" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">5jcup</a>の告知が行われました。</p>

<p>5jcupにはWebパフォーマンス部でも<a href="https://5jcup.org/awards/html5j-performance" title="html5j-performance" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">「Webパフォーマンス賞」</a>という賞を提供しています。この賞は応募されたWeb作品のパフォーマンス計測を実際に行い、パフォーマンスへの配慮を怠っていないWebサイト、Webアプリケーションに対して賞を提供するというものです。イベントの最後に、Webパフォーマンス部部長の竹洞さんから、現在は「副賞なし」となっていますが、現在、<strong>副賞を用意する方向で検討している</strong>との追加コメントが有りました。興味がある方は是非応募してみましょう！　
<a href="https://5jcup.org/" title="5jcup" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/webperformance_awards1.png" alt="webperformance_awards" width="497" height="180" class="aligncenter size-full wp-image-6634" srcset="/wp-content/uploads/2014/05/webperformance_awards1.png 497w, /wp-content/uploads/2014/05/webperformance_awards1-300x108.png 300w, /wp-content/uploads/2014/05/webperformance_awards1-207x74.png 207w" sizes="(max-width: 497px) 100vw, 497px" /></a></p>

<h2>Session 1.【総論】Webパフォーマンス事始め</h2>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8720.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8720.jpg" alt="竹洞さん２" width="300" height="200" class="alignright size-medium wp-image-6433" srcset="/wp-content/uploads/2014/05/IMG_8720.jpg 640w, /wp-content/uploads/2014/05/IMG_8720-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8720-207x138.jpg 207w" sizes="(max-width: 300px) 100vw, 300px" /></a>
html5jパフォーマンス部部長の竹洞さんのセッションです。竹洞さんは、元々は司法書士事務所で働いていて、そこからIT業界にキャリアチェンジし、VMwareやAKAMAI、Verizonを経て現在は、Keynoteという1995年に世界ではじめてパフォーマンス計測（クライアントはヤフー）を行った会社の日本代表をされています。</p>

<p>今回のセッションでは、欧米ではどのようなWebのパフォーマンス管理がなされているのか、国内企業のWebサイトのパフォーマンスの現状を紹介しつつ、Webパフォーマンスの最前線の手法や考え方について説明がありました。</p>

<h3>日本のWeb・パフォーマンスサイトの現状</h3>

<p>日本の主要なWebサイトのパフォーマンス計測結果が示されました。現在、アメリカの主要なWebサイトのトップページは読み込みが１秒きっており、それと比べれば、日本のサイトは軒並み遅いという現状が有ります。このスライドは日本のデスクトップサイトのパフォーマンス測定結果（正規分布図を箱ひげ図に変換）です。
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8736.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8736.jpg" alt="IMG_8736" width="640" height="427" class="aligncenter size-full wp-image-6450" srcset="/wp-content/uploads/2014/05/IMG_8736.jpg 640w, /wp-content/uploads/2014/05/IMG_8736-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8736-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>パフォーマンスを見る際に統計学の観点で重要なことは、複数の測定データを用いて平均値からどの程度離れているか（偏差）を算出し比較することになります。平均値を単純に比較してはいけません。偏差が離れていれば離れているほどばらつきが多い（成績が悪い）といえ、逆に偏差が短いほどサイト品質が良いといえます。この偏差を基に標準偏差を算出し、正規分布図に落とし込み、複数のデータを重ねて見やすいように箱ひげ図に変換したものが、上記画像となります。グラフ左側のひげから右側の箱まで（全体の７５％）に本来は全てのデータが収まることが望ましいのですが、右側にひげとしてそれに収まりきれていない２５％のデータが出ているのがわかります。</p>

<p>※統計学の基礎知識含めて竹洞さんが詳しく説明していますので、もっと知りたい方はYoutube動画をご覧ください。</p>

<h3>Webサイト品質管理</h3>

<p>Webサイト品質管理の為のパフォーマンス計測は定常的に観測を行うことが大切です。FirefoxやChromeの計測ツールで図るのはもちろんOKですが、一時的なデータではなく、継続して計測しなければ、「遅い」というパフォーマンスの情報は見えてきません。先述した箱ひげ図の右側２５％のデータがどういう状況で発生するのか、どのようなパターンでこのデータが変化するのかを定常的な観測データから把握し、Webサイトのパフォーマンス問題を特定していくことが重要となります。
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8742.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8742.jpg" alt="IMG_8742" width="640" height="427" class="aligncenter size-full wp-image-6459" srcset="/wp-content/uploads/2014/05/IMG_8742.jpg 640w, /wp-content/uploads/2014/05/IMG_8742-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8742-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<h3>パフォーマンス計測の手法</h3>

<p>大きく分けると以下３種類あります。日本ではServer-Side Monitoringが主流ですが、世界的にホットになっているのはReal User Monitoringとなります。しかしながら、どれか特定の方法で取得するのではなく、３種類全てを活用する必要があります。</p>

<ul>
<li>Server-Side Monitoring</li>
<li>Synthesis Monitoring</li>
<li>Real User Monitoring（RUM）</li>
</ul>

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

<p>Server-Side Monitoringで測定したサーバサイドでのパフォーマンス値、Synthesis Monitoringで測定したISPでのパフォーマンス値、Real User Monitoringで測定したエンドユーザ側でのパフォーマンス値を適切な手法で計算することで、パフォーマンス問題の原因を特定することが可能になります。どれか一つに手法を絞るのではなく、それぞれの手法の特徴を理解し組み合わせることが重要となってきます。</p>

<p>尚、パフォーマンスデータの取り方については、統計学で「実験計画法」という手法が確立しています。実験計画法を利用するにあたっては３つの原則「局所管理化」、「反復」、「無作為化」があります。
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8749.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8749.jpg" alt="IMG_8749" width="640" height="427" class="aligncenter size-full wp-image-6467" srcset="/wp-content/uploads/2014/05/IMG_8749.jpg 640w, /wp-content/uploads/2014/05/IMG_8749-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8749-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>また、「観測者効果」の問題も考慮する必要があります。Google Analyticsのコードを入れて安心してはいけません。それが測定結果にどのような影響を与えるのかを把握する必要があります。
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8750.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8750.jpg" alt="IMG_8750" width="640" height="427" class="aligncenter size-full wp-image-6468" srcset="/wp-content/uploads/2014/05/IMG_8750.jpg 640w, /wp-content/uploads/2014/05/IMG_8750-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8750-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>竹洞さんのセッションはかなりのボリュームです。詳しく知りたい方はYoutube動画をご覧いただくか、後日公開される発表資料をご覧ください。</p>

<h2>Session 2.【各論1】JavaScriptの高速化</h2>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8774.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8774.jpg" alt="IMG_8774" width="300" height="200" class="alignright size-medium wp-image-6488" srcset="/wp-content/uploads/2014/05/IMG_8774.jpg 640w, /wp-content/uploads/2014/05/IMG_8774-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8774-207x138.jpg 207w" sizes="(max-width: 300px) 100vw, 300px" /></a>
続いては株式会社ディー・エヌ・エー坊野さんのセッションです。坊野さんはもともとWebブラウザの開発を行っていたということです。</p>

<p>今回のセッションでは、Webブラウザ開発者の視点から、どのようなJavaScriptを書けばWebブラウザが高速に実行できるのかという観点で様々なテクニックの解説がありました。また、本題に入る前に、DeNAがなぜHTML5にてアプリケーション開発に取り組むのか、具体的にはどのようなことをやっているのかについても簡単に説明がありました。</p>

<h3>HTML5アプリケーション開発と最適化</h3>

<p>HTML5でのアプリケーション開発は以下の様なことが一般的に言われます。</p>

<ul>
<li>コンパイル不要</li>
<li>遅い</li>
<li>メモリ使用量が多い</li>
</ul>

<p>しかし、最近のブラウザはJavaScriptのコードも機械語にコンパイルして実行するため、Javaなどと比較してなぜ遅いのか？率直な疑問が出てきます。</p>

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

<h3>JavaScriptのコンパイラの動き</h3>

<p>まず、JavaScriptのコンパイラの動きについてについて見ていきます。ブラウザにおけるJavaScriptの実行プロセスは以下のとおり。</p>

<ol>
<li>JavaScriptコードを解析</li>
<li>中間言語に変換</li>
<li>コードブロック解析</li>
<li>機械語コードに変換</li>
<li>実行</li>
<li>実行結果を基にして最適化コードを作成し、実行</li>
</ol>

<p>最近のJavaScriptコンパイラは複数回のコンパイルを行います。（上記プロセスだと5と6が該当）なぜか？静的解析だけではJavaScriptコードの最適化は困難なので、一度最適化なしのコードを実行、プロファイラを用いて最適化の可能性などについて判定を行い、その結果を用いて最適化されたコードを生成、再コンパイルしているのです。
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8780.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8780.jpg" alt="IMG_8780" width="640" height="427" class="aligncenter size-full wp-image-6494" srcset="/wp-content/uploads/2014/05/IMG_8780.jpg 640w, /wp-content/uploads/2014/05/IMG_8780-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8780-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<h3>JavaScriptコード最適化の観点</h3>

<p>ブラウザ開発者からみたJavaScriptコード最適化の観点は、以下の通りとなります。JavaSciptコンパイラが出力する機械語コードを最適なものにするように、JavaScriptのコードを変えてあげればいいのです。また、JavaScriptコンパイラの出力のみにある余計なコードは全て最適化を阻害するものとなるため、極力排除する方がよいでしょう。
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8784.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8784.jpg" alt="IMG_8784" width="640" height="427" class="aligncenter size-full wp-image-6500" srcset="/wp-content/uploads/2014/05/IMG_8784.jpg 640w, /wp-content/uploads/2014/05/IMG_8784-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8784-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>次に、具体的にどのようなものが最適化を阻害するオーバーヘッドになるかを見ていきます。</p>

<p>JavaScript APIのオーバーヘッド、例えば<strong>Date.now()</strong>・・・
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8786.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8786.jpg" alt="IMG_8786" width="640" height="427" class="aligncenter size-full wp-image-6502" srcset="/wp-content/uploads/2014/05/IMG_8786.jpg 640w, /wp-content/uploads/2014/05/IMG_8786-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8786-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>HTML5 APIのオーバヘッド、例えば<strong>document.createElement(&#8216;canvas&#8217;)</strong>・・・
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8788.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8788.jpg" alt="IMG_8788" width="640" height="427" class="aligncenter size-full wp-image-6504" srcset="/wp-content/uploads/2014/05/IMG_8788.jpg 640w, /wp-content/uploads/2014/05/IMG_8788-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8788-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>これらの処理は複数の工程処理を行う必要があり、実行するにあたってはオーバヘッドになってしまいます。</p>

<h3>JavaScript関数の最適化</h3>

<p>最適化にあたっては、先ほどの観点にならってまず、同一のコードをJavaScript関数とC++関数で実行し速度を比較してみます。今回の例では、前者は183us〜828us（ブラウザにより差分有り）、後者は0.6usという実行結果の差ができました。次に、相違点を列挙し、コードを最適化するというプロセスを実施します。</p>

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

<h3>Web開発者が最適化の美味しいとこどりをするには？</h3>

<p>これまで説明してきたようなことをブラウザ開発者はやっていますが、Web開発者の皆さんは美味しいところだけうまく取り入れて下さい。
具体的に、最適化のやり方として「関数のインライン化」や「変数名の短縮」などはツールを活用すればできるため、オススメしません。おすすめの手法は以下の通りです。</p>

<ul>
<li>ソーシャルネットワークを活用して有識者に聞く（そのためにはわかりやすいコードを書こう）</li>
<li>JavaやC++と比較しやすいコードを書く</li>
<li>API Proxyを使う</li>
<li>Assertionを用いて型チェックを行う</li>
</ul>

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

<p>最後に、大事なことは「コンパイラの気持ちになってコードを書く！」ということ。</p>

<h2>Session 3.【各論2】ブラウザにやさしいHTML/CSS</h2>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8804.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8804.jpg" alt="IMG_8804" width="300" height="200" class="alignright size-medium wp-image-6529" srcset="/wp-content/uploads/2014/05/IMG_8804.jpg 640w, /wp-content/uploads/2014/05/IMG_8804-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8804-207x138.jpg 207w" sizes="(max-width: 300px) 100vw, 300px" /></a>
最後は、株式会社レイハウオリ 猪狩さんのセッションです。猪狩さんはWebサイトの開発、高速化、HTMLの構造化などをかなり突き詰めてやっていて、雑誌執筆などもされています。</p>

<p>Webの高速化を行うためにはブラウザの仕組みを理解する必要があります。下のサイトをみればだいたい把握できるそうですが、内容はかなり難しいということ。そのため今回は、高速化に繋がる部分を簡単に紹介するとともに、沢山のデモを交えた体感型のセッションとなりました。</p>

<p><a href="http://www.html5rocks.com/ja/tutorials/internals/howbrowserswork/" title="HTML5 Rocks" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">http://www.html5rocks.com/ja/tutorials/internals/howbrowserswork/</a></p>

<h3>ブラウザにモテるHTML/CSSとは</h3>

<p>よく言われるWeb高速化の３原則に、「少なくする（数）」、「軽くする（量）」、「近くする（距離）」があります。
具体的には、以下のようになります。</p>

<p>少なくする（数）</p>

<ul>
<li>CSSスプライト</li>
<li>ファイル結合</li>
</ul>

<p>軽くする（量）</p>

<ul>
<li>縮小化</li>
<li>テキスト圧縮</li>
<li>キャッシュ利用</li>
</ul>

<p>近くする（距離）</p>

<ul>
<li>CDNを利用する</li>
</ul>

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

<p>これら基本的なテクニックについて、もっと詳しい理解を得て応用力をつけ、有用に活用できるようにする必要があります。</p>

<h3>Webページが表示されるまでを知ろう</h3>

<p>Webページを表示するまでの大まかな流れは以下のとおりです。</p>

<ol>
<li>HTTPリクエスト① &#8211; HTMLのみをリクエストする</li>
<li>DNSで名前解決 &#8211; ドメインからIPアドレスを調べる</li>
<li>TCP接続 &#8211; サーバに接続を行う</li>
<li>HTTPリクエスト② &#8211; HTMLのパース結果に基づき各リソースをリクエストする</li>
</ol>

<p>※ これが繰り返されます</p>

<p>HTTPリクエスト②では、HTMLの中身をパースして個別のリソースをサイトの上位から順に取得していきます。
ダウンロードは並列で逐次的に行われます。最大並列数はブラウザによって異なります。
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8828.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8828.jpg" alt="IMG_8828" width="640" height="427" class="aligncenter size-full wp-image-6553" srcset="/wp-content/uploads/2014/05/IMG_8828.jpg 640w, /wp-content/uploads/2014/05/IMG_8828-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8828-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>１ホストあたりの各ブラウザの同時接続数
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8829.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8829.jpg" alt="IMG_8829" width="640" height="427" class="aligncenter size-full wp-image-6554" srcset="/wp-content/uploads/2014/05/IMG_8829.jpg 640w, /wp-content/uploads/2014/05/IMG_8829-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8829-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>IE6〜IE7は同時に２本なので他のブライザに比べかなり時間がかかります。</p>

<p>HTMLが読み込まれた後、表示されるまでのプロセスは以下のとおりです。HTMLのパース結果からDOM treeが作られて、それからRender treeが作られます。最後はそれを画面に描画します。
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8831.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8831.jpg" alt="IMG_8831" width="640" height="427" class="aligncenter size-full wp-image-6556" srcset="/wp-content/uploads/2014/05/IMG_8831.jpg 640w, /wp-content/uploads/2014/05/IMG_8831-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8831-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>レンダリングプロセスの中でも、特定のCSSを利用するとLender Layerが生成され、その中でも特にGraphic Layerの動きに注目します。
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8834.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8834.jpg" alt="IMG_8834" width="640" height="427" class="aligncenter size-full wp-image-6561" srcset="/wp-content/uploads/2014/05/IMG_8834.jpg 640w, /wp-content/uploads/2014/05/IMG_8834-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8834-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>CSSセレクタマッチングについても取り上げます。
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8836.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8836.jpg" alt="IMG_8836" width="640" height="427" class="aligncenter size-full wp-image-6564" srcset="/wp-content/uploads/2014/05/IMG_8836.jpg 640w, /wp-content/uploads/2014/05/IMG_8836-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8836-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>JavaScriptの実行については以下のとおりです。
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8838.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8838.jpg" alt="IMG_8838" width="640" height="427" class="aligncenter size-full wp-image-6568" srcset="/wp-content/uploads/2014/05/IMG_8838.jpg 640w, /wp-content/uploads/2014/05/IMG_8838-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8838-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<h3>ブラウザとユーザの気持ちになる</h3>

<p>ブラウザの視点に立ってみると、レンダリングプロセスを実行する上で重要となる点は以下の通りです。</p>

<ul>
<li>見た目から表示したい ->  順序の最適化</li>
<li>時間がかること大変なことは、できるだけ避けたい -> リクエスト、サイズ、消費メモリの最小化</li>
<li>いろんなこと一変にしたくない -> 消費メモリの分散化</li>
<li>他のブラウザいなくなれ（こっそりｗ）</li>
</ul>

<p>ユーザーの気持ちはどうでしょうか？</p>

<ul>
<li>早くコンテンツを見たい -> 順序の最適化</li>
<li>待ちたくない -> リクエスト、サイズ、消費メモリの最小化</li>
<li>スムーズであって欲しい -> 消費メモリの分散化</li>
</ul>

<p>それぞれに共通な「順序の最適化」、「リクエスト、サイズ、消費メモリの最小化」、「消費メモリの分散化」の観点で、それぞれの手法（アプローチ）をライブデモで紹介します。これは、低スペックな端末で見るとより効果がわかりやすいと思います。</p>

<h3>デモで分かるブラウザにやさしいHTML/CSS</h3>

<p>ライブデモはこちらのサイトにまとまっています。</p>

<p><a href="http://goo.gl/zA4ZvQ" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">http://goo.gl/zA4ZvQ</a></p>

<p>ID : tech , PASS : tech-lab</p>

<h4>DNSプリフェッチ</h4>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8843.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8843.jpg" alt="IMG_8843" width="640" height="427" class="aligncenter size-full wp-image-6575" srcset="/wp-content/uploads/2014/05/IMG_8843.jpg 640w, /wp-content/uploads/2014/05/IMG_8843-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8843-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a>
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8849.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8849.jpg" alt="IMG_8849" width="640" height="427" class="aligncenter size-full wp-image-6583" srcset="/wp-content/uploads/2014/05/IMG_8849.jpg 640w, /wp-content/uploads/2014/05/IMG_8849-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8849-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<h4>リソース読み込み順序</h4>

<p>OKパターン
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8850.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8850.jpg" alt="IMG_8850" width="640" height="427" class="aligncenter size-full wp-image-6586" srcset="/wp-content/uploads/2014/05/IMG_8850.jpg 640w, /wp-content/uploads/2014/05/IMG_8850-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8850-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>NGパターン
<a href="https://html5experts.jp/wp-content/uploads/2014/05/IMG_8851.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/05/IMG_8851.jpg" alt="IMG_8851" width="640" height="427" class="aligncenter size-full wp-image-6587" srcset="/wp-content/uploads/2014/05/IMG_8851.jpg 640w, /wp-content/uploads/2014/05/IMG_8851-300x200.jpg 300w, /wp-content/uploads/2014/05/IMG_8851-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<h4>JSアニメーションとCSSアニメーションの違い</h4>

<p>原則として、JSアニメーションよりCSSアニメーションの方が高速なので、CSSアニメーションを利用するようにしましょう。
特にモバイルでは重要になってきます。
また、モバイルでのCSSアニメーションにおいては、アニメーションする要素はposition absoluteにしなければパフォーマンスで問題が出てきます。</p>

<p>※ライブデモの詳細はYoutube動画をご覧ください。</p>

<h3>イマドキのHTML/CSS高速化って？</h3>

<p>最後に、イマドキのHTML/CSS高速化ってどうなってるの？とよく聞かれるため、昔と変わってきたことに着目して幾つか取り上げます。</p>

<h4>CSSスプライトはしない</h4>

<p>メンテナンスコストの方がパフォーマンスにおけるメリットを上回るため仕様はおすすめしません。特にモバイルでは、回線の品質がまちまちまので、スプライトして画像をまとめるとそこがボトルネックになることもあるため、例えば、１ページの画像数が１０個いかであれば、分割しておいたほうがメリットが大きいのではないでしょうか。</p>

<p>＊比較デモがあるため興味がある方はYoutube動画をご覧ください。</p>

<h4>CSSセレクタのパフォーマンスは気にしない？</h4>

<p>最近はブラウザのCSS実行エンジンが早いので気にしません。よく使います。</p>

<h4>可能な限りベクターでコーディング</h4>

<p>デザインはCSSで極力再現しましょう。CSSでできない場合はSVG、それが難しいようであればPNGでやりましょう。Webフォントも良いアプローチです。</p>

<h4>PCのみ、モバイルのみ、レスポンシブの区分けが大事</h4>

<p>それぞれのターゲットによって設計方針は変えていくべきです。</p>

<h4>パフォーマンス &lt; メンテナンス</h4>

<p>メンテナンス性を犠牲にしてパフォーマンスを追求するのはよくありません。</p>

<h2>Webパフォーマンス部の今後の予定</h2>

<p>Webパフォーマンス部では、第２回から第１１回まで予定がすでに決まっています。</p>

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

<p>日本企業が世界に進出するためにはWebサイトのパフォーマンスは大事です！
今回の勉強会に参加できなかった方は、是非次回以降の勉強会に参加してみては如何でしょうか？</p>

<h2>勉強会の動画配信はこちら</h2>


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


<p>＊この勉強会は一見の価値有りです。参加できなかった方は是非一度全編通して見てみることをオススメします。</p>

<h2>ライブライティングについて</h2>

<p>この記事は、イベント開催中にライブライティングしたもので、改訂履歴は以下の通りとなります。</p>

<ul>
<li>2014/5/9 18:40 &#8211; 最終版記事に更新完了</li>
<li>2014/5/8 22:00 &#8211; イベント終了（この時点では記事は書きかけ）</li>
<li>2014/5/8 19:00 &#8211; 記事公開</li>
</ul>

<p>パフォーマンス部ロゴデザイン：Kaori Nishino (@kanishionori)</p>
]]></content:encoded>
		
		<series:name><![CDATA[イベントレポート]]></series:name>
	</item>
		<item>
		<title>モバイル対応Webアプリケーションのキャッシュ戦略</title>
		<link>/kyo_ago/2466/</link>
		<pubDate>Tue, 24 Sep 2013 00:00:40 +0000</pubDate>
		<dc:creator><![CDATA[吾郷 協]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Application Cache]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Webアプリケーション]]></category>
		<category><![CDATA[オフラインファースト]]></category>
		<category><![CDATA[高速化]]></category>

		<guid isPermaLink="false">/?p=2466</guid>
		<description><![CDATA[近年、モバイルブラウザ上でアプリケーションを作るにあたり、JavaScriptでも不安定な回線上で動作する設計が求められるようになってきました。 ここでは、「オフラインファースト」をはじめとする、モバイルなどの回線が不安...]]></description>
				<content:encoded><![CDATA[<p><a href="https://html5experts.jp/wp-content/uploads/2013/09/dtl_thm_017.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2013/09/dtl_thm_017.png" alt="dtl_thm_017" width="207" height="156" class="alignright size-full wp-image-2593" /></a>
近年、モバイルブラウザ上でアプリケーションを作るにあたり、JavaScriptでも不安定な回線上で動作する設計が求められるようになってきました。</p>

<p>ここでは、「オフラインファースト」をはじめとする、モバイルなどの回線が不安定な状況を想定したWebアプリケーション設計に関して、キャッシュ方法やよく使われるAPIなどを紹介したいと思います。</p>

<p><span id="more-2466"></span></p>

<p>「オフラインファースト」とは2012年ごろから提唱されていた、「回線がオフラインになることを前提にアプリケーションの設計を行う思想」のことで、オフライン前提に設計することにより回線状況によらないサービス提供や、効率的な通信をベースにした高速な動作を目指すものです。</p>

<p>それではここからはキャッシュ方法とそれぞれ向いているコンテンツの紹介を行います。</p>

<h1>読み込みデータのキャッシュ</h1>

<p>ApplicationCacheやlocalStorage、オンメモリキャッシュなどを使って、「サーバから取得したデータをローカルに保持する」ものです。</p>

<p>これは一般に「クライアントサイドキャッシュ」と呼ばれるもので、ネットワークがオンラインの時に読み込んだデータをオフライン時に使用します。</p>

<p>サーバと連動しないコンテンツに向いており、実際のコンテンツ以外でもテンプレートファイルなどの「動的なコンテンツの静的な部分」にも使用されます。</p>

<h1>読み込みデータのマージ</h1>

<p>これは「読み込みデータのキャッシュ」と大きくは変わりませんが、「読み込みデータのキャッシュ」がオンラインになった際に毎回キャッシュを読みなおすのに比べて、「読み込みデータのマージ」はオンラインになった際にサーバ上で更新があった内容のみダウンロードを行います。</p>

<p>更新があった内容のみダウンロードを行うため、帯域の使用量が少なくなる利点がありますが、サーバとクライアントでデータの更新タイミングを管理する必要があるため、「読み込みキャッシュ」に比べて実装が複雑になります。</p>

<p>「多数の画像ファイルの内、更新があったもののみを再取得する」など、やりとりするデータ量が多いコンテンツに使用されます。</p>

<h1>書き込みデータのキャッシュ</h1>

<p>書き込み時に回線状況を確認して、オフラインの場合オンラインになるまでデータの送信を遅延させる方法です。</p>

<p>また、オフラインだった時だけではなく、サーバへの通信に失敗した場合、常にデータを再送する形で実装されることもあります。</p>

<p>実装方法としては独自に定義した通信用のコードを使用するほかに、XMLHttpRequestを乗っ取る方法や、使用しているライブラリ（jQuery）などのajaxメソッドをラッピングする方法などがあります。</p>

<p>「投稿」や「保存」などのサーバへの更新処理に使われますが、ゲーム等のタイミングが重要な通信や、「購入」等のサーバ側との連動が、重要な通信では使用されません。</p>

<h1>書き込みデータのマージ</h1>

<p>これは「読み込みデータのマージ」に書き込みが行われることを想定されたものですが、「書き込みの時系列を保持するか」、「同じデータを同時に編集していた場合にどう整合性を保つか」等によって実装難易度は大きく変わります。<br />
（時系列を保持せず、同時編集時は常に最後の修正が反映されれば良い場合、書き込みデータのキャッシュ実装と大きな差はありません）</p>

<p>これに関してはサーバ側の実装も大きく関わってくるためクライアント側だけで設計するのは難しいですが、もしクライアント側だけで実装したい場合には<a href="https://developers.google.com/drive/realtime/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google Drive Realtime API</a>などの外部サービスの使用も検討してみてください。</p>

<h1>オフライン動作</h1>

<p>これは単純なデータのキャッシュではなく「ブラウザがオフラインの状態でも動作させる」方法になります。</p>

<p>現状、ブラウザ上でオフライン時にコンテンツを提供するには、基本的にApplicationCacheを使用します。</p>

<p>サーバ側の処理が重要な場合オフライン動作の必要性は高くありませんが、クライアントサイドで完結する要素が多いモバイル向けのツールやアプリケーションなどでは必要性が高くなります。</p>

<p>ここからは実際にキャッシュを実装する際によく使用される機能について紹介します。</p>

<h2>Web Storage（localStorage、sessionStorage）</h2>

<p>IE8以降の主要なブラウザで使用できる同期型の保存領域です。</p>

<p>多くのブラウザは5MB程度のデータを保持することが可能です。</p>

<p>実装も容易なためよく使われますが、同期型で実装されているためパフォーマンス的な問題も指摘されています。</p>

<p><a href="https://dev.mozilla.jp/2012/03/there-is-no-simple-solution-for-local-storage/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ローカルストレージに簡単な解決策はない | Mozilla Developer Street (modest)</a>では具体的な問題点や代替案が書かれています。</p>

<h2>Cookie</h2>

<p>古くから実装されており、サポートブラウザも広いことから、長い間クライアントキャッシュの保存領域としても使用されてきました。</p>

<p>ただ、Cookieに保存した内容はサーバへも送信されてしまうことから、Cookieをキャッシュとして使用する場合、以後の通信すべてで不要なデータをサーバに送ることになるため、大きなデータをキャッシュすることには向いていません。</p>

<h2>location.hash</h2>

<p>URLの # 以降に文字列を設定し、クライアントキャッシュとして使用する方法です。</p>

<p>サーバサイドへも送信されず、古いブラウザでも動作可能ですが、「ブラウザの履歴に残る」、「URLを共有した際にキャッシュも共有される」、「ブックマーク等にキャッシュも保存される」、「#を使った画面遷移時にキャッシュが破棄される」といった問題があるため、キャッシュとして使用する場合は注意が必要です。</p>

<h2>ブラウザキャッシュ</h2>

<p>JavaScriptから直接操作するAPIは提供されていませんが、ブラウザキャッシュもクライアントサイドでは重要なキャッシュになります。</p>

<p>具体的には「非表示のimg要素を作成し、img.srcへ画像のURLを設定して先読みさせる」、「見えないiframeで次に読み込むページを先読みする」といった方法で使用されます。</p>

<h2>Web SQL Database</h2>

<p>ブラウザ内に内蔵されたSQLiteに対して、JavaScriptからAPI経由でSQLを発行することでデータの保存、取得を行うのが<a href="http://www.w3.org/TR/webdatabase/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web SQL Database API</a>です。</p>

<p>もともとWebKit系のブラウザで実装されており、W3Cでも標準仕様として提案されていましたが、SQLiteへの依存などの問題によりW3C上では廃案になりました。<br />
（<a href="http://javascript.g.hatena.ne.jp/edvakf/20091102/1257139731" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ブラウザ上のデータベースに関して &#8211; JavaScriptで遊ぶよ &#8211; g:javascript</a>では廃案になった経緯等がまとめられています）</p>

<p>ただ、<a href="http://caniuse.com/sql-storage" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">モバイル環境では使える環境が多い</a>ため、モバイル環境に限ったウェブアプリケーションなどでは使用されることもあります。</p>

<h2>Indexed Database（Indexed DB）</h2>

<p>標準仕様としての策定が中止されたWeb SQL Databaseに代わり登場したクライアントサイドDBです。</p>

<p>Web SQL DatabaseがあくまでもSQLiteの仕様に準拠しているのに比べて、Indexed DatabaseはJavaScriptからの使用に特化しておりシンプルなObjectやFile objectなどをそのまま格納できます。</p>

<p>Chrome、Firefox、IE10でサポートされるなど、<a href="http://caniuse.com/indexeddb" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">デスクトップブラウザではサポートが広まっています</a>が、Mobile Safari、Android標準ブラウザでのサポートが行われていないためモバイル環境での使用は広まっていません。</p>

<h2>Filesystem API</h2>

<p>ブラウザ上にディレクトリなどのFilesystemを操作するAPIを提供するのが、Filesystem APIです。</p>

<p>DOMFileSystem  objectやDirectoryEntry objectなどを使って、File objectを階層構造で管理することができます。</p>

<p>このAPIはinput[type=&#8221;file&#8221;]やD&amp;Dで渡されたファイルを処理する際に使用する「File API」とは違うAPIであることに注意してください。<br />
（Filesystem APIでも単一のファイルを操作する際はFile APIで提供される機能を使用しますが、File APIはあくまでもFilesystem APIから独立した仕様です）</p>

<p>主にChromeで実装されていますが、<a href="http://caniuse.com/filesystem" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Chrome以外のブラウザでは実装が進んでいない</a>ため、一般的なウェブ環境ではあまり使用されていません。</p>

<p><a href="https://dev.mozilla.jp/2012/07/why-no-filesystem-api-in-firefox/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Firefox に FileSystem API が無いのはなぜか？ | Mozilla Developer Street (modest)</a>ではMozillaのFileSystem APIに対するスタンスが書かれています。</p>

<h2>ApplicationCache</h2>

<p>ApplicationCacheはcache manifestと呼ばれるキャッシュ対象のURLを記述したテキストファイルをhtmlから参照することで、記述されているURLの内容をローカルキャッシュとして使用する仕様です。</p>

<p>ApplicationCacheには以下の様な機能が含まれます。</p>

<ul>
<li>ブラウザがオフラインでも、事前にキャッシュした内容を表示する</li>
<li>ネットワーク通信なしに、cache manifestに書かれたURLのファイルにアクセスする</li>
<li>ブラウザがオフライン時のみ、代替内容を表示する</li>
<li>JavaScriptからキャッシュの取得、更新イベントを受け取る</li>
</ul>

<p>現在、ブラウザがオフライン時でもコンテンツを提供する場合ApplicationCacheが主に使用されますが、ApplicationCacheは「設計に失敗したAPI」と呼ばれるほど使い勝手が悪く、さまざまな問題を抱えています。</p>

<h1>ApplicationCacheの問題点</h1>

<p>ApplicationCacheに関しての紹介で「さまざまな問題を抱えています」と書きましたが、ここではそのうちの主なものについていくつか紹介したいと思います。</p>

<h2>読み込み元htmlがキャッシュされる</h2>

<p>ApplicationCacheを使用する場合、仕様上ApplicationCacheを使用しているhtmlもキャッシュされてしまうため、動的なコンテンツを出力してもすぐに反映されません。</p>

<p>そのため、ApplicationCacheを使用する場合は基本的に1枚の静的なhtmlを用意し、動的な部分はすべてJavaScriptを使用して構築することになります。</p>

<p>これはWebサイト構築の当初から想定している場合は問題ありませんが、サーバサイドで動的にコンテンツを生成している既存のWebサイトに対して、あとからApplicationCacheを導入する場合には大きな障害になります。</p>

<h2>キャッシュのクリアが困難</h2>

<p>ブラウザによってはApplicationCacheをクリアするUIを提供していないものもあり、開発中も含めて一度キャッシュされたApplicationCacheをクリアするのが困難な場合があります。</p>

<p>特にiOSの場合、アプリが独自に使用しているUIWebViewのApplicationCacheをクリアするには、アプリを削除して入れなおす以外の方法がありません。<br />
（アプリが独自のUIを提供している場合を除く）</p>

<h2>JavaScriptからキャッシュを操作することができない</h2>

<p>JavaScriptからApplicationCacheに関しては「キャッシュ状態の確認」、「サーバ上のデータ確認」、「キャッシュの破棄」を行うことができます。</p>

<p>ただし、キャッシュ操作は全キャッシュに対しての操作のみで、個別のファイルに対しての操作は提供されていません。</p>

<p>そのため、「高速化のために出来るだけキャッシュするファイルを多くしたいが、キャッシュするファイルが多いとキャッシュの更新に時間がかかる」という状況になります。</p>

<p>キャッシュの更新は自動的に行われるため基本的にブラウザ側で操作を行う必要はありませんが、逆に「一部のキャッシュのみ更新したい」、「更新順に優先度を付けたい」、「指定したキャッシュが更新されたらJavaScriptからアクセスしたい」と言った内容は実現できません。</p>

<h1>それでも使われるApplicationCache</h1>

<p>問題点の多いApplicationCacheですが、現状ブラウザがオフライン時にコンテンツを提供するためにはもっとも現実的な方法であるため、問題点があることを前提で使用されている状況です。</p>

<p>もしApplicationCacheを導入する場合、以下の点に注意してください。</p>

<h2>最初に導入するか決断する</h2>

<p>ApplicationCacheは仕様的にシングルページアプリケーション（1枚のhtmlをベースにJavaScriptでコンテンツを構築する形式）を想定しており、サーバサイドで毎回htmlを組み立てて出力する形式は想定されていません。</p>

<p>サーバサイドで毎回htmlを組み立てて出力するコンテンツの場合でもiframeを経由するなどして活用することは可能です。しかし、iframe内のApplicationCacheに対する状態管理とiframeと、本体間のキャッシュデータをやりとりするコードが必要になるため、実装は複雑になります。</p>

<h2>最悪の事態を想定する</h2>

<p>ApplicationCacheは使い方によっては完全にサーバから独立して動く事が可能ですが、場合によってはサーバからの変更を一切受け付けなくなってしまう状態に陥る場合があります。</p>

<p>もしサイト上でApplicationCacheを使用する場合、常にネットワーク上からダウンロードするJavaScriptを読み込ませておき、最悪の場合でもJavaScriptからリダイレクトの指示を出せるようにしておくことをおすすめします。</p>

<hr />

<p>ここまでキャッシュの設計やAPIに関して紹介してきましたが、ユーザから見た場合キャッシュとは「最良の通信やパフォーマンスが提供されない場合の代替手段」であり、本来存在しないことが求められる技術でもあります。</p>

<p>そのため、もしキャッシュを使用する場合、「ユーザの意図に反した動作にならないか」、「最良の状態でないことをユーザが理解できるか」といったことを意識して使用してください。</p>
]]></content:encoded>
			</item>
		<item>
		<title>モバイルブラウザでもサクサクに動作する最適化6つのノウハウ</title>
		<link>/sou/2413/</link>
		<pubDate>Thu, 19 Sep 2013 22:00:56 +0000</pubDate>
		<dc:creator><![CDATA[城戸 総史]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[パフォーマンス]]></category>
		<category><![CDATA[モバイル]]></category>
		<category><![CDATA[高速化]]></category>

		<guid isPermaLink="false">/?p=2413</guid>
		<description><![CDATA[連載： パフォーマンスチューニング (6)「Webサイト・アプリ高速化テクニック徹底解説」第8回は、モバイルブラウザに向けた最適化について紹介します。 モバイル端末はPCに比べ、CPUやネットワークなどの性能面で劣ること...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/performance-tech/" class="series-149" title="パフォーマンスチューニング" data-wpel-link="internal">パフォーマンスチューニング</a> (6)</div><p>「Webサイト・アプリ高速化テクニック徹底解説」第8回は、モバイルブラウザに向けた最適化について紹介します。
モバイル端末はPCに比べ、CPUやネットワークなどの性能面で劣ることからボトルネックの影響が出やすく、またゲーム開発など突き詰めたチューニングを行う場面では、特殊なノウハウも必要になります。</p>

<p>しかしきちんと最適化を行えば、その効果もその分著しく、比較的低スペックな端末や3G回線であっても、サクサク軽量なサービス提供が可能です。今回の記事では、その勘所をお伝えしたいと思います。
</p>

<p><span id="more-2413"></span></p>

<h2 id="">1. ボトルネックを取り除く</h2>

<p><a href="https://html5experts.jp/wp-content/uploads/2013/09/html5experts_image_Mobile.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2013/09/html5experts_image_Mobile.png" alt="html5experts_image_Mobile" width="207" height="156" class="alignright size-full wp-image-2451" /></a></p>

<p>
まずはやってしまいがちなボトルネックの事例について、挙げていきたいと思います。前述のようにモバイル端末では、その性能からPCよりも顕著に、未最適化箇所が体感に影響を及ぼします。</p>

<p>
仕事がらそこそこの数のアプリケーションを見てきましたが、モバイル向けに特化したチューニングができていないのではなく、一般に求められる最適化がなされておらず、それがボトルネックとなって遅いといった事例をよく目にします。</p>

<p>
以下では、特にモバイルで問題となる一般的な最適化項目を挙げてみました。個々の詳細な解説については、本連載シリーズの中でより詳細にレポートしていきます。ぜひ、目を通してみてください。</p>

<p>よくありがちな例としては、</p>

<ul>
<li>JavaScriptファイルの取り扱いが最適化されておらず、不要なブロッキングが発生している</li>
<li>適切なレスポンスヘッダが設定されておらず、ブラウザキャッシュが機能していない（もしくはConditional GETのリクエストを飛ばしている）</li>
<li>過剰な数のHTTPリクエストが発生している</li>
</ul>

<p>といったものがあります。</p>

<h3 id="javascript">JavaScriptファイルの取り扱いに注意する</h3>

<p>まず影響が大きいのは、JavaScriptファイルの取り扱いです。<br>
script要素はブラウザの他の処理をブロックします。HTML文中にscript要素があると、ブラウザはパース処理など他の仕事を停止し、script要素の評価を優先して実行します。<br>
普段は様々な仕事が並列で走っているのですが、script要素だけは特別扱いで、これはブラウザにとって最も重い仕事のひとつとなります。もちろん、モバイル端末においても顕著に影響を与えます。</p>

<p>script要素の数を減らすか、非同期化しましょう。<br>
defer、async属性を用いることで、上記のブロッキングがなくなります。<br>
非同期化を行わない（行えない）場合はブロッキングの影響を最小限に抑えるよう配慮します。<br>
具体的にはファイル結合を行い、script要素の数を減らし、またbody要素の最下部に置くなど、ブラウザの処理をできるだけ阻害しないようにします</p>

<h3 id="">ブラウザキャッシュを有効に機能させる</h3>

<p>また、ブラウザキャッシュも重要です。<br>
画像、CSSファイルなどの全アセットがキャッシュに入り、DOMContentLoadedまでにHTTPリクエストが全く発生しない状況では体感速度が大幅に向上します。サクッとファーストビューが表示されるなど、明らかに体感が変わります。
「HTTPリクエストが全く発生しない」ことが重要です。Conditional GET（304）を見かけた場合もきっちり摘み取りましょう。
</p>

<p>
またサーバ側で画像合成を行うなど、動的なアセットを持つ場合にレスポンスヘッダの付け忘れが起こりやすいようです。
こういった動的なアセットはファーストビューに含まれることも多く、キャッシュの可否で体感速度が変わってきます。
反対に毎回動的に生成するようなものは、もしファーストビューなど重要な箇所に含まれないようなものは遅延ロードに回してやるのもよいでしょう。
</p>

<p>
例: cache validator（この場合はLast-Modified）が設定されているので正しくキャッシュされる。<br>
<img src="/wp-content/uploads/2013/09/header_cacheable.png" alt="キャッシュ可能" />
</p>

<p>
例: cache validator に相当するヘッダがなく、キャッシュ不可として扱われる。<br>
<img src="/wp-content/uploads/2013/09/header_uncacheable.png" alt="キャッシュ不可" />
</p>

<h3 id="">HTTPのリクエスト数を削減する</h3>

<p>モバイル端末では、PCよりも顕著にHTTPのリクエスト数が性能面に現れます。</p>

<p>理想はファーストビューの表示までに20本未満程度だと思います。<br>30本以上のリクエスト数を見ると、多いなと感じます。これらにはリクエスト本数を削減するにはスプライトシートを使う、base64 encodeで文字列化して埋め込む、遅延ロードを行う等々、その時々に応じた方法があります。
</p>

<p>上記に挙げたボトルネックはどれもGoogle Page Speed等のツールを用いたチェックが可能です。<br>
特殊なノウハウではなく、検出もしやすく改善もしやすいので、ぜひ活用＆対応してみましょう。
</p>

<h2 id="">2. チューニングの為の知識と準備</h2>

<h3 id="">大まかな流れを掴む</h3>

<p>JavaScriptヘビーなアプリケーションなど通常の最適化だけでは十分に軽量化できないものがあります。<br>
そのような場合は、より突っ込んだ測定と最適化のチューニング作業が必要です。</p>

<p>モバイルでのチューニング作業は、ざっくり例えると買い物に近い感覚です。<br>
まずコンテンツの表示にかけてよい時間、つまり予算を定め、DOMContentLoadedまでの所要時間やJavaScriptの処理時間といったパートごとのコスト計測を行い、予算内にそれらが収まるよう、値切ったり（高速化）、予算外に回したり（遅延評価）といったやりくりを行う、といったノリです。
</p>

<p>まず予算を決めます。<br>
予算を決めるには、そのコンテンツやアプリケーションがユーザの目から見て使えるようになったと思えるポイント、待ち時間が終わったと感覚的に思えるポイントを定めます。<br>
これはコンテンツによって様々です。ファーストビューが表示されるまでの場合もあれば、メインアプリケーション部分をユーザが操作可能になるまでの場合、アニメーションが再生を開始するまでの場合など、そのアプリケーションの特性によって決まります。<br>
ここまでに要する時間をもって、予算として定めます。
</p>

<p>
経験則的には、アセットがブラウザキャッシュに収まった状態で、この感覚的待ち時間が大体800ms以下に収まるとサクサクである、読み込みが軽量であると利用者にも感じてもらえることが多いようです。<br>
大体の予算感の参考にしてください。
</p>

<p>
さて、次に計測を行うのですが、
計測にあたってはターゲット環境の選定が重要になります。<br>
これは端末、OS、ブラウザによって実効性能や動作特徴が変わるので、結果として高速化のために解決するべき問題が環境にひも付いて変わるためです。<br>
ここでは端末、OS、ブラウザ、回線種別の組み合わせを指して「環境」と呼んでいます。特に端末とブラウザの違いについて、下記で見ていきましょう。
</p>

<h3 id="">ターゲット端末を定める</h3>

<p>
モバイルで発生する大半の問題は実はCPUやGPU、もしくはネットワーク性能の向上で簡単に解決できてしまいます。
</p>

<p>
端末性能は日々向上を見せており、今日の課題は明日の課題となり得ないことがあります。<br>
端末の買い換えサイクルは2年程度とよく言われますが、実際にベンチマークを取ると2年前の端末と現在の端末では5～8倍近い性能差が発生します（さらに極端な例もあります）。<br>
本当に解決すべき問題を見定めるためには、その時の状況に即したターゲット端末の選定が重要になります。
</p>

<p>
本原稿の執筆時点は、低スペック端末が世間から消えるか消えないかのちょうど過渡期です。<br>
シェアを広げつつある性能の良い端末に向けて体験も豊かに補強しつつ、多少年数の経った低スペック端末でも円滑にサービスが動作するような、両方取りのチューニングが求められている時期だと思います。</p>

<p>
今回は低スペック端末向けのチューニングも視野に入れましょう。<br>
低スペック端末の代表格としては、例えばiPhone 4があります。iPhone 4はディスプレイサイズに比べてCPU/GPUの性能が十分と言えない、問題を見つけやすいチューニング向きの端末です。<br>
iPhone 4は発売から年数も経過していますが、iOS7がカバーしていることもあり、まだサポートが必要だと思います。<br>
また比較的新しい端末であっても、例えばGalaxy S3など一昨年に発売されたものでも、CPU/GPUの負荷軽減処理が効果的にはたらく低スペック端末に近い挙動のものがあります。<br>
やはりまだ、高速化には端末性能を考慮した作り込みが必要となる、低スペック端末への配慮が必要な時期だと言えるでしょう。
</p>

<h3 id="">ブラウザ間の差異について</h3>

<p>モバイルブラウザは様々な種類が存在しますが、ここではシェアの高いMobile SafariとAndroid Browser、Chrome for Androidといったブラウザに絞って話を進めます。</p>

<p>
Mobile SafariとAndroid BrowserはOSのバージョンによっても挙動に違いがあるため、選定時には気をつけてください。
</p>

<p>
まずブラウザキャッシュの取り扱いは各ブラウザで異なり、体感や最適化に影響を与えます。
</p>

<p>
Mobile Safariはオンメモリのキャッシュしか持たず、このためOSの都合で頻繁なキャッシュアウトが発生しやすく、また本体やブラウザの再起動など、プロセスの寿命に伴ってキャッシュが破棄されます。
</p>

<p>
キャッシュ領域のサイズ自体は100MB前後だと言われていますが、状況によってブレがあり、確定した値を持っていません。<br>
ひとつのサイトを訪れ継続して操作を行う場合はキャッシュ効果を期待できますが、サイトを再訪した時など、時間を置いて訪れた際は、以前のキャッシュはもうないものと思った方がよいでしょう。
</p>

<p>
Android 2.2や2.3といった2系のAndroid Browserでは、キャッシュ領域が8MBとそもそも小さく、キャッシュ効果自体があまり期待できません。<br>
吉報としてはAndroid2系のシェアが下がりつつあることでしょうか。
</p>

<p>
Android 4系のAndroid BrowserやChrome for Androidになると、85MBのファイルキャッシュ（Persistent Cache）を持つため、比較的良好な効果が期待できます。<br>
max-ageやETagといったキャッシュ寿命の設定も、この辺りから効果を持ち始めます。
</p>

<p>
このようにモバイル端末では、キャッシュの取り扱いに諸々問題があります。<br>
より詳しい説明が <a href="http://www.guypo.com/uncategorized/mobile-browser-cache-sizes-round-2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Guy&#8217;s Podのエントリ</a>に掲載されているため、興味のある方は目を通されるとよいでしょう。</p>

<p>
ほかにもHTTPの同時接続数やJavaScriptの実行パフォーマンスなど細かな点が変わります。<br>
例えばiOS5とiOS6では、局所的なJavaScriptの実行パフォーマンスの違いからアニメーション描画に差異があり、体感的な差異をもたらすといったことが実際にありました。<br>
また、iOS7がリリースされたため、既にiOS5の性能劣化はあまり重要な問題とは言えなくなりました。<br>
このように細かなチューニングや性能測定を行う際はOSバージョン、ブラウザによる性能変化に注意し、その時に適切なものを選ぶよう注意が必要です。
</p>

<h3>計測に際して</h3>

<p>
計測を行う場合はざっくり、以下の三つのパートから計測を開始することが多いでしょうか。<br>
尚、計測を行う際はMobile SafariのWeb Inspectorなど、結果に影響を与えるデバッガ類を走らせないよう注意が必要です。
</p>

<ul>
<li>DOMContentLoadedまでの所要時間を計る</li>
<li>JavaScriptのメインルーチンが呼び出されるまでの所要時間を計る</li>
<li>感覚的待ち時間に該当する関数の実行完了までの所要時間を計る</li>
</ul>

<p>
それぞれの計測区結果を基に、さらに絞り込み問題の検出と改善を進めます。<br>
上記それぞれの所要時間に応じた具体的なチューニング方法を次に解説します。
</p>

<h2 id="domcontentloaded">3. DOMContentLoadedまでを高速化する</h2>

<p>
意外と重くなりがちなのが、DOMContentLoadedまでの所要時間です。<br>
経験則ですが、divやul、liなどHTMLタグの入れ子を深めると、その部分の処理が重くなる傾向があります。<br>
疑わしい部分はコメントアウトして計測してみる、といった方法で特定を行います。<br>
特に低スペック端末が影響を受けやすく、複雑なHTMLで組まれたメニュー部分を排除すると80ms近くDOMContentLoadedが改善した例もあります。
</p>

<p>
対応としてはHTMLの記述を見直すか、対象箇所を遅延評価にくくり出すのがよいでしょう。
遅延評価の方法はいくつかあり、XHRで取得する、または&lt;script type=&#8221;text/htmlfragment&#8221;&gt; のような評価されないscript要素で囲み、後でinnerHTMLに放り込むといった方法があります（文字列をHTMLとして評価する場合は、XSSなどセキュリティ面に十分気をつけてください）。</p>

<p>このようにファーストプライオリティに含まれないもの、例えばファーストビューに無関係な画像やHTMLブロックを遅延評価に追い出す方法は効果的でよく用いられます。</p>

<p>
例えば、画像の遅延ロードがあります。<br>
img要素のsrc属性を一旦data-src属性に記述しておき、優先すべき処理が終わってから、JavaScriptでdata-srcを拾って画像を改めて読み込むといったことを行います。<br>
重要でない仕事を後ろにずらすことで端末はその貴重なCPU、ネットワークといったリソースを重要な仕事に集中して利用することができます。<br>
このような遅延評価の手法、考え方はモバイルでは有効でチューニング作業全般においてよく登場します。
</p>

<h2 id="">4. メインルーチン実行までを高速化する</h2>

<p>
この場合はJavaScriptの読み込みにボトルネックが残っているか、読み込まれたJavaScriptの初期実行で時間を食っているケースを疑います。
</p>

<p>
各種JavaScriptライブラリも遅延要因になることがあります。<br>
これを計測するには、大変ベタな方法ですが、script要素内にライブラリのJavaScriptコードを貼り付け、前後でDate.nowを取ると計測できます。
</p>

<p><code>
var t = Date.now();
// ここにライブラリなど、評価したいJavaScriptコードを挿入する
// (function() { .... })
alert(Date.now() - t);
</code></p>

<p>
比較的重めのライブラリの例としてはjQueryがあります。<br>
jQueryはiPhone 4で80ms前後、Galaxy S3で100-200msの時間を初期実行に要します。<br>
これはファイルのダウンロードではなく上記のように純粋にJavaScriptの評価実行に基づいて発生する時間です。<br>
（jQuery1.8.3カスタムビルドで最小時にiPhone4+iOS6.1で54-61ms、フルビルドで80ms前後、2.0.0b1で同じく80ms前後）
</p>

<p>
仮に手持ちの予算が800msであるとすると、この所要時間は安くない買い物になります。<br>
またアプリケーションが依存するライブラリのコストは、遅延評価やチューニングといった緩和手段が取れず、必ず払うコストになります。
</p>

<p>
jQueryを例に挙げましたが、この場合はZepto.jsやtt.jsといったより軽量なライブラリに乗り換える手段があります。<br>
もしAndroidとiOSに絞れるコンテンツであれば、ライブラリを使わないのもよいでしょう。<br>
特にゲームやアニメーションを主体としたコンテンツではDOM操作の頻度も減るため、その分のライブラリを削ってゲームエンジンやデータの読み込みに予算を充てることが多くなります。<br>
目的にあったライブラリ選択を行い、予算を節約しましょう。<br>
またよく使うライブラリは、事前にコストを計測しておくとよいでしょう。</p>

<p>
他にはCPUやGPUに過剰な負荷がかかっている、といった場合が考えられます。<br>
特にDOMContentLoaded前後の時間帯は計算資源の空きが少なく、過剰なJIT処理の発生や重いアニメーションの再生を重ねると全体が遅延する、描画が一瞬固まるといったことなどがあります。<br>
HTMLの読み込み直後はできるだけCPU、GPUに優しく、負荷の高い処理は遅延させると体感が高速化することがあります。
</p>

<h2 id="">5. メインルーチン実行自体を高速化する</h2>

<p>
メインルーチンの実行自体に時間がかかる場合は、フレームワークやコンテンツ固有の特徴にひも付く問題が多くなります。<br>
フレームワークやゲームエンジン個々の話になると、その利用者に限られた内容となってしまうため、ここでは割愛します。<br>
ただ普段自分がよく使うライブラリ、フレームワークがモバイル端末できちんと動作するか実行性能を知り、できれば経験を重ねてチューニングに慣れておくと楽になります。<br>
プロファイラのような各種ツール群もこの辺りから活躍が始まります。</p>

<p>
ゲームのように大きなデータの扱いやタイミング制御の伴う画像等のアセットを扱う場合は、並列化、先読み処理といったテクニックもよく使われます。<br>
例えば先読みであれば次のように行います。
</p>

<p><code>
function preload() {
    // 先読みを行う
    loadImage('path');
}</p>

<p>function playScene() {
    // 画像を必要とする処理を行う
    loadImage('path', function() {
        play();
    });
}</p>

<p>function loadImage(src, onSuccess, onError) {
    var img = new Image();
    if (onSuccess) {
        img.onload = onSuccess;
    }
    if (onError) {
        img.onerror = onError;
    }
    img.src = src;
    return img;
}
</code></p>

<p>
並列化や先読みを行う場合、また少し複雑なアプリケーションになると非同期制御の問題がついて回ります。<br>
筆者もいままで様々な非同期制御ライブラリを使ってきましたが、現在はuupaa氏作のFlow.js（<a href="http://uupaa.hatenablog.com/entry/2013/03/12/185555" title="Flow.js" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">紹介記事</a>）に落ち着いています。<br>
Flow.js の長所としては、単純シンプルがゆえに動作が軽量であることが挙げられ、特に速度面を求める場合は Flow.js は良い選択肢となるでしょう。<br>
例えば Flow.js を使って複数画像の読み込み制御を行う場合は、次のようになります。
</p>

<p><code>
function playScene() {
    // 複数画像を必要とする処理を行う
    var paths = ['path-a', 'path-b', 'path-c'];
    var flow = new Flow(paths.length, function() {
      // 全ての画像の読み込みが終わると実行される
      play();
    });</p>

<pre><code>// 画像を読み込む
loadImage(paths[0], flow);
loadImage(paths[1], flow);
loadImage(paths[2], flow);
</code></pre>

<p>}</p>

<p>function loadImage(src, flow) {
    var img = new Image();
    if (flow) {
        img.onload = function() {
            flow.pass();
        }
    }
    img.src = src;
    return img;
}
</code></p>

<p>また連続した操作部分やサイト全体を、AJAX化するとサクサク感が増します。<br>
ブラウザはページの初期化に際して様々な処理を行っており、新たなページに遷移するだけで相応のCPU負荷がかかります。<br>
AJAX化することでこれを避けて、CPUに空きを作ってやることができ、ゲームなどの重いアニメーション、CPUを酷使するような仕事をファーストビュー領域内で行う場合などに有効です。</p>

<h2 id="javascript">6. JavaScript全体の実行速度を向上させる</h2>

<p>カリカリにチューニングを施す場面では、JavaScriptコード自体の最適化が求められます。</p>

<p>
例えば三項演算子を使い、cond ? A : B と書くより (cond &amp;&amp; A) || B と書いた方が高速です（ただしA≒false があり得るときに注意）。<br>
配列に要素追加を行うのであれば、arary.push(value)ではなくarray[array.length] = valueと書いたほうが速い、オブジェクトのプロパティに2回以上アクセスする場合は変数に代入した方が速いなど、このようなTIPSがJavaScriptには数多く存在します。
</p>

<p>
塵も積もれば何とやらで、CPUリソースが貴重なモバイル端末、特にゲームやミドルウェアなどの突き詰めた性能が必要となる場面はこのようなJavaScriptコードの最適化が効果を発揮します。
</p>

<p>
これを行うには<a href="http://jsx.github.io/" title="JSX" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">JSX</a>のようなJavaScriptの実効性能の最適化を特徴としたツールの導入が効果的です。<br>
上記TIPS程度であれば人手でまかなえますが、
「関数の呼び出し実行自体が遅く、関数をインライン展開した方が高速」などプログラマの手で生産的にまかなえる範囲を超えたノウハウも存在し、生産的にコードを書きたいのであればアプローチを変える必要があります。<br>
またJavaScriptエンジンが変わるとパフォーマンスの現れ方も変わるため、実行速度最適化の観点から考えるとプログラマが直接JavaScriptを書くのでなく、optimizerやaltJSなどを通じて最適化をかけることが望ましいといった結論に達します。
</p>

<p>
JavaScriptアプリケーション自体も複雑度が増してきており、本格的なアプリケーション開発においてエンジニアが直接JavaScriptを書く時代も終わりつつあるのかも知れません。<br>
そろそろaltJSの時代だな、と思います。
</p>

<h2 id="">最後に</h2>

<p>以上、ざっくりとモバイルでの最適化手法をお伝えしてきました。</p>

<p>
上手に最適化を施してやれば、通常のWebページ、Webアプリケーションはもとより、ゲームやアニメーションといった重量級のコンテンツでも、十分にサクサク快適に動作します。
</p>

<p>
そのために計測を行い、どこにコストを費やしているのか、問題を正確に把握するアプローチが大切です。<br>
「重い」と言われた場合、軽量化を求められた場合はどの端末で、どういった操作を行った時に重いのか、改善を必要としているのか、まず環境の特定から入り測定を行いましょう。
</p>

<p>
時々「ページの体感が重いから、画像を含むアセット量を500KB以下に定める」といったアプローチも聞きますが、それでは問題の一部しか解決できず、サクサクな体感に至らないケースがままあります。<br>
HTMLの読み込みコスト、JavaScriptによるブロッキング、フレームワークやゲームエンジンに紐付いた実行遅延、、CPUやネットワーク性能に限りがあるモバイル環境下では様々な要因が絡んで「もっさり」が発生します。<br>
サクサク化への効果的なアプローチと問題解決に、本稿がお役に立てることを願っています。
</p>
]]></content:encoded>
		
		<series:name><![CDATA[パフォーマンスチューニング]]></series:name>
	</item>
		<item>
		<title>DOM操作の最適化によるJavaScriptチューニング（後編）</title>
		<link>/yoshikawa_t/1932/</link>
		<pubDate>Sun, 08 Sep 2013 22:00:47 +0000</pubDate>
		<dc:creator><![CDATA[吉川 徹]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[パフォーマンス]]></category>
		<category><![CDATA[ブラウザ]]></category>
		<category><![CDATA[高速化]]></category>

		<guid isPermaLink="false">/?p=1932</guid>
		<description><![CDATA[連載： パフォーマンスチューニング (5) 連載「Webサイト・アプリ高速化テクニック徹底解説」の第5回は、前回の「DOM操作の最適化によるJavaScriptチューニング（前編）」に続く後編です。後編では、create...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/performance-tech/" class="series-149" title="パフォーマンスチューニング" data-wpel-link="internal">パフォーマンスチューニング</a> (5)</div><p><style>.codecolorer-container+h3{margin-top:1.5em;}</style>
連載「Webサイト・アプリ高速化テクニック徹底解説」の第5回は、前回の「<a href="https://html5experts.jp/yoshikawa_t/1888/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">DOM操作の最適化によるJavaScriptチューニング（前編）</a>」に続く後編です。後編では、createElement()などのDOM操作メソッドを使ったさまざまなテクニックや、パフォーマンスを劣化させるよくあるパターンについて詳しく解説します。</p>

<div style="border: 1px solid gray; margin: 1em; padding: 1em;">
<article>
<h1>CodeIQとの連動企画！</h1>
この記事で学べるJavaScriptチューニングのテクニックを、実際に<a href="https://codeiq.jp/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">CodeIQ</a>の問題で試すことができます。もう既に自信がある方は腕試しに、もしくは理解度チェックのための復習として是非ご活用ください！<a href="https://codeiq.jp/ace/yoshikawa_t/q452" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">こちら</a>から問題にチャレンジ！
</article>
</div>

<!-- more -->

<h1>DOM操作の最適化によるJavaScriptチューニング（後編）</h1>

<p>前回は、DOM操作が遅い原因と仕組みについて簡単に説明し、チューニングのサンプルをいくつか解説しました。その中で、innerHTMLを利用したコードをサンプルにあげていますが、innerHTMLを利用する場合、いくつかの点で注意が必要です。</p>

<ul>
<li>HTMLの文字列を扱うため単純な子要素の追加ができない（子要素をすべて書き換えることになる）</li>
<li>追加する要素が多くなると、文字列連結のコストやHTMLをパースするコストが膨れ上がる</li>
<li>HTMLを直接扱うため、きちんとエスケープしないとクロスサイトスクリプティングの脆弱性を作りこむ可能性がある</li>
</ul>

<p>以上の点から、特に理由がなければinnerHTMLよりもDOM操作メソッドを使ったほうが良いでしょう。今回は、DOM操作メソッドを使ったさまざまなテクニックや、パフォーマンスを劣化させるよくあるパターンを紹介し、そのチューニング方法を見ていきます。</p>

<p>また、前回の記事のinnerHTMLを使ったサンプルでは、上に挙げたような複数の要因でパフォーマンスに影響与えていることから、レイアウト・レンダリングの遅さのみを理由とするには、あまり適切ではありませんでした（チューニング自体には問題はありませんので心配しないでください）。折を見て改訂したいと思います。ご指摘して頂いた方々、ありがとうございました。
本連載では、より良い情報を皆さんに届けるため、ご指摘や疑問点などがあれば是非フィードバックを頂ければと思います。フィードバックを受け、できるかぎり記事を更新していきたいと思います。</p>

<h2>DOM操作メソッドを使ったテクニック</h2>

<p>createElement()やappendChild()などのDOM操作メソッドを使った方法では、単純にinnerHTMLによるコードを置き換えるだけでなく、さまざまなテクニックがあります。ここでは、DOM操作メソッドを使う際に覚えておいた方がよいテクニックをいくつか紹介します。</p>

<h3>複数の要素をまとめて追加する</h3>

<p>複数の要素を追加する場合、構造によってはそのままでは一度に追加できないことがあります。例えば、次のサンプルのようにul要素にli要素を追加していくようなケースです。</p>

<pre><code>:javascript:
// サンプル1: ul要素にli要素を追加していく（低速）
var ul = document.querySelector('#output');
for ( var i = 0; i &lt; data.length; i++ ) {
  var li = document.createElement('li');
  li.textContent = data[i];

  // ループのたびにli要素を追加
  ul.appendChild(li);
}
</code></pre>

<p>このサンプルでは、ループのたびにli要素を追加していますので、DOMツリーへ更新が何度も発生します。こういった場合には、DocumentFragmentを利用して複数のli要素をまとめて追加することができます。次のコードは、DocumentFragmentを利用して書き換えたコードです。</p>

<pre><code>:javascript:
// サンプル1: ul要素にli要素をまとめて追加（高速）
var ul = document.querySelector('#output'),
    fragment = document.createDocumentFragment();

for ( var i = 0; i &lt; data.length; i++ ) {
  var li = document.createElement('li');
  li.textContent = data[i];

  // いったんDocumentFragmentに追加する
  fragment.appendChild(li);
}

// 最後にDocumentFragmentをul要素に追加する
ul.appendChild(fragment);
</code></pre>

<p>DocumentFragmentは、従来のDOMツリーとは分離された独立した小さなDOMツリーです。createDocumentFragment()メソッドを使って作成します。DocumentFragmentに追加された要素は、そのままでは見た目に影響を与えないため、まずはDocumentFragmentにli要素を追加していきます。そして、最後にul要素にそのDocumentFragmentを追加し、反映します。こうすることで、元のDOMツリーへの更新が1回だけで済みます。</p>

<h3>繰り返し同じような要素を追加する（テンプレート化）</h3>

<p>同じような要素を繰り返し追加する場合、要素をまた一から作成していくのは面倒です。また、要素が多くなってくるとパフォーマンス的にもあまり良くありません。例えば、ボタンが押されるたびに、次のような構造を持つli要素を追加していくことを考えてみましょう。</p>

<pre><code>:html:
&lt;li&gt;
  &lt;artcile class="item"&gt;
    &lt;h1 class="title"&gt;アイテム&lt;/h1&gt;
    &lt;p class="detail"&gt;詳細&lt;/p&gt;
  &lt;/artcile&gt;
&lt;/li&gt;
</code></pre>

<p>これを素直にDOM操作メソッド使って構築すると次のようにボタンが押されるたびに毎回要素を生成して構築する形になります。</p>

<pre><code>:javascript:
// ボタンがクリックされる度に複雑な要素を追加
button.addEventListener('click', function(){

  // 各要素を生成
  var li = document.createElement('li'),
      article = document.createElement('article'),
      h1 = document.createElement('h1'),
      p = document.createElement('p');

  // 各要素のプロパティを設定し、組み立てる（省略）

  ul.appendChild(li);
}, false);
</code></pre>

<p>サンプルでは、コードが多い部分を省略していますが、多くのDOM操作をしています。このような場合、構築される要素をテンプレート化して、それをcloneNode()を使ってコピーするようにすれば、DOM操作の数を減らすことができます。cloneNode()を利用すると次のようなコードになります。</p>

<pre><code>:javascript:
// テンプレートとしてli要素を構築
var template = document.createElement('li'),
    article = document.createElement('article'),
    h1 = document.createElement('h1'),
    p = document.createElement('p');

// 各要素のプロパティを設定し、組み立てる（省略）

// ボタンがクリックされる度にテンプレートから要素を追加
button.addEventListener('click', function(){

  // テンプレートから要素をコピー
  var li = template.cloneNode(true);

  // 一部書き換えて追加
  li.querySelector('.title').textContent = 'アイテム';
  li.querySelector('.detail').textContent = 'アイテムの詳細'
  ul.appendChild(li);
}, false);
</code></pre>

<p>こうすると、ボタン押すたびにテンプレートからコピーするだけなので効率的です。構築する要素が複雑になればなるほど、cloneNode()を利用する方が高速になります。cloneNode()の引数は、子要素を一緒にコピーするかどうかなので、trueを指定しておきます。また、cloneNode()ではイベントリスナーをコピーすることはできませんので注意してください。</p>

<h3>複数の要素をまとめて置き換える</h3>

<p>既に表示されているインターフェースに対して最新の情報を反映するような場合があるかと思います。その際に、表示するデータが細かいとDOM操作も細かくなってしまうことがあります。例えば、次のようなHTMLの各p要素の内容を書き換えることを考えてください。</p>

<pre><code>:html:
&lt;div class="results"&gt;
  &lt;p&gt;結果1&lt;/p&gt;
  &lt;p&gt;結果2&lt;/p&gt;
  &lt;p&gt;結果3&lt;/p&gt;
&lt;/div&gt;
</code></pre>

<p>これを単純に書き換える場合は、次のようなコードになりがちです。</p>

<pre><code>:javascript: 
var elements = document.querySelectorAll('.results p');
elements[0].textContent = '結果a';
elements[1].textContent = '結果b';
elements[2].textContent = '結果c';
</code></pre>

<p>この場合、3つのp要素を順に書き換えているので、DOMツリーへの更新が3回発生してしまいます。このような場合、replaceChild()を使って一度に置き換えることができます。</p>

<pre><code>:javascript:
var origin = document.querySelector('.results'),
    clone = origin.cloneNode(true);

// コピーした要素を更新する
var elements = clone.querySelectorAll('p');
elements[0].textContent = '結果a';
elements[1].textContent = '結果b';
elements[2].textContent = '結果c';

// 元の要素とコピーした要素を入れ替える
origin.parentNode.replaceChild(clone, origin);
</code></pre>

<p>この方法であれば、DOMツリーへの更新は1回で済みます。また、先ほどのサンプルと同様にcloneNode()がイベントハンドラーをコピーできないことに注意しましょう。</p>

<h2>パフォーマンスを劣化させるよくあるパターン</h2>

<p>ここからは、パフォーマンスを劣化させるよくあるパターンや、そのチューニング方法を紹介します。</p>

<h3>複数のスタイルの書き換え</h3>

<p>ある要素のスタイルを複数書き換える場合に、ついやってしまいがちなのが次のコードです。</p>

<pre><code>:javascript:
// 複数のスタイルの書き換え（低速）
element.style.background = 'gray';
element.style.border = '1px solid black';
</code></pre>

<p>この場合も、レイアウトが複数発生する可能性があるので、次のように記述しましょう。</p>

<pre><code>:javascript:
// 複数のスタイルの書き換え（高速）
// style属性で一度にすべて指定する
element.setAttribute('style', 'background: gray; border: 1px solid gray;');
</code></pre>

<p>setAttribute()を使ってsytle属性を使って一度に複数のスタイルを指定しています。また、あらかじめ指定するスタイルがある程度決っているなら、可読性やメンテナンスを考えてclass属性を使っても良いでしょう。</p>

<pre><code>:javascript:
// classを指定して複数のスタイルを適用する
element.className = 'hoge';
</code></pre>

<h3>アニメーション</h3>

<p>ある要素の位置やサイズを動かしてアニメーションさせるような場合、スタイルでposition: absoluteやpositon: fixedを指定しておくと良いでしょう。これは、レイアウト・レンダリングの範囲を最少化するためです。position: absoluteなどを指定すると他の要素との位置関係やサイズ計算から切り離されるため、その要素に対する変更が他の要素に影響しなくなります。そのため、レイアウト・レンダリングのコストが小さくなり、パフォーマンスが向上します。アニメーションのチューニングについては、また別の記事で触れますので楽しみにしていてください。</p>

<h3>スタイル情報の取得</h3>

<p>多くのDOM操作によるスタイル情報の取得の中でも、次に挙げるプロパティ、メソッドについては特に注意が必要です。</p>

<ul>
<li>getComputedStyle()</li>
<li>offset*系のプロパティ</li>
<li>client*系のプロパティ</li>
<li>scroll*系のプロパティ</li>
</ul>

<p>（offset*系のプロパティとは、offsetという単語を含むoffsetTop、offsetLeft、offsetHeight、offsetWidthなどのプロパティです）</p>

<p>これらのプロパティ、メソッドは、現時点での最新の情報を返そうとするため、それまでに実行したDOM操作があれば、すぐさまレイアウト・レンダリングを実行します。本来であればブラウザが自動的に最適化し、非同期に実行しているものを強制的に実行してしまうため大きなボトルネックになります。例えば、あるブロックを単純に右に動かすだけのコードを見てみましょう。</p>

<pre><code>:javascript:
// あるブロックを右に動かす
setInterval(function(){
  block.style.left = block.offsetLeft + 1 + 'px';
}, 1000 / 60 );
</code></pre>

<p>ここでは、あるブロックのoffsetLeftを取得し、1を加えてスタイルのleftに代入しています。leftの値を更新した後に、またすぐにoffsetLeftを参照しているので、その時点でレイアウト・レンダリングが発生し、遅くなります。そのため、offsetLeftの値をキャッシュしておき、以降はそれを利用するように変更しましょう。</p>

<pre><code>:javascript:
// あるブロックを右に動かす
// offsetLeftの値を一度キャッシュして以降は使いまわす
var left = block.offsetLeft;
setInterval(function(){
  left++;
  block.style.left = left + 'px';
}, 1000 / 60 );
</code></pre>

<p>このように、上記であげたプロパティ、メソッドは、多くのDOM操作をしているような箇所では特にボトルネックになりやすいので注意しましょう。（サンプルでは、JavaScriptを使っていますが、もちろんCSSで記述しても良いでしょう。）</p>

<h3>要素の取得</h3>

<p>それほど気にするほどの差ではありませんが、要素を取得する際にquerySelector()やquerySelectorAll()よりも、getElementById()やgetElementsByTagName()、getElementsByClassName()を利用した方が若干速くなります。</p>

<pre><code>:javascript:
// div要素をすべて取得
var elements = document.querySelectorAll('div');

// querySelectorAll()よりも若干速い
var elements = document.getElementsByTagName('div');
</code></pre>

<p>その他の違いにも、getElementsByTagName()などは、結果として返るリスト（NodeList）が常に現在のDOMツリーを反映したものになるのに対して、querySelectorAll()などは取得した時点のものになります。例えば、これらのメソッドで要素を取得した後に、要素が追加された場合、getElementsByTagName()で取得したリストではリストにその要素が自動的に追加されますが、querySelectorAll()ではリストに変化はありません。そういった違いも覚えておくと良いでしょう。</p>

<h2>まとめ</h2>

<p>ここまで前編、後編にわたってDOM操作の最適化について解説しました。いくつかのサンプルやパターンを交えて、チューニング方法を紹介してきましたが、もちろんこれ以外にもたくさんのテクニックがあります。細かいテクニックをあげていくときりがありませんが、重要なのはDOM操作自体の回数を減らすことと、DOMツリーへの更新とレイアウトやレンダリングなどの範囲、回数を減らすことです。それさえ覚えておけば、自分でいろいろなコードに応用できるかと思います。自分自身で考えてチューニングしていきましょう。</p>
]]></content:encoded>
		
		<series:name><![CDATA[パフォーマンスチューニング]]></series:name>
	</item>
		<item>
		<title>DOM操作の最適化によるJavaScriptチューニング（前編）</title>
		<link>/yoshikawa_t/1888/</link>
		<pubDate>Wed, 04 Sep 2013 22:00:03 +0000</pubDate>
		<dc:creator><![CDATA[吉川 徹]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[パフォーマンス]]></category>
		<category><![CDATA[ブラウザ]]></category>
		<category><![CDATA[高速化]]></category>

		<guid isPermaLink="false">/?p=1888</guid>
		<description><![CDATA[連載： パフォーマンスチューニング (4)連載「Webサイト・アプリ高速化テクニック徹底解説」の第4回は、JavaScriptのチューニングのうち、ボトルネックになりやすいDOM操作の最適化について解説します。前編・後編...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/performance-tech/" class="series-149" title="パフォーマンスチューニング" data-wpel-link="internal">パフォーマンスチューニング</a> (4)</div><p>連載「Webサイト・アプリ高速化テクニック徹底解説」の第4回は、JavaScriptのチューニングのうち、ボトルネックになりやすいDOM操作の最適化について解説します。前編・後編にわたって、DOM操作が遅くなる原因と仕組み、その解決策について詳しく解説します。</p>

<div style="border: 1px solid gray; margin: 1em; padding: 1em;">
<article>
<h1>CodeIQとの連動企画！</h1>
この記事で学べるJavaScriptチューニングのテクニックを、実際に<a href="https://codeiq.jp/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">CodeIQ</a>の問題で試すことができます。もう既に自信がある方は腕試しに、もしくは理解度チェックのための復習として是非ご活用ください！<a href="https://codeiq.jp/ace/yoshikawa_t/q452" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">こちら</a>から問題にチャレンジ！
</article>
</div>

<!-- more -->

<h1>DOM操作の最適化によるJavaScriptチューニング（前編）</h1>

<p>DOM（Document Object Model）とは、HTMLをアプリケーション（ここではJavaScript）から利用するためのAPIです。JavaScriptによるユーザーインターフェースの構築やレスポンスの表示など、インタラクティブな部分はほとんどがDOM操作によるものでしょう。このように、非常に利用頻度の高いDOM操作ですが、同時に性能的にボトルネックになりやすい箇所でもあります。これらのDOM操作の最適化について、今回から前編・後編にわたって詳しく解説していきます。</p>

<h2>DOM操作は書き方によってスピードに数十倍の差が出る</h2>

<p>DOM操作は、書き方によって非常にパフォーマンスに差が出ます。例えば、次のようなコードを見てみましょう。id属性に&#8221;output&#8221;と指定された要素に、data配列の中身を単純にリスト表示するだけのものです。</p>

<pre><code>:javascript:
// サンプル1: パフォーマンスが悪い
var ul = document.querySelector('#output');
for ( var i = 0; i &lt; data.length; i++ ) {
  ul.innerHTML += '&lt;li&gt;' + data[i] + '&lt;/li&gt;';
}
</code></pre>

<p>これは、非常にパフォーマンスが悪い例です。これを次のように書き換えるだけで、環境にもよりますが速度は数十倍にもなります。</p>

<pre><code>:javascript:
// サンプル2: サンプル1に比べてパフォーマンスが良い
var ul = document.querySelector('#output');
var html = '';
for ( var i = 0; i &lt; data.length; i++ ) {
  html += '&lt;li&gt;' + data[i] + '&lt;/li&gt;';
}
ul.innerHTML = html;
</code></pre>

<p>このように、ボトルネックとなっているDOM操作をチューニングすれば、パフォーマンスが大きく改善する可能性があります。ここからは、DOM操作が遅くなる原因と仕組みを解説しながら、対応策を見ていきます。</p>

<h2>なぜDOM操作は遅いのか？</h2>

<p>DOM操作はなぜ遅いのでしょうか。それには、大きく2つの理由があります。1つ目は、DOMの実装方法によるものと、2つ目は、DOM操作によるレンダリングのコストが非常に高いということが挙げられます。この2つの理由と対応方法を覚えておけば、さまざまなコードに応用できます。それぞれ見ていきましょう。</p>

<h3>ブラウザの実装による遅さ</h3>

<p>元々DOMは、特定のプログラミング言語を対象としたものではなく、別々の言語から汎用的にアクセスできるような仕様になっています。そのため、多くのブラウザでは、HTMLのレイアウトや描画を担当するレンダリングエンジンと、JavaScriptを担当するスクリプトエンジンに分かれています。このようにスクリプト部分をモジュール化することによってDOM操作に別のプラグラミング言語を使うことも容易になっています。しかしながら、そのデメリットとして、JavaScriptからDOM操作を行うということは、モジュール間をブリッジするコストが発生することにもなります。そのため、DOM操作自体がプリミティブな操作に比べて非常に低速になっています。そういった観点から、HTMLの要素の単純なプロパティ参照なども含めて、極力DOM操作を減らすようにすることが重要です。</p>

<h3>レイアウト・レンダリングによる遅さ</h3>

<p>DOM操作の結果は、実際のHTMLに反映される際に、ブラウザでさまざまな処理が起こります。例えば、要素が追加された場合には、それによって発生する各要素の大きさや位置といったレイアウトを他の影響する要素を含めて、すべて再計算しなければなりません。また、レイアウトの再計算が終わったあとには、それらを画面にレンダリングする必要もあります。そして、これらの処理は非常にコストが高いものです。そのため、DOM操作によってレイアウトやレンダリングに影響がある範囲、回数をなるべく減らす必要があります。</p>

<p>例えば、冒頭に示したサンプル1のコードでは、次のようにli要素をループが回るたびに追加しているため、レイアウトとレンダリングが何回も発生して非常に遅くなってしまう可能性があります（レイアウトやレンダリングは非同期で処理されるため、実際にはブラウザがある程度、自動的に最適化してくれます）。</p>

<pre><code>:javascript:
// 複数回、レイアウト、レンダリングされる可能性がある
for ( var i = 0; i &lt; data.length; i++ ) {
  ul.innerHTML += '&lt;li&gt;' + data[i] + '&lt;/li&gt;';
}
</code></pre>

<p>innerHTMLを利用しているため、少なくてもHTMLのパースはループのたびに発生します。また、古いブラウザでは文字列の連結自体が問題になることもあります。このコードを、レイアウトとレンダリングが1回になるように書き換えると次のようになります。（その他にも、innerHTMLを「+=」演算子で余分に参照していることや、innerHTMLの中身を毎回すべて書き換えていることも遅さの原因になっていますが、次のコードではそれらも改善しています。）</p>

<pre><code>:javascript:
// 変数にHTMLを格納しておき最後に1回だけ書き換える
var html = '';
for ( var i = 0; i &lt; data.length; i++ ) {
  html += '&lt;li&gt;' + data[i] + '&lt;/li&gt;';
}
ul.innerHTML = html;
</code></pre>

<p>最終的に、結果が表示されれば良いので、li要素のHTMLは、いったん別の変数に格納しておき、最後に1回だけinnerHTMLへ代入しています。これによって、DOM操作の回数もレンダリングの回数も以前のコードに比べて1回で済みます。</p>

<h2>innerHTMLとDOM操作メソッド</h2>

<p>ここまでのサンプルでは、innerHTMLを使ってDOM操作を記述していますが、createElement()やappendChild()などのDOM操作メソッドを使う方法もあります。次のサンプルは、サンプル2をDOM操作メソッドを利用して記述した例です。</p>

<pre><code>:javascript:
// サンプル3: createElement()を使った例
var ul = document.querySelector('#output');
var fragment = document.createDocumentFragment();
for ( var i = 0; i &lt; data.length; i++ ) {
  var li = document.createElement('li');
  li.textContent = data[i];
  fragment.appendChild(li);
}
ul.appendChild(fragment);
</code></pre>

<p>innerHTMLとDOM操作メソッドは、それぞれ良い点がありますが、基本的にはDOM操作メソッドを使っていくほうがクロスサイトスクリプティングの脆弱性を作りこみにくいので安全です（innerHTMLは、文字列をパースするためユーザーの入力値を使う場合はエスケープする必要があります）。これらのDOM操作メソッドを利用する方法は、次回で詳しく取り上げていきます。</p>

<h3>innerHTMLとDOM操作メソッドのスピード</h3>

<p>innerHTMLとcreateElement()などのDOM操作メソッドは、どちらが速いかといった形でよく比較されることが多いですが、パフォーマンスという観点からはそれほど気にしなくても良いでしょう。モダンな環境では、お互いの速度差はそれほど大きくありませんし、ブラウザは常にバージョンアップされていますのでベンチマークの結果はすぐに変わります。特定の環境に特化したチューニングを行うのでなければ、細かい速度差を気にするよりは、機能の違いで使い分けていきましょう（ちなみに、現在はIE、FirefoxはinnerHTMLの方が若干速く、Chrome、SafariはDOM操作メソッドの方が若干速くなっています）。</p>

<h2>次回の内容について</h2>

<p>今回は、DOM操作が遅くなる理由と、その対処方法について簡単に解説しました。次回は、createElement()によるDOM操作と、チューニングのためのさまざまなTipsを紹介していく予定です。お楽しみに！</p>
]]></content:encoded>
		
		<series:name><![CDATA[パフォーマンスチューニング]]></series:name>
	</item>
	</channel>
</rss>
