<?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/"
	>

<channel>
	<title>Screw-Axis &#187; Web</title>
	<atom:link href="http://screw-axis.com/category/tips/web/feed/" rel="self" type="application/rss+xml" />
	<link>http://screw-axis.com</link>
	<description>flexible, elastic and principled.</description>
	<lastBuildDate>Fri, 04 May 2012 16:52:52 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>[Design] Responsive Layoutを学ぶ(2)</title>
		<link>http://screw-axis.com/2011/02/17/responsive-layout2/</link>
		<comments>http://screw-axis.com/2011/02/17/responsive-layout2/#comments</comments>
		<pubDate>Wed, 16 Feb 2011 15:14:46 +0000</pubDate>
		<dc:creator>nao58</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[design]]></category>

		<guid isPermaLink="false">http://screw-axis.com/?p=846</guid>
		<description><![CDATA[前回で、レスポンシブなデザインがつまりどういうものであるかと、その基本技術であるメディア・クエリーについて見てきました。 簡単におさらいしておくと、次のようなページを フレキシブル・グリッド・バージョン (A List  [...]
Related posts:<ol>
<li><a href='http://screw-axis.com/2011/02/16/responsive-layout1/' rel='bookmark' title='[Design] Responsive Layoutを学ぶ(1)'>[Design] Responsive Layoutを学ぶ(1)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://screw-axis.com/wp-content/uploads/2011/02/responsive2.jpg" alt="" title="responsive layout" width="240" height="158" class="alignright size-full wp-image-886" /><a href="/2011/02/16/responsive-layout1/">前回</a>で、レスポンシブなデザインがつまりどういうものであるかと、その基本技術であるメディア・クエリーについて見てきました。</p>
<p>簡単におさらいしておくと、次のようなページを<br />
<a href="http://www.alistapart.com/d/responsive-web-design/ex/ex-site-flexible.html">フレキシブル・グリッド・バージョン</a> (A List Apart)<br />
最終的には、次のようなレスポンシブ・レイアウトに<br />
<a href="http://www.alistapart.com/d/responsive-web-design/ex/ex-site-FINAL.html">レスポンシブ・レイアウト・バージョン</a> (A List Apart)<br />
仕上げようという試みです。<br />
<span id="more-846"></span></p>
<h4>基になるレイアウト</h4>
<p>まずは、大まかなレイアウトの構造を確認しておきましょう。全体の構成は大きく分けて4つのブロックから出来ています。<br />
<img src="http://screw-axis.com/wp-content/uploads/2011/02/inquire_layout.png" alt="" title="レイアウト" width="671" height="485" class="aligncenter size-full wp-image-869" /><br />
mastはfloat: left、それ以外の3つはfloat: rightが指定されて、こうした段組になっています。<br />
(これはあくまで、今回のサンプルの話です。レスポンシブ・レイアウトは、どんな段組にしようと基本的には実装可能です)</p>
<h4>レスポンシブ初歩</h4>
<p>では、これをウインドウサイズを縮めた時に、縦方向に並ぶよう記述してみましょう。</p>
<pre name="code" class="css">
@media screen and (max-width: 600px) {
  .mast,
  .intro,
  .main,
  .footer {
    float: none;
    width: auto;
  }
}</pre>
<p>非常に簡単なことで、各クラスのfloat指定を無くしてやるだけです。コードは「横幅が600pxより小さくなった場合、4つのクラスに対してfloat: noneとwidth: autoを指定する」という意味になります。</p>
<p>動作は、<a href="http://www.alistapart.com/d/responsive-web-design/ex/ex-site-linearize.html">こちら</a>から確認できます。いかがでしょうか。</p>
<h4>画像の組み換え</h4>
<p>次に、mainブロックにある画像に着目してみます。</p>
<p>現在、3&#215;2のレイアウトになっていますが、スクリーンを小さくしていくと画像が小さくなりすぎてしまうので、ある地点から2&#215;3のレイアウトに変えようと思います。</p>
<p>各人物のエリアには figure というクラスが割り当てられていて、約1/3の大きさになるように指定されています。そして、それぞれ右側にマージンをとっています。ただし、レイアウト上右端に来る2人(HOLMESとWINTER)は、右側のマージンが不要なので、id指定により除去しています。</p>
<pre name="code" class="css">
.figure {
  float: left;
  margin: 0 3.317535545023696682% 1.5em 0;   /* 21px / 633px */
  width: 31.121642969984202211%;             /* 197px / 633px */
}

li#f-mycroft,
li#f-winter {
  margin-right: 0;
}</pre>
<p>ここでスクリーンの横幅が400px以下だった場合には、figure の横幅が約半分になるようメディア・クエリーで指定します。</p>
<pre name="code" class="css">
@media screen and (max-width: 400px) {
  .figure,
  li#f-mycroft {
    margin-right: 3.317535545023696682%;    /* 21px / 633px */
    width: 48.341232227488151658%;          /* 306px / 633px */
  }

  li#f-watson,
  li#f-moriarty {
    margin-right: 0;
  }
}</pre>
<p>更に、右側のマージンが不要になる人物(つまり右端に来る人物)も変わるので、そこの指定も行っています。</p>
<p>動作を<a href="http://www.alistapart.com/d/responsive-web-design/ex/ex-site-mini.html">確認</a>してみてください。</p>
<h4>大画面対応</h4>
<p>さきほどのレイアウト組み換えは、逆にスクリーンが大きくなった際にも有効なテクニックです。</p>
<p>次のコードは、スクリーンの幅が1300pxを超えた場合に、人物を横一列に並べるよう指定しています。</p>
<pre name="code" class="css">
@media screen and (min-width: 1300px) {
  .figure,
  li#f-mycroft {
    margin-right: 3.317535545023696682%;    /* 21px / 633px */
    width: 13.902053712480252764%;          /* 88px / 633px */
  }
}</pre>
<p>動作は<a href="http://www.alistapart.com/d/responsive-web-design/ex/ex-site-larger.html">このように</a>なります。</p>
<h4>更に進んだ使い方</h4>
<p>これらのテクニックを応用することで、更に進んだレイアウトが可能になります。</p>
<p>前回の冒頭で紹介した<a href="http://www.alistapart.com/d/responsive-web-design/ex/ex-site-FINAL.html">最終形</a>では、次のような工夫をしています。</p>
<ul>
<li>各メニューが、小さな画面では最上部に横並びになる (ナビゲーションはページの先頭にあった方が便利なはず)</li>
<li>小さくすると、ロゴがシンプルな小さいバージョンに換わる (余計なものを除去)</li>
<li>大きな画面では、メニューが右上に並ぶ (人物が横一列にならび高さが低くなるので、そちらに移してもレイアウト上問題ないはず)</li>
</ul>
<p>あとはCSSのテクニックとの組み合わせばかりなので、コードを挙げての説明は割愛します。必要に応じて、サンプルのコードを直接開いてみてください。工夫次第で、かなり色々なことが出来ると思います。</p>
<h4>古いブラウザへの対応</h4>
<p>このようにメディア・クエリーは非常に強力な機能です。しかし、きちんと対応しているのは主なブラウザでは次のあたりになります。</p>
<ul>
<li>Safari 3以上</li>
<li>Google Chrome</li>
<li>Firefox 3.5以上</li>
<li>Opera 7以上</li>
</ul>
<p>何かと問題の Internet Explorer も、次のバージョン9からはメディア・クエリーに対応すると<a href="http://ie.microsoft.com/testdrive/HTML5/CSS3MediaQueries/">表明</a>はしています。</p>
<p>実際のところ、メディア・クエリーが動作しないブラウザであってもフレキシブル・グリッドなどは機能するものが多いですし、極端に大きくしたり小さくした際に最適なレイアウトが得られないだけなので問題は無いかもしれません。しかし、せっかく用意したものなので少しでも多くのブラウザに対応させたいということであれば、次のような方法があります。</p>
<ul>
<li>jQueryの<a href="http://plugins.jquery.com/project/MediaQueries">Media Queryプラグイン</a>を使う。非常に限定的な機能しか使えませんが、2007年からある便利なツールです。</li>
<li><a href="http://code.google.com/p/css3-mediaqueries-js/">Css3-mediaqueries-js</a>を使う。スクリプトがメディア・クエリーの記述を探し出して解析し、動作をエミュレートしてくれます。おかげでIE5以上、Firefox全般、Safari 2以上でもメディア・クエリーが使えるようになります。</li>
</ul>
<p>これらを導入することで、古いブラウザ環境であってもJavaScritpが動作するようになっていれば、対応できるようになります。</p>
<p>レスポンシブ・レイアウトは、Webの閲覧デバイスが加速度的に多様化している現在、ユーザにとっても開発者にとっても重要なものになってくるでしょう。これからサイトデザインやリニューアルをする場合、最初から設計に組み込んでおくのが良いと思います。</p>
<p>Related posts:<ol>
<li><a href='http://screw-axis.com/2011/02/16/responsive-layout1/' rel='bookmark' title='[Design] Responsive Layoutを学ぶ(1)'>[Design] Responsive Layoutを学ぶ(1)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://screw-axis.com/2011/02/17/responsive-layout2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Design] Responsive Layoutを学ぶ(1)</title>
		<link>http://screw-axis.com/2011/02/16/responsive-layout1/</link>
		<comments>http://screw-axis.com/2011/02/16/responsive-layout1/#comments</comments>
		<pubDate>Wed, 16 Feb 2011 09:45:55 +0000</pubDate>
		<dc:creator>nao58</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[design]]></category>

		<guid isPermaLink="false">http://screw-axis.com/?p=823</guid>
		<description><![CDATA[PCとスマートフォン両対応ページを作っていると、避けて通れないのがレイアウトの問題。昨年サンフランシスコのAdobe Maxで紹介していたResponsive Layoutが良いんだろうと思って調べたのですが、なかなか日 [...]
Related posts:<ol>
<li><a href='http://screw-axis.com/2011/02/17/responsive-layout2/' rel='bookmark' title='[Design] Responsive Layoutを学ぶ(2)'>[Design] Responsive Layoutを学ぶ(2)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://screw-axis.com/wp-content/uploads/2011/02/responsive_layout.jpg" alt="" title="responsive layout" width="240" height="200" class="alignright size-full wp-image-826" style="margin-left: 10px;" />PCとスマートフォン両対応ページを作っていると、避けて通れないのがレイアウトの問題。昨年サンフランシスコのAdobe Maxで紹介していたResponsive Layoutが良いんだろうと思って調べたのですが、なかなか日本語でまとまった資料が見つからず。</p>
<p>どうも「Responsive Layout」を日本で何と呼んでいるか分からず、だから見つからないのだと思うのですが。海外に<a href="http://www.alistapart.com/articles/responsive-web-design/">すごく良い記事</a>があったので、こちらのサンプルを用いながら、自分用にまとめておきます。</p>
<p>なお、サンプルは元記事のものへのリンクですが、本文は自分のざっとの理解で書いていますので、翻訳にはなっていません。ご了承ください。<br />
<span id="more-823"></span></p>
<h4>デバイスごとに個別にページを用意</h4>
<p>サイトが世に必要とされはじめた頃は、これが定番でしたね。サブドメインで m.example.com とか mobile.example.com とか。最近になっても smartphone.example.com なんてのも見かけます。</p>
<p>日本のガラケー対応は、あまりにもPC向けページとは作りが異なるので、結局これしかない部分もあります。また、デバイスによって画面のステップ数を変えるようなこだわりがある場合は、必要かもしれません。</p>
<p>しかし、ほぼ同じアーキテクチャで閲覧できる最近のスマートフォンで、そうした手間をかけるのは面倒です。SEOやメディアからの被リンクにも、あまり良いことは無いですし。</p>
<p>かといって、PCそのままのページ構成では読みにくい場合があることも事実。そこでまず出てくるのがフレキシブル・レイアウトです(まだ、今回取り上げたい「レスポンシブ・レイアウト」ではないので、慌てずに)。</p>
<h4>フレキシブルなレイアウト</h4>
<p>フレキシブル・レイアウトがどういったものなのか、サンプルを見てみましょう。</p>
<p><a href="http://www.alistapart.com/d/responsive-web-design/ex/ex-site-flexible.html" target="_blank">フレキシブル・グリッド・サンプル</a> (A List Apart)</p>
<p>PCブラウザで閲覧している場合、ウインドウサイズを大きくしたり小さくしたりすると、どういうものかすぐに分かると思います。いわゆる Fruid Grid (可変グリッド)と呼ばれる構造に、フレキシブル・イメージという親のグリッドにあわせて画像サイズが自動調整されるテクニックを用いた、まさに「フレキシブルな」レイアウトになっています。</p>
<p>可変グリッドや<a href="http://unstoppablerobotninja.com/entry/fluid-images">フレキシブル・イメージ</a>については詳細な説明は割愛しますが(要望があれば、どこかで)、スクリプトは事実上IE対応のみで、マトモなブラウザ相手であればHTML+CSSだけでサクサク実装できるのが魅力です。</p>
<p>これで概ね幸せだったのですが、iPhoneサイズで見るには、まだ残念な感じです。極端にブラウザを細くすると、グリッドがヘシャげて読みにくくなることが分かるかと。</p>
<p>そこでレスポンシブ・レイアウトの登場です。</p>
<h4>レスポンシブなレイアウト</h4>
<p>レスポンシブ・レイアウトでは、フレキシブル・レイアウトのように画面サイズに対して線形比率でレイアウトするのではなく、一定の閾値(ブレーク・ポイント)を堺にスタイルを切り替えることで、更に柔軟な構成を実現します。</p>
<p>まずは、実際に動作するサンプルを見てみましょう。</p>
<p><a href="http://www.alistapart.com/d/responsive-web-design/ex/ex-site-FINAL.html" target="_blank">レスポンシブ・レイアウト・サンプル</a> (A List Apart)</p>
<p>ブラウザサイズを変えていくと、ある地点でレイアウトが変わることがわかると思います。たとえば小さくしていくとサイドバーとコンテンツが縦に並んだり、画像の配置が変わったりといった具合です。この切り替わる境界点が「閾値」の部分です。</p>
<p>更に注目して欲しいのは、依然としてフレキシブル・レイアウトの動作も残している点です。閾値内でのレイアウトには、また従来のテクニックを組み合わせることが可能になっています。</p>
<p>これであれば、例えば同じスマートデバイスでもiPhoneとGalaxy Tabのように大きさが異なるディスプレイで、あるいは縦横の切替で、それぞれに最適な見せ方をすることができます。</p>
<p>次に、具体的な実装を見て行きましょう。</p>
<h4>メディア・クエリー</h4>
<p>元々はCSS2.1から登場した登場したメディア・タイプが、「デバイスによってスタイルを切り替える」という発想のスタートだったと思います。</p>
<pre name="code" class="html">
<link rel="stylesheet" type="text/css" href="core.css" media="screen" />
<link rel="stylesheet" type="text/css" href="print.css" media="print" />
</pre>
<p>実際に<a href="http://www.w3.org/TR/CSS21/media.html#media-types">多くのメディアタイプが定義</a>され、可能性を感じさせる仕様でした。しかし、メディア側の実装がなかなか追いつかず、実質的にはprintくらいしか使われていないと思います。</p>
<p>そこで登場したのが、考え方を引き継いで、より柔軟な実装を可能にした「<a href="http://www.w3.org/TR/css3-mediaqueries/">メディア・クエリー</a>」です。</p>
<p>メディア・クエリーは、メディア・タイプのようにデバイス依存のクラスを作成するのではなく、レンダリングするデバイスのサイズや性能を調べ、それを基に適用するスタイルを切り替えるものです。例えば次のコードは、iOS、Android、PCなどを問わず、出力先がスクリーン(プリンタなどではなく)で、デバイスの横幅が480px以内であればshetland.cssを適用するという意味になります。</p>
<pre name="code" class="html">
<link rel="stylesheet" type="text/css"
  media="screen and (max-device-width: 480px)"
  href="shetland.css" />
</pre>
<p>この例では、960&#215;480のスマートフォンを縦に持っている時は、横幅が480pxなのでスタイルが読み込まれます。しかし、横に持ち替えると条件に合致しなくなるので、この行は無視されるようになります。</p>
<p>こうしたことは、近年は<a href="http://www.themaninblue.com/experiment/ResolutionLayout/">JavaScriptを用いて実現する</a>のが常套でした。しかし、メディア・クエリーの実装が進んできたことで、こちらを使えば更に解像度や色数など、更に進んだ機能にも対応できます。</p>
<pre name="code" class="html">
<link rel="stylesheet" type="text/css"
  media="screen and (max-device-width: 480px) and (resolution: 163dpi)"
  href="shetland.css" />
</pre>
<p>またメディア・クエリーは、スタイルシート自体を切り分けるだけでなく、CSSファイルの中に記述することも可能です。</p>
<pre name="code" class="css">
@media screen and (max-device-width: 480px) {
  .column {
    float: none;
  }
}
</pre>
<p>更に、importの記述により切り分けることも出来ます。</p>
<pre name="code" class="css">
@import url("shetland.css") screen and (max-device-width: 480px);
</pre>
<p>特定のデバイスを見分けて切り分けるよりも、その特性にあわせたスタイルを適用する方が合理的であるという考え方を基に、こうした機能は実装されました。</p>
<p>レスポンシブ・レイアウトは、このメディア・クエリーを活用して多種多様なデバイスで最適な表示を実現するようデザインします。</p>
<p><a href="/2011/02/17/responsive-layout2/">次回</a>で、具体的な実装方法を見ていきます。</p>
<p>Related posts:<ol>
<li><a href='http://screw-axis.com/2011/02/17/responsive-layout2/' rel='bookmark' title='[Design] Responsive Layoutを学ぶ(2)'>[Design] Responsive Layoutを学ぶ(2)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://screw-axis.com/2011/02/16/responsive-layout1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[css] 効率の良いcssを書くための7箇条</title>
		<link>http://screw-axis.com/2009/06/15/css-good-7-practices/</link>
		<comments>http://screw-axis.com/2009/06/15/css-good-7-practices/#comments</comments>
		<pubDate>Sun, 14 Jun 2009 16:44:15 +0000</pubDate>
		<dc:creator>nao58</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[css]]></category>

		<guid isPermaLink="false">http://screw-axis.com/?p=557</guid>
		<description><![CDATA[スタイルシートをシンプルに効率よくすることは、ネットワーク転送量の低下、パース速度の向上、そしてHTMLとのマッチング効率化に繫がります。これはページのパフォーマンスを大きく向上させることに繫がります。 前回は大まかなブ [...]
Related posts:<ol>
<li><a href='http://screw-axis.com/2009/06/15/css-%e3%83%9a%e3%83%bc%e3%82%b8%e3%81%ab%e3%82%b9%e3%82%bf%e3%82%a4%e3%83%ab%e3%81%8c%e3%81%82%e3%81%a6%e3%82%89%e3%82%8c%e3%82%8b%e4%bb%95%e7%b5%84%e3%81%bf%e3%82%92%e5%ad%a6%e3%81%b6/' rel='bookmark' title='[css] ページにスタイルがあてられる仕組みを学ぶ'>[css] ページにスタイルがあてられる仕組みを学ぶ</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm4.static.flickr.com/3361/3238626102_a2840f4af9_m.jpg" alt="inefficient" title="inefficient" width="161" height="240" class="alignright size-full" style="margin-left: 5px;" />スタイルシートをシンプルに効率よくすることは、ネットワーク転送量の低下、パース速度の向上、そしてHTMLとのマッチング効率化に繫がります。これはページのパフォーマンスを大きく向上させることに繫がります。</p>
<p>前回は<a href="/2009/06/15/css-%e3%83%9a%e3%83%bc%e3%82%b8%e3%81%ab%e3%82%b9%e3%82%bf%e3%82%a4%e3%83%ab%e3%81%8c%e3%81%82%e3%81%a6%e3%82%89%e3%82%8c%e3%82%8b%e4%bb%95%e7%b5%84%e3%81%bf%e3%82%92%e5%ad%a6%e3%81%b6/">大まかなブラウザの挙動</a>を見ました。<br />
今回は、そういった動きを踏まえた上で、やってしまいがちな非効率なスタイル指定を挙げてみます。そういった指定を避けることで、軽量で高速なスタイルシートを記述することができるでしょう。</p>
<p>なお、この記事は、Google Page Speedの”<a href="http://code.google.com/intl/ja/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors">Use efficient CSS selectors</a>&#8220;および、Mozillaの&#8221;<a href="https://developer.mozilla.org/en/Writing_Efficient_CSS">Writing Efficient CSS for use in the Mozilla UI</a>&#8220;などを元に書いています。<br />
<span id="more-557"></span></p>
<h5>1. 不要なスタイルは書かない</h5>
<p>言うまでもない大前提です。ですが、ちょっと調べてみると意外と多いのではないでしょうか。<br />
例えばサイト内で幾つかのパターンのページがあります。しかしひとつの外部cssを使っているため、それぞれのページでは不要なスタイルを大量に読み込んでいるようなことは無いでしょうか。<br />
または、ページを変更してコンテンツを入れ替えた場合、新しいコンポーネントのためのスタイルは当然追加しますが、削除した方のスタイルは削除しているでしょうか。</p>
<p>確かに<a href="/2009/06/06/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%961/">ファイルがキャッシュされれば転送時間は軽減できます</a>が、それでも余分なスタイル記述はDisk I/Oの増加をもたらすだけでなく、<a href="/2009/06/15/css-%e3%83%9a%e3%83%bc%e3%82%b8%e3%81%ab%e3%82%b9%e3%82%bf%e3%82%a4%e3%83%ab%e3%81%8c%e3%81%82%e3%81%a6%e3%82%89%e3%82%8c%e3%82%8b%e4%bb%95%e7%b5%84%e3%81%bf%e3%82%92%e5%ad%a6%e3%81%b6/">ルールの多さはそのままマッチングコストの増加</a>に繫がります。</p>
<p><a href="http://code.google.com/intl/ja/speed/page-speed/index.html">Google Page Speed</a>を用いれば、そのページで使っていないルールを確認できます。<br />
スタイルはスクリプトに比べて<a href="/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/">分割ダウンロードもしやすい</a>ので、使いやすい単位にcssを分割するなどして、可能な限り不要なスタイルを書かないようにしましょう。</p>
<h5>2. Universal Rulesを使わない (出来れば、Tag Rulesも)</h5>
<p><a href="/2009/06/15/css-%e3%83%9a%e3%83%bc%e3%82%b8%e3%81%ab%e3%82%b9%e3%82%bf%e3%82%a4%e3%83%ab%e3%81%8c%e3%81%82%e3%81%a6%e3%82%89%e3%82%8c%e3%82%8b%e4%bb%95%e7%b5%84%e3%81%bf%e3%82%92%e5%ad%a6%e3%81%b6/">前回</a>説明しましたが、Keyセレクタによってルールは4種類に分けられます。その際に最も非効率なのが、Universal Rulesです。Universal Rulesはつまり、IDでもクラスでも要素でも無いルールです。これは全ての要素が常に立ち止まって確認するルールになってしまいます。<br />
次にパフォーマンスの悪いのは、Tag Rulesです。これらを極力避けるようにしましょう。</p>
<h5>3. IDをタグやクラス名とあわせない</h5>
<p>IDはページ内で完全に一意なものなので、そこにタグやクラス名を重ねることは全くの無駄です。<br />
場合によっては、スクリプトなどでクラス指定を切り替え、それによって動きを変えたい場合があるかもしれません。しかしその場合でも、クラス名の方をユニークにすることで無駄な評価を避けられるはずです。<br />
また、ひとつのcssファイルを複数ページで使いまわし、その時にページによって同じIDのあたるタグが変わることでルールを変えるような運用も、前述のような理由で避けるべきです。</p>
<pre>
  ×  button#backButton { ... }
  ×  .menu-left#newMenuIcon { ... }
  ○  #backButton { ... }
  ○  #newMenuIcon { ... }
</pre>
<h5>4. 子孫セレクタを使わない</h5>
<p>次のようなセレクタを、descendant(子孫)セレクタと呼びます。</p>
<pre>
body * {...}
#footer h3 {...}
* html #atticPromo ul li a {...]
</pre>
<p>これは関係を辿るセレクタとしては最低ｊといってよいほどにかかるので、極力避けましょう。<br />
と書くと、ショックを受ける人もいるのではないでしょうか。(自分は最初にこれを聞いた時、少なからずそうでした)<br />
CssはCASCADE Styele Sheetです。「カスケード」はまさに、こういった入れ子での制御を使いこなすことだと思っていました。<br />
しかし、前回のエントリを見ていただいたら分かるのではないかと思うのですが、要素がマッチする限りDOMツリーを辿ることを繰り返さなければなりません。この上でKeyセレクタがTagもしくはUniversalであれば、まさに最悪です。(先ほど挙げた例は、まさにそれです)</p>
<p>要素の関係性で表現するのではなく、クラス指定などを用いて効率の良いマッチングが行えるようにしましょう。<br />
例えば次のようなスタイルを書くよりも、</p>
<pre>
.side-menu ul li { ... }
.side-menu ol li { ... }
.top-menu ul li { ... }
</pre>
<p>各li要素にクラス指定を行った方が、マッチングコストは安くあがります。</p>
<pre>
.side-menu-list { ... }
.side-menu-list { ... }
.top-menu-list { ... }
</pre>
<h5>5. 子セレクタを使わない</h5>
<p>子孫セレクタほどではありませんが、child(子)セレクタも非常に高コストです。<br />
特にTag RulesやUniversal Rulesと組み合わせてはいけません。特にルールが頻繁にマッチしてしまうと、辿る回数はその分だけ増えていきます。例えば次のようなルールは、その親要素であることが稀であり、無駄にコストを上げてしまう一例です。</p>
<pre>
form > input { ... }
dl > dt { ... }
table > thead > tr > th { ... }
</pre>
<p>前の子孫セレクタ同様に、クラス指定などでの直裁的な指定をするようにしましょう。</p>
<h5>6. :hover擬似セレクタを使わない</h5>
<p>:hover擬似セレクタの指定は、どんな場合であれパフォーマンスに悪影響を与えますが、特にアンカー(aタグ)でない要素に対して用いると問題が多くなります。</p>
<pre>
div:hover
* div:hover
</pre>
<p>出来るならば、擬似セレクタではなく javascript の onmouseover などによる制御を行いましょう。</p>
<h5>7. 継承に委ねる</h5>
<p>親要素から自動的に継承されるスタイルをきちんと理解して、無駄な指定を省きましょう。<br />
例えば list-style-image スタイルは親要素から継承されます。これを知っているかどうかで、場合によっては次のようなスタイルルールを作ってしまうかもしれません。</p>
<pre>
div.star-list ul li { list-style-image: url( star.gif ); }
</pre>
<p>しかし、これは次のような指定で充分です。</p>
<pre>
div.star-list { list-style-image: url( star.gif ); }
</pre>
<p>些細なことのようですが、ここでulブロックやli要素が数百あったらどうでしょう。上の例では、その数百の要素に対して「先祖がulで、その先祖がstar-listというクラスを持つdiv要素であるか」という評価を繰り返すことになってしまいます。しかし下の例であれば、その数百のli要素群は全くマッチングコストをかけることなく、同じ効果を与えられます。</p>
<p>なお、ここで言う「効率が良い」とは、あくまで実行時のパフォーマンスにフォーカスしたものです。開発やメンテナンスなどの管理効率などとは相反するような場合もあるかもしれません。<br />
しかし、ここで挙げられていることはよく読めば、「直接指定」や「重複を避ける」など、スタイル指定のスパゲティ化を避ける方法とも言えます。<br />
ページの高速化は何よりのユーザビリティ向上なので、うまくバランスをとりながらパターンを確立していきましょう。</p>
<p>Related posts:<ol>
<li><a href='http://screw-axis.com/2009/06/15/css-%e3%83%9a%e3%83%bc%e3%82%b8%e3%81%ab%e3%82%b9%e3%82%bf%e3%82%a4%e3%83%ab%e3%81%8c%e3%81%82%e3%81%a6%e3%82%89%e3%82%8c%e3%82%8b%e4%bb%95%e7%b5%84%e3%81%bf%e3%82%92%e5%ad%a6%e3%81%b6/' rel='bookmark' title='[css] ページにスタイルがあてられる仕組みを学ぶ'>[css] ページにスタイルがあてられる仕組みを学ぶ</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://screw-axis.com/2009/06/15/css-good-7-practices/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[css] ページにスタイルがあてられる仕組みを学ぶ</title>
		<link>http://screw-axis.com/2009/06/15/css-%e3%83%9a%e3%83%bc%e3%82%b8%e3%81%ab%e3%82%b9%e3%82%bf%e3%82%a4%e3%83%ab%e3%81%8c%e3%81%82%e3%81%a6%e3%82%89%e3%82%8c%e3%82%8b%e4%bb%95%e7%b5%84%e3%81%bf%e3%82%92%e5%ad%a6%e3%81%b6/</link>
		<comments>http://screw-axis.com/2009/06/15/css-%e3%83%9a%e3%83%bc%e3%82%b8%e3%81%ab%e3%82%b9%e3%82%bf%e3%82%a4%e3%83%ab%e3%81%8c%e3%81%82%e3%81%a6%e3%82%89%e3%82%8c%e3%82%8b%e4%bb%95%e7%b5%84%e3%81%bf%e3%82%92%e5%ad%a6%e3%81%b6/#comments</comments>
		<pubDate>Sun, 14 Jun 2009 16:30:31 +0000</pubDate>
		<dc:creator>nao58</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[css]]></category>

		<guid isPermaLink="false">http://screw-axis.com/?p=535</guid>
		<description><![CDATA[Google Page Speedの記事から始まってしまったサイト高速化関連記事。 今回は、効率の良いスタイルを書くために、ブラウザがHTMLを解析してDOMツリーをつくり、そこにスタイルをあてていく過程を見ていきましょ [...]
Related posts:<ol>
<li><a href='http://screw-axis.com/2011/12/19/jquery-mobile-actionsheet/' rel='bookmark' title='[jQuery Mobile] ActionSheetプラグイン'>[jQuery Mobile] ActionSheetプラグイン</a></li>
<li><a href='http://screw-axis.com/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(3)'>[Web] Google Page Speedでサイトを高速化(3)</a></li>
<li><a href='http://screw-axis.com/2009/06/15/css-good-7-practices/' rel='bookmark' title='[css] 効率の良いcssを書くための7箇条'>[css] 効率の良いcssを書くための7箇条</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm1.static.flickr.com/156/414482195_751c172098_m.jpg" alt="painter" title="painter" width="240" height="175" class="alignright size-full" style="margin-left: 5px;" /><a href="/2009/06/14/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%96/">Google Page Speedの記事</a>から始まってしまったサイト高速化関連記事。<br />
今回は、効率の良いスタイルを書くために、ブラウザがHTMLを解析してDOMツリーをつくり、そこにスタイルをあてていく過程を見ていきましょう。</p>
<p>基本的な手順がわかると、どういったcssの書き方が効率が良く、どういった書き方では迂遠であったり冗長であったりするのかが、理解できるようになると思います。</p>
<p>この記事は、Google Page Speedの&#8221;<a href="http://code.google.com/intl/ja/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors">Use efficient CSS selectors</a>&#8220;および、Mozillaの&#8221;<a href="https://developer.mozilla.org/en/Writing_Efficient_CSS">Writing Efficient CSS for use in the Mozilla UI</a>&#8220;などを元に書いています。そのため、この仕組みは主にMozillaエンジンについてです。IEやWebKitでは若干異なった動作をする部分もあるようです。<br />
<span id="more-535"></span></p>
<h5>マッチングの回数</h5>
<p>ブラウザは、読み込んだHTMLをパースしてDOMツリーを作成します。<br />
その後、ツリーを辿りながらそれぞれの要素について、各スタイルが合致するかどうかを検証することになります。検証はルールのグルーピング(後述)などにより効率化はされていますが、基本的には全ての要素を駆動表に、全てのスタイルルールを検証する作業になります。つまり、端的には次のような計算数分だけ、マッチングが行われるわけです。</p>
<pre>HTML中の全要素数 × スタイル上のルール数</pre>
<p>例えば、次のようなシンプルな文書があったとします。</p>
<pre name="code" class="html">
&lt;head&gt;
  &lt;style&gt;
    div { ... }
    h1 { ... }
    .sample div { ... }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h1&gt;タイトル&lt;/h1&gt;
  &lt;div&gt; ... &lt;/div&gt;
  &lt;div class="sample"&gt;
    &lt;div&gt; ... &lt;/div&gt;
  &lt;/div&gt;
&lt;/body&gt;
</pre>
<p>この中に、要素は5つ(body, h1, div x 3)あります。スタイルは3つです。5つの各要素に対して3つのルールがマッチするかを検証するわけですから、マッチング数としては 5 x 3 となり、計15回のマッチングが行われる計算になります。</p>
<h5>マッチングの詳細</h5>
<p>では、今度は各マッチングを見ていきます。<br />
まず&#8221;Keyセレクタ&#8221;という言葉を覚えてください。これは、単純に「ルールの一番右側にあるセレクタ」を指します。例えば次のようなスタイルがあった場合、</p>
<pre name="code" class="css">
  #id { ... }
  .class div, .class p { ... }
  div.class form input[checked="checked"] { ... }
</pre>
<p>Keyセレクタは上から順に、#id、divとp、input[checked="checked"]です。<br />
このKeyセレクタが次のいずれに該当するかで、スタイルルールをまず大きく4つに分類します。</p>
<ul>
<li><strong>ID Rules</strong><br />
KeyセレクタがIDであるもの。</p>
<pre name="code" class="css">
button#backButton { }
#urlBar[type="autocomplete"] { }
treeitem > treerow > treecell#myCell:active { }
</pre>
</li>
<li><strong>Class Rules</strong><br />
Keyセレクタがクラス指定であるもの。</p>
<pre name="code" class="css">
button.toolbarButton { }
.fancyText { }
menuitem > .menu-left[checked="true"] { }
</pre>
</li>
<li><strong>Tag Rules</strong><br />
Keyセレクタがタグ指定であるもの。</p>
<pre name="code" class="css">
td { }
treeitem > treerow { }
input[type="checkbox"] { }
</pre>
</li>
<li><strong>Universal Rules</strong><br />
Keyセレクタが、つまり上記3つのいずれにも当てはまらないもの。</p>
<pre name="code" class="css">
[hidden="true"] { }
* { }
tree > [collapsed="true"] { }
</pre>
</li>
</ul>
<p>このようなグループ分けをした上で、マッチングは該当要素に合致するかどうかを、ルールの右(Keyセレクタ)から順に左方向に確認していきます。合致しなくなったところで検証を止めます。</p>
<p>具体的に見てみましょう。<br />
次のようなスタイルがあったとします。</p>
<pre>
div.cls fieldset > input { ... }
</pre>
<p>HTMLは、次のようにします。</p>
<pre name="code" class="html">
&lt;body&gt;
  &lt;div class="cls"&gt;
    &lt;div&gt;
      &lt;form&gt;
        &lt;fieldset&gt;
          &lt;input type="checkbox" id="id" /&gt;
        &lt;/fieldset&gt;
      &lt;/form&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/body&gt;
</pre>
<p>ここで6行目のcheckboxを、前述のスタイルルールにマッチングしてみます。</p>
<ol>
<li>Keyセレクタである&#8221;input&#8221;がタグなので、このルールはTag Rulesに分類されています。この要素はまずTag Rules中のinputにマッチするかを確認し、検証を始めます。</li>
<li>ひとつ左に行くと、これは「1つ親の要素がfieldsetである」という意味です。そこでDOMツリーでひとつ上を確認(5行目)すると、確かにfieldsetです。</li>
<li>そこで次のルールを確認します。次は「先祖にclsという名前のクラスを持つdiv要素があること」です。DOMツリーを順に辿っていくと(4→3→2行目)、該当するものが見つかりました。</li>
<li>全てのルールに合致したので、このスタイルを適用します。</li>
</ol>
<p>では次に、次のようなルールを検証してみましょう。</p>
<pre>
#id { ... }
</pre>
<p>これは当然、ID Rulesにカテゴライズされています。</p>
<ol>
<li>idというidを持つ要素であるので、合致する</li>
</ol>
<p>終わりです。</p>
<p>これは極端な例ですが、スタイル指定の効率の良し悪しが想像つくと思います。<br />
次は、具体的に効率の悪いスタイル記述を挙げてみます。そういった記述を極力避けることで、スタイルの適用を高速化することができます。</p>
<p>Related posts:<ol>
<li><a href='http://screw-axis.com/2011/12/19/jquery-mobile-actionsheet/' rel='bookmark' title='[jQuery Mobile] ActionSheetプラグイン'>[jQuery Mobile] ActionSheetプラグイン</a></li>
<li><a href='http://screw-axis.com/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(3)'>[Web] Google Page Speedでサイトを高速化(3)</a></li>
<li><a href='http://screw-axis.com/2009/06/15/css-good-7-practices/' rel='bookmark' title='[css] 効率の良いcssを書くための7箇条'>[css] 効率の良いcssを書くための7箇条</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://screw-axis.com/2009/06/15/css-%e3%83%9a%e3%83%bc%e3%82%b8%e3%81%ab%e3%82%b9%e3%82%bf%e3%82%a4%e3%83%ab%e3%81%8c%e3%81%82%e3%81%a6%e3%82%89%e3%82%8c%e3%82%8b%e4%bb%95%e7%b5%84%e3%81%bf%e3%82%92%e5%ad%a6%e3%81%b6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Web] Google Page Speedでサイトを高速化</title>
		<link>http://screw-axis.com/2009/06/14/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%96/</link>
		<comments>http://screw-axis.com/2009/06/14/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%96/#comments</comments>
		<pubDate>Sat, 13 Jun 2009 19:01:08 +0000</pubDate>
		<dc:creator>nao58</dc:creator>
				<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://screw-axis.com/?p=517</guid>
		<description><![CDATA[3～4回で書けると思ったGoogle Page Speedについて。 ひとつの項目について思った以上に長くなってしまっているので、順番を間違えた気もしますが、ここでインデックス的に全体をまとめておきます。 おさらいしてお [...]
Related posts:<ol>
<li><a href='http://screw-axis.com/2009/06/06/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%961/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(1)'>[Web] Google Page Speedでサイトを高速化(1)</a></li>
<li><a href='http://screw-axis.com/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(3)'>[Web] Google Page Speedでサイトを高速化(3)</a></li>
<li><a href='http://screw-axis.com/2009/06/07/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%962/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(2)'>[Web] Google Page Speedでサイトを高速化(2)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm1.static.flickr.com/32/59503362_9c937ed84a_m.jpg" alt="speed" title="speed" width="180" height="240" class="alignright size-full" style="margin-left: 5px;" />3～4回で書けると思った<a href="http://code.google.com/intl/ja/speed/page-speed/index.html">Google Page Speed</a>について。</p>
<p>ひとつの項目について思った以上に長くなってしまっているので、順番を間違えた気もしますが、ここでインデックス的に全体をまとめておきます。</p>
<p>おさらいしておくと、このツールはFirebugと組み合わせて使う、ページのボトルネック調査ツールです。<br />
Page Speedを実行したからといって、自動的にページの表示スピードが速くなるようなことはありません。リストアップされた問題点を理解し、自分の環境にあわせた対応策をとって、はじめてページは高速になります。</p>
<p>自サイトに対して挙げられた項目であれ、そうでなくても、注意すべき点として基本的な内容を理解しておくことは有益です。<br />
<span id="more-517"></span></p>
<h4 style="background-color: black; color: white;">キャッシュの最適化 &#8211; Optimizing caching</h4>
<p>ネットワーク転送量を減らすことは、ページの表示速度を劇的に速められます。ブラウザやプロキシのキャッシュの仕組みを学び、効率良くデータを交換しましょう。</p>
<h5>Leverage browser caching</h5>
<p>ブラウザキャッシュを有効にして、データの再送を減らします。<br />
キャッシュを使うには、HTTPレスポンスヘッダにExpireやETagなどを付けてやる必要があります。キャッシュの方法には一定期間無条件でキャッシュをする方法と、データに変更が無いかどうかの通信を行い、必要な場合だけ内容を転送する方法があり、当然ながら前者の方が高速です。<br />
ヘッダを付与するのは、ほとんどの場合Webサーバの役目です。<br />
<a href="/2009/06/06/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%961/">&raquo; 詳細</a></p>
<h5>Leverage proxy caching</h5>
<p>プロキシサーバにキャッシュをさせると、各クライアントからネットワーク的に近いところでキャッシュが行われ、高速化やサーバの負荷軽減に役立ちます。<br />
HTTPヘッダへの記述や静的ファイルのURL記述方法によって、キャッシュされるかどうかが変わってきます。逆に効果測定用のリクエストなど、プロキシにキャッシュさせたくないものもあります。ケースを学び、正しくコントロールできるようにしましょう。</p>
<h4 style="background-color: black; color: white;">往復遅延時間の最小化 &#8211; Minimizing round-trip times</h4>
<p>キャッシュは主に再訪者に効果があるものですが、RTTを軽減することは全てのケースで有効です。<br />
無駄を省き、パラレルに効率良くダウンロードすることで、根本的な高速化を図ることが出来ますが、若干高度なトピックが多いかもしれません。</p>
<h5>Minimize DNS lookups</h5>
<p>HTTPで通信する際、ホスト名毎にDNSルックアップと呼ばれる作業が必要になります。例えば&#8221;screw-axis.com&#8221;と通信したい場合、そのままでは接続先を見つけることができません。DNSに問い合わせて、&#8221;112.78.113.31&#8243;というIPアドレスであることを教えてもらわなければなりません。<br />
同じホスト名であれば何度もルックアップする必要はありませんが、例えば1つのページに20種類のホストがあれば、20回の問い合わせが必要になります。可能な範囲でこの数を減らすことは、無駄を省き、RTTの最小化に役立ちます。<br />
後述するように、必ずしもホスト数を最小にすることがイコール最適化ではないのですが、不要な呼び出しは減らしていきましょう。</p>
<h5>Minimize redirects</h5>
<p>サイトがリダイレクトを使う理由は様々です。サイトの移転、多重ドメイン、アクセスのトラッキングなど、それぞれの理由でリダイレクトを行っていると思いますが、可能な限りこれを避ける方法を講じるべきです。<br />
単に不要なものを除外する他にも、リダイレクトではなくリライトを用いたり、トラッキングをバックグラウンドで非同期に行うなどの工夫をしていきましょう。</p>
<h5>Combine external JavaScript</h5>
<p>外部Jsファイルはモジュール毎に分割されがちですが、1つにまとめてもコード量は同じです。<br />
特にJavascriptはパラレルダウンロードが行われないブラウザが多いため、接続の初期化やHTTPヘッダの往復が細かいボトルネックになります。<br />
管理の利便性などとのトレードオフになりますが、Minify、結合、圧縮を行って通信できる管理運用方法を確立しましょう。<br />
<a href="/2009/06/07/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%962/">&raquo; 詳細</a></p>
<h5>Combine external CSS</h5>
<p>スタイルシートもJs同様に、まとめることでボトルネックを軽減できます。<br />
しかしCSSに関してはパラレルにダウンロードできるブラウザが殆どなので、ケースによっては分かれていた方が高速な場合もあります。(そのケースはトータルでかなり巨大なスタイル群になっているはずなので、そもそも避けるべき事態ですが)<br />
その際でも、<a href="/2009/06/07/css-import%e3%82%92%e4%bd%bf%e3%81%86%e3%81%b9%e3%81%8d%e3%81%a7%e3%81%aa%e3%81%84%e7%90%86%e7%94%b1/">指定の仕方によってはパラレルに走らないこともある</a>ので注意してください。<br />
<a href="/2009/06/07/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%962/">&raquo; 詳細</a></p>
<h5>Optimize the order of styles and scripts</h5>
<p>ダウンロードの手順で、同時に走る通信量は大きく変わります。<br />
head要素内のファイル指定順、インラインスクリプトのタイミングなど、原理を理解してセオリーを身につけましょう。<br />
<a href="/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/">&raquo; 詳細</a></p>
<h5>Parallelize downloads across hostnames</h5>
<p>ひとつのブラウザが、あるホストと同時に作れる接続は限られています。<br />
平行ダウンロード数を増やすため、ホストを敢えて分散させるテクニックも学びましょう。<br />
<a href="/2009/06/12/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%964/">&raquo; 詳細</a></p>
<h4 style="background-color: black; color: white;">リクエストサイズの最小化 &#8211; Minimizing request size</h4>
<p>HTTPはリクエスト毎にヘッダを送受信します。<br />
このサイズを減らすことは、ひとつひとつは小さくても、回数が非常に多いのでトータルで大きな転送量を減らすことに繋げることが出来ます。</p>
<h5>Minimize cookie size</h5>
<p>cookieのサイズは極力小さくしましょう。<br />
例えばユニークなIDを発行してcookieに入れ、データの中身はサーバ側で持つような工夫も有効です。</p>
<h5>Serve static content from a cookieless domain</h5>
<p>静的ファイルを大量に扱うようなサイトでは特に、リクエストに付随するcookieの転送量は馬鹿にならなくなってきます。<br />
スタティックなファイルを置く専用のドメインを用意することで、完全にcookieの送受信を無くす方法も検討しましょう。</p>
<h4 style="background-color: black; color: white;">データ本体のサイズ最小化 &#8211; Minimizing payload size</h4>
<p>静的なファイルであれ動的なファイルであれ、データ本体のサイズが通常は最も大きくなります。<br />
このサイズを減らすことは、極めて本来的・直観的にページを「軽く」することに繫がります。</p>
<h5>Enable gzip compression</h5>
<p>最近はほとんどのブラウザはgzip圧縮されたコンテンツを解凍することが出来ます。<br />
基本的にdeflateは圧縮時に比較的コストがかかり、解凍が非常に高速なアルゴリズムです。HTML、Css、Javascriptのようなテキストベースのコンテンツは特に圧縮効果が高いので、ネットワーク転送量軽減のために積極的に活用しましょう。</p>
<h5>Remove unused CSS</h5>
<p>使わないスタイル定義は削除しましょう。<br />
効率の良いスタイルを書くことは、単に転送量だけでなくパースやレンダリングの速度向上にもつながります。<br />
複数のページにまたがったスタイルシートを使う場合、ファイルをパーツに分割して必要なものだけを取り込むような工夫をしましょう。<br />
Page Speedは該当ページで使われていないスタイルを洗い出してもくれるので、最適化に役立つでしょう。<br />
<a href="/2009/06/15/css-good-7-practices/">&raquo; 効率の良いcssを書くための7箇条</a></p>
<h5>Minify JavaScript</h5>
<p>スクリプトをコーディングする際、可読性のために改行やインデントは欠かせません。しかし、そういった改行や空白をネットワーク転送し、パースする際に読み込むことはコンピュータにとっては無駄です。<br />
<a href="http://www.crockford.com/javascript/jsmin.html">JSMin</a>や<a href="http://developer.yahoo.com/yui/compressor/">YUI Compressor</a>を使い、整形用文字の除去や変数・関数名の圧縮などを行いましょう。</p>
<h5>Defer loading of JavaScript</h5>
<p>ブラウザはスクリプトが実行されるまで、ページをレンダリングせずに待機します。これは、スクリプト内でページを変更する可能性があるからです。<br />
ユーザはレンダリングが先に行われると、体感速度が上がったように感じるものです。<br />
明示的に「このJsファイルはページのレンダリングに不要」と指定することで、ブラウザの処理の順番を制御することが出来ます。</p>
<h5>Optimize images</h5>
<p>それほど画質を落とさずに画像のファイルサイズを減らすための軽減ツールや圧縮ツールも数多くあります。<br />
必要性と許容できる画質のバランスをとりながら、極力ファイルサイズを軽くするようにしていきましょう。</p>
<h5>Serve resources from a consistent URL</h5>
<p>キャッシュを有効に使うため、同じファイルは常に同じURLを使うようにしましょう。<br />
例えばa.example.comとb.example.comに同じJsファイルがあった場合、二重に置かずにb.example.comからもa.example.comを参照した方が効率が良いはずです。</p>
<h4 style="background-color: black; color: white;">ブラウザのレンダリング最適化 &#8211; Optimizing browser rendering</h4>
<p>ダウンロードが終わってからも、ページが表示されるまでにブラウザはパース、レンダリング、実行を行います。<br />
クライアント側での処理を最適化することで、ページを軽くすることが出来ます。</p>
<h5>Use efficient CSS selectors</h5>
<p>CSSの指定は基本的にセレクターを用います。しかし一概にセレクターと言っても、効率の良い指定と悪いものがあります。<br />
極力非効率なCSSセレクター指定を避ける記述を覚えましょう。<br />
<a href="/2009/06/15/css-%e3%83%9a%e3%83%bc%e3%82%b8%e3%81%ab%e3%82%b9%e3%82%bf%e3%82%a4%e3%83%ab%e3%81%8c%e3%81%82%e3%81%a6%e3%82%89%e3%82%8c%e3%82%8b%e4%bb%95%e7%b5%84%e3%81%bf%e3%82%92%e5%ad%a6%e3%81%b6/">&raquo; ページにスタイルがあてられる仕組みを学ぶ</a><br />
<a href="/2009/06/15/css-good-7-practices/">&raquo; 効率の良いcssを書くための7箇条</a></p>
<h5>Avoid CSS expressions</h5>
<p>Internet Explorer 5～7向けに、CSS Expressionを使っているサイトもあるでしょう。しかし、これはレンダリングのパフォーマンスを下げてしまいます。<br />
IEも8以降は機能自体が非推奨になることもあり、他の方法で実現できる方策を練りましょう。</p>
<h5>Put CSS in the document head</h5>
<p>body内などでstyle要素を使わないようにしましょう。<br />
可能な限りheadタグ内にlink要素を記述し、@importは使わないようにしましょう。</p>
<h5>Specify image dimensions</h5>
<p>imgタグに画像のサイズは必ず指定しましょう。<br />
サイズがわかれば、画像のダウンロードが終わる前にも正しい位置でレンダリングが可能です。</p>
<p>今後も時間があれば、ピックアップして詳しく取り上げようと思います。</p>
<p>Related posts:<ol>
<li><a href='http://screw-axis.com/2009/06/06/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%961/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(1)'>[Web] Google Page Speedでサイトを高速化(1)</a></li>
<li><a href='http://screw-axis.com/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(3)'>[Web] Google Page Speedでサイトを高速化(3)</a></li>
<li><a href='http://screw-axis.com/2009/06/07/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%962/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(2)'>[Web] Google Page Speedでサイトを高速化(2)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://screw-axis.com/2009/06/14/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%96/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[Web] Google Page Speedでサイトを高速化(4)</title>
		<link>http://screw-axis.com/2009/06/12/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%964/</link>
		<comments>http://screw-axis.com/2009/06/12/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%964/#comments</comments>
		<pubDate>Thu, 11 Jun 2009 16:42:37 +0000</pubDate>
		<dc:creator>nao58</dc:creator>
				<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://screw-axis.com/?p=462</guid>
		<description><![CDATA[パラレルダウンロードについて、更にもうひとつ。今度は、JsやCssなどのテキスト系外部ファイルだけでなく、画像なども含めた全ての外部ファイルに関する話題です。 今、皆さんが管理しているページは、画像やFlashなども含め [...]
Related posts:<ol>
<li><a href='http://screw-axis.com/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(3)'>[Web] Google Page Speedでサイトを高速化(3)</a></li>
<li><a href='http://screw-axis.com/2009/06/07/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%962/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(2)'>[Web] Google Page Speedでサイトを高速化(2)</a></li>
<li><a href='http://screw-axis.com/2009/06/06/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%961/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(1)'>[Web] Google Page Speedでサイトを高速化(1)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm1.static.flickr.com/27/57398619_b4985e17dc_m.jpg" alt="1000 arms" title="1000 arms" width="240" height="160" class="alignright size-full" style="margin-left: 5px;" />パラレルダウンロードについて、更にもうひとつ。今度は、<a href="/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/">JsやCssなどのテキスト系外部ファイル</a>だけでなく、画像なども含めた全ての外部ファイルに関する話題です。</p>
<p>今、皆さんが管理しているページは、画像やFlashなども含めた「外部ファイル」を幾つくらい必要としているでしょうか？<br />
私が今、チューニングを求められているページは、1ページ表示しようとしただけで、もろもろ含めて150以上のファイルをダウンロードしてしまいます。<br />
当然、css spriteなどでファイル数そのものを減らすことを考えなければいけませんが、それでも限界がある数です。</p>
<p>なるべく多くのファイルを、同時並行でダウンロードしてきて欲しい。こんな場合に考えなければいけないのが、<a href="http://code.google.com/intl/ja/speed/page-speed/docs/rtt.html#ParallelizeDownloads">ホスト毎に貼れるセッションの数</a>です。<br />
<span id="more-462"></span></p>
<h5>ホストごとのダウンロード数 &#8211; Parallelize downloads across hostnames</h5>
<p>ブラウザがひとつのホストとの間に同時にはれるセッション数は、2から多くても6程度です。（正確には、例によって<a href="http://stevesouders.com/ua/results.php">UA Profiler</a>参照）<br />
これは技術的な限界ではなく、<a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.4">HTTP1.1で策定された取り決め</a>です。攻撃まがいの行為を防ぐなどの目的で、ひとつのホストと同時に接続要求できるのは「2」までとされましたが、現在はハードウェアの性能やネットワークの帯域が向上したことで、もう少し多くの接続が許されるようになってきています。</p>
<p>現在の主流ブラウザを「6」とすれば、それでも6つのファイルしか同時にダウンロードすることは出来ないということになります。<br />
前述のページであれば、どんなに効率が良くても25回(150/6)分のロード時間が必要になってしまいます。<br />
これを増やすために、セッション数の制限があるのは「あるホストと」であることに注目してみましょう。</p>
<p>例えば&#8221;example.com&#8221;というサーバにあるページを表示する場合、&#8221;example.com/img&#8221;のような場所に画像を置くことが多いかと思います。<br />
しかしその場合、前述のように同時にはれるセッションは多くて6つまでです。仮に30のファイルが必要だとすれば、第5陣まで取得しなければなりません。</p>
<p>では、この画像類が&#8221;img1.example.com&#8221;,&#8221;img2.example.com&#8221;&#8230;というような、複数のホストに振り分けられていれば、どうでしょう。<br />
img1に6ファイル、img2にも6ファイルと同時にとりにいけば、30ファイルを同時並行で一斉にダウンロードすることも可能です。<br />
このような「トリック」を使うことは、サイトの高速化に非常に重要です。</p>
<p>ホストは、必ずしも物理的/IP的に異なるものである必要はありません。実体として同一の、ヴァーチャルホストなどであったとしても、ブラウザは名前が異なれば別々のホストとして認識します。</p>
<p>以下はGoogle Mapsでのタイルレイヤー画像のダウンロード状況を示してくれたグラフです。</p>
<div style="width: 100%; overflow: auto;">
<img src="http://code.google.com/intl/ja/speed/page-speed/images/paralleldownload.png" width="807" height="445" />
</div>
<p>赤枠で囲ったあたりだけでも10以上のファイルが、複数のホストから同時にダウンロードされていることが分かるでしょう。</p>
<p>但し、だからといって闇雲に増やせば良いというわけではありません。<br />
ホストとの接続には新たなTCP接続のための初期化や、名前解決のためのDNS Lookupなどの処理が必要になります。更に同時にあまりにも多くのファイルダウンロードが実行されれば、今度はクライアント端末のCPUなどが高負荷になりすぎる可能性もあります。<br />
Googleによれば、経験則上でホストの数は2～5くらいとしておくのが良いようです。</p>
<p>注意点が2点あります。</p>
<p>まず、JavaScriptファイルは多くのブラウザでパラレルダウンロードが出来ない件。<br />
このため、複数のホストにJsファイルを分散することは無意味です。ここでは、前回で説明したように<a href="/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/">スタイル等との指定順に配慮</a>したり、<a href="/2009/06/07/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%962/">外部ファイルをひとつに結合する</a>ことが、より重要です。</p>
<p>次に、あるファイルは、同じサーバから再度取得されるようにしなければならないということ。<br />
例えばランダムに、ある時は a.gif を img3 で取得し、同ファイルを次は img2 に取得しにいくようにするようなことは、決してやってはいけません。初回で見たような<a href="/2009/06/06/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%961/">ブラウザキャッシュを有効活用</a>できなくなってしまいます。</p>
<p>最後に、このトリックを用いると、静的画像のcookieヘッダの利用を制限することも容易になります。<br />
これについては、また別途。</p>
<p>Related posts:<ol>
<li><a href='http://screw-axis.com/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(3)'>[Web] Google Page Speedでサイトを高速化(3)</a></li>
<li><a href='http://screw-axis.com/2009/06/07/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%962/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(2)'>[Web] Google Page Speedでサイトを高速化(2)</a></li>
<li><a href='http://screw-axis.com/2009/06/06/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%961/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(1)'>[Web] Google Page Speedでサイトを高速化(1)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://screw-axis.com/2009/06/12/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%964/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Web] Google Page Speedでサイトを高速化(3)</title>
		<link>http://screw-axis.com/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/</link>
		<comments>http://screw-axis.com/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/#comments</comments>
		<pubDate>Thu, 11 Jun 2009 12:26:47 +0000</pubDate>
		<dc:creator>nao58</dc:creator>
				<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://screw-axis.com/?p=449</guid>
		<description><![CDATA[なかなか更新する時間がとれないですが、今回は外部ファイル取り込み時間の圧縮の続きで、パラレルダウンロードに焦点をあてます。 JsやCssなどの外部ファイルは、ブラウザによりますがパラレルに平行してダウンロードすることが可 [...]
Related posts:<ol>
<li><a href='http://screw-axis.com/2009/06/07/css-import%e3%82%92%e4%bd%bf%e3%81%86%e3%81%b9%e3%81%8d%e3%81%a7%e3%81%aa%e3%81%84%e7%90%86%e7%94%b1/' rel='bookmark' title='[css] @importを使うべきでない理由'>[css] @importを使うべきでない理由</a></li>
<li><a href='http://screw-axis.com/2009/06/14/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%96/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化'>[Web] Google Page Speedでサイトを高速化</a></li>
<li><a href='http://screw-axis.com/2009/06/07/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%962/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(2)'>[Web] Google Page Speedでサイトを高速化(2)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm3.static.flickr.com/2404/2238052867_c4e15374b9_m.jpg" alt="Pararell" title="Pararell" width="165" height="240" class="alignright size-full" style="margin-left: 5px;" />なかなか更新する時間がとれないですが、今回は<a href="/2009/06/07/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%962/">外部ファイル取り込み時間の圧縮</a>の続きで、パラレルダウンロードに焦点をあてます。</p>
<p>JsやCssなどの外部ファイルは、ブラウザによりますがパラレルに平行してダウンロードすることが可能です。1つより2つ、2つよりも更に<a href="http://code.google.com/intl/ja/speed/page-speed/docs/rtt.html#PutStylesBeforeScripts">多くのファイルを同時にダウンロードさせる</a>ことは、トータルのRTT軽減に直接役立ちます。<br />
しかし記述方法によっては、パラレルダウンロードが全く行われなくなってしまうこともあります。<br />
ダウンロードジョブを効果的に並べて、ページの表示速度を向上させる方法を見ていきましょう。<br />
<span id="more-449"></span></p>
<h5>CssやJsの並びを最適化 &#8211; Optimize the order of styles and scripts</h5>
<p>まず覚えておくべきなのは、「外部Jsファイルを取り込むページでは、そのダウンロードが終わるまで、HTMLのレンダリングやページ内のscriptタグの実行を行わない」ということです。<br />
これはスクリプトが(X)HTMLやスタイルを変更する可能性があるためです。</p>
<p>そしてRTT軽減のために更に重要なことは、<strong>「多くのブラウザは、スクリプトのダウンロードが始まると他の外部ファイルのダウンロードを待たせる」</strong>点です。<br />
一方、既にダウンロードしているファイルがあれば、ブラウザはそれと平行してスクリプトのダウンロードを開始します。</p>
<p>GoogleはPage Speedのドキュメント中で、これをわかりやすく説明する実験をしています。</p>
<p>まず、次のようなコードでページを表示します。</p>
<pre name="code" class="html">
&lt;head&gt;
&lt;link rel="stylesheet" type="text/css" href="stylesheet1.css" /&gt;
&lt;script type="text/javascript" src="scriptfile1.js" /&gt;
&lt;script type="text/javascript" src="scriptfile2.js" /&gt;
&lt;link rel="stylesheet" type="text/css" href="stylesheet2.css" /&gt;
&lt;link rel="stylesheet" type="text/css" href="stylesheet3.css" /&gt;
&lt;/head&gt;
</pre>
<p>各ファイル1つずつのダウンロードに要する時間が一律100ミリ秒だとすると、結果は次のようになります。</p>
<div style="width: 100%; overflow: auto;">
<img src="http://code.google.com/intl/ja/speed/page-speed/images/waterfall1.png" width="460" height="161" />
</div>
<p>順に見ると、まずはstylesheet1.cssのダウンロードがはじまります。次にscriptfile1.jsが参照され、平行してダウンロードします。その次はscriptfile2.jsですが、前述のようにスクリプトのダウンロードは他を待たせるため、ここで処理を止めて完了を待ちます。scriptfile1の取得完了後、scriptfile2を取り、同様にそれ以降は待たされることになります。scriptfile2が終わったところで漸く、stylesheet2.cssの取得を開始します。CSSはパラレルダウンロードが可能なため、続くstylesheet3.cssも並行して取得します。<br />
結果として、300msを要して全てのファイルを取得できました。</p>
<p>では次に、同じファイルを順番を整理してダウンロードしてみます。</p>
<pre name="code" class="html">
&lt;head&gt;
&lt;link rel="stylesheet" type="text/css" href="stylesheet1.css" /&gt;
&lt;link rel="stylesheet" type="text/css" href="stylesheet2.css" /&gt;
&lt;link rel="stylesheet" type="text/css" href="stylesheet3.css" /&gt;
&lt;script type="text/javascript" src="scriptfile1.js" /&gt;
&lt;script type="text/javascript" src="scriptfile2.js" /&gt;
&lt;/head&gt;
</pre>
<p>Cssと最初のJsはパラレルにダウンロードされるので、トータルの所要時間は200msとなります。</p>
<div style="width: 100%; overflow: auto;">
<img src="http://code.google.com/intl/ja/speed/page-speed/images/waterfall2.png" width="346" height="170" />
</div>
<p>このように、何気なく配置しているかもしれないhead要素内のファイルの並び順も、ページの表示速度に大きく影響します。<br />
これはscriptタグ内に書かれるインラインコードでも同様で、例えば次のような記述では、スタイルシートのパラレルダウンロードが分断されてしまいます。</p>
<pre name="code" class="html">
&lt;head&gt;
&lt;link rel="stylesheet" type="text/css" href="stylesheet1.css" /&gt;
&lt;script type="text/javascript"&gt;
 document.write("Hello world!");
&lt;/script&gt;
&lt;link rel="stylesheet" type="text/css" href="stylesheet2.css" /&gt;
&lt;link rel="stylesheet" type="text/css" href="stylesheet3.css" /&gt;
&lt;link rel="alternate" type="application/rss+xml" href="front.xml" title="Say hello" /&gt;
&lt;link rel="shortcut icon" type="image/x-icon" href="favicon.ico"&gt;
&lt;/head&gt;
</pre>
<p>これらを踏まえ、次のような基本ルールでのぞみましょう。</p>
<ul>
<li><strong>外部スクリプトは、外部スタイルシートの後に読み込む</strong><br />
可能な限り、この順番を守るべきです。仮にスクリプトが実行された結果をうけてはじめて結果が変わるようなスタイルの設定をしない限り、このルールを徹底させましょう。</li>
<li><strong>インラインスクリプトは、外部ファイルの指定後に記述する</strong><br />
これも可能な限り、このルールで書くべきです。<br />
但し、外部スクリプトがインラインスクリプトの記述いかんで動作を変えるような場合、これが難しいこともあるでしょう。その場合は逆に、インラインスクリプトをスタイルシートも含めた全ての外部ファイル指定の<strong>前に</strong>持っていくべきです。</li>
</ul>
<p>但し、ここまで見てきた「スタイルシートはパラレルダウンロード可能」「スクリプトは他のファイルのダウンロードを待たせる」といった動作は、あくまで「現時点での多くのブラウザで」という注釈がつきます。<br />
<a href="http://stevesouders.com/ua/results.php">UA Profiler</a>などで確認すれば、Chrome2やFF3.1、IE8などの最新ブラウザでは、スクリプトのパラレルダウンロードもサポートしはじめています。<br />
こういったブラウザが主流になってくれば、ここで挙げたセオリーも変わってくるでしょう。<br />
しかしそれまでは、高速なサイトを作るためには、こういったことへも意識を保っておくことが重要です。</p>
<p>Related posts:<ol>
<li><a href='http://screw-axis.com/2009/06/07/css-import%e3%82%92%e4%bd%bf%e3%81%86%e3%81%b9%e3%81%8d%e3%81%a7%e3%81%aa%e3%81%84%e7%90%86%e7%94%b1/' rel='bookmark' title='[css] @importを使うべきでない理由'>[css] @importを使うべきでない理由</a></li>
<li><a href='http://screw-axis.com/2009/06/14/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%96/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化'>[Web] Google Page Speedでサイトを高速化</a></li>
<li><a href='http://screw-axis.com/2009/06/07/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%962/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(2)'>[Web] Google Page Speedでサイトを高速化(2)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://screw-axis.com/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[css] @importを使うべきでない理由</title>
		<link>http://screw-axis.com/2009/06/07/css-import%e3%82%92%e4%bd%bf%e3%81%86%e3%81%b9%e3%81%8d%e3%81%a7%e3%81%aa%e3%81%84%e7%90%86%e7%94%b1/</link>
		<comments>http://screw-axis.com/2009/06/07/css-import%e3%82%92%e4%bd%bf%e3%81%86%e3%81%b9%e3%81%8d%e3%81%a7%e3%81%aa%e3%81%84%e7%90%86%e7%94%b1/#comments</comments>
		<pubDate>Sun, 07 Jun 2009 07:04:25 +0000</pubDate>
		<dc:creator>nao58</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[css]]></category>

		<guid isPermaLink="false">http://screw-axis.com/?p=415</guid>
		<description><![CDATA[実は以前に別の場所でも書いたのですが、今回Google Page Speedの方でも少しだけ触れられていたので、改めてまとめ。 自分でも経験があることなのですが、開発をやっているとどうしても、構造をモジュール化して複数の [...]
Related posts:<ol>
<li><a href='http://screw-axis.com/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(3)'>[Web] Google Page Speedでサイトを高速化(3)</a></li>
<li><a href='http://screw-axis.com/2011/02/16/responsive-layout1/' rel='bookmark' title='[Design] Responsive Layoutを学ぶ(1)'>[Design] Responsive Layoutを学ぶ(1)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm3.static.flickr.com/2132/2198945946_0a50cabb6b_m.jpg" alt="Stop Import" title="Stop Import" width="240" height="180" class="alignright size-full" style="margin-left: 5px;" />実は以前に別の場所でも書いたのですが、今回<a href="/2009/06/07/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%962/">Google Page Speedの方</a>でも少しだけ触れられていたので、改めてまとめ。</p>
<p>自分でも経験があることなのですが、開発をやっているとどうしても、構造をモジュール化して複数のファイルに分割して管理したくなります。<br />
StyleSheetにおいても同様で、プレゼンテーション層のコンポーネントにあわせてCSSを用意し、ページ構成にあわせて取り込むようなことをやりたくなるでしょう。</p>
<p>しかしその際、@import構文を使うのはパフォーマンスと挙動の両方に有害である可能性が高いと、「<a href="http://www.amazon.co.jp/gp/product/487311361X?ie=UTF8&#038;tag=paiitbla-22&#038;linkCode=as2&#038;camp=247&#038;creative=1211&#038;creativeASIN=487311361X">ハイパフォーマンスWebサイト ―高速サイトを実現する14のルール</a>」の著者としても知られるSteve Souders氏が<a href="http://www.stevesouders.com/blog/2009/04/09/dont-use-import/">警鐘を鳴らして</a>います。<br />
<span id="more-415"></span></p>
<h5>使うべきでないポイント</h5>
<p>@importは、大きく分けて2つの観点で「使うべきでない」とされています。</p>
<p>ひとつは、パフォーマンスの問題。StyleSheetは<a href="http://stevesouders.com/ua/results.php">ほぼ全ての主要ブラウザでパラレルロードがサポート</a>されています。これにより、例えば取得に1秒かかるファイルを3つ使うにも、3ファイルを平行して取得できるのでトータル1秒で済みます。<br />
しかし、@importを使うことで、パラレルにダウンロードが出来なくなるケースがあります。その結果、3つのファイルは順に取得され、計3秒かかることになってしまいます。</p>
<p>次に、挙動の問題。こちらはある意味、パフォーマンスよりも深刻です。<br />
ある条件下で@importを使うと、CSSの読み込み順序が変わってしまうことがあります。スタイルシートは読み込まれる順番によって適用スタイルの優先度が変わるため、結果として「ある特定のブラウザで、挙動が変わることがある」という非常に再現性の悪い不具合を内包させてしまうことになってしまいます。</p>
<h5>検証1: @import x 2</h5>
<p>まず、a.cssとb.cssという2つの外部ファイルを、HTML内で直接、共に@importで取り込む場合の検証をしてみましょう。</p>
<pre name="code" class="html">
&lt;style&gt;
  @import url('a.css');
  @import url('b.css');
&lt;/style&gt;
</pre>
<p>この方法であれば、2つのCSSは並行してダウンロードされ、パフォーマンスの問題は発生しません。<br />
# 後述するように、JavaScriptとあわせた場合にエラーの原因となる可能性はありますが。<br />
<img src="http://stevesouders.com/tests/atimport/import-import.gif" alt="figure1" title="figure1" width="200" height="40" class="size-full" /></p>
<h5>検証2: linkと@import</h5>
<p>次に、HTMLでa.cssをlinkで、b.cssをインラインstyle要素の@importで呼び出すようにしてみます。</p>
<pre name="code" class="html">
&lt;link rel='stylesheet' type='text/css' href='a.css' /&gt;
&lt;style&gt;
  @import url('b.css');
&lt;/style&gt;
</pre>
<p>この場合、Internet Explorerの6～8では、次のようにシーケンシャルにダウンロードされるようになってしまいます。<br />
<img src="http://stevesouders.com/tests/atimport/link-import.gif" alt="figure2" title="figure2" width="400" height="40" class="size-full" /><br />
結果、パフォーマンスの劣化を招きます。</p>
<h5>検証3: link中で@import</h5>
<p>a.cssをlinkで呼び出し、その中でb.cssを@importで呼んでいた場合はどうでしょうか。</p>
<p>[HTML]</p>
<pre name="code" class="html">
&lt;link rel='stylesheet' type='text/css' href='a.css' /&gt;
</pre>
<p>[a.css]</p>
<pre name="code" class="css">
@import url('b.css');
</pre>
<p>この場合、ブラウザはまずa.cssを読み込み、次にようやくb.cssを取り込むことを通知されます。<br />
結果、先ほどの例のようにIEだけでなく、全てのブラウザでシーケンシャルロードになってしまいます。<br />
<img src="http://stevesouders.com/tests/atimport/link-with-import.gif" alt="figure3" title="figure3" width="400" height="40" class="size-full" /></p>
<h5>検証4: linkブロック中で@import</h5>
<p>では、少し変えて、今度は非常に軽量なc.cssを用意してみます。そしてc.cssが@importでb.cssを読み込みます。a.cssとc.cssをlinkで読み込んでみると、どうなるでしょうか。<br />
[HTML]</p>
<pre name="code" class="html">
&lt;link rel='stylesheet' type='text/css' href='a.css' /&gt;
&lt;link rel='stylesheet' type='text/css' href='c.css' /&gt;
</pre>
<p>[c.css]</p>
<pre name="code" class="css">
@import url('b.css');
</pre>
<p>実行前に少し考えてみましょう。まず、a.cssとc.cssは並行して読み込まれるはずです。そして非常に小さなc.cssを読み込んだところで、b.cssの読み込みが始まります。トータルでかかる時間は、c.css+b.cssになると予想されます。</p>
<p>結果は、次のようなものでした。2行目から順にa, c, bの読み込みを表します。<br />
<img src="http://stevesouders.com/tests/atimport/link-blocks-import-not-ie.gif" alt="figure5" title="figure5" width="210" height="54" class="size-full" /><br />
予測した通りの結果です。</p>
<p>ところが、同じコードをIEで実行すると、次のようになってしまいます。<br />
<img src="http://stevesouders.com/tests/atimport/link-blocks-import.gif" alt="figure4" title="figure4" width="400" height="54" class="size-full" /><br />
a.cssとc.cssは平行してダウンロードされていますが、a.cssのダウンロードが終わるまでb.cssの取得が開始されていません。<br />
どうやらIEでは、パラレルダウンロードされるファイルの最も遅いものに引き摺られてしまうようです。</p>
<h5>検証5: 大量の@importとscript</h5>
<p>今度は、検証1で少し触れた@importとscriptの組み合わせを試してみます。</p>
<pre name="code" class="html">
&lt;style&gt;
  @import url('a.css');
  @import url('b.css');
  @import url('c.css');
  @import url('d.css');
  @import url('e.css');
  @import url('f.css');
&lt;/style&gt;
&lt;script src='one.js' type='text/javascript'&gt;&lt;/script&gt;
</pre>
<p>IEでの実行結果を見てください。<br />
<img src="http://stevesouders.com/tests/atimport/many-imports.gif" alt="figure6" title="figure6" width="400" height="110" class="size-full" /><br />
上から2行目の、最も長いのがone.jsのダウンロードです。<br />
この例のようにスクリプトタグを一番最後に書いても、IEでは真っ先にダウンロードが始まってしまいます。<br />
このため、このスクリプトがスタイルが当たっていることを前提としている場合（cssによって指定される位置や色、形状などを元にしたエフェクトなど）、予期しない動作を招いてしまう可能性があります。</p>
<h5>検証6: link x 2</h5>
<p>linkだけを並べたケースは、最も問題が起きにくい優れた記述です。</p>
<pre name="code" class="html">
&lt;link rel='stylesheet' type='text/css' href='a.css' /&gt;
&lt;link rel='stylesheet' type='text/css' href='b.css' /&gt;
</pre>
<p>検証5で既に部分的に見ていることですが、IEであっても期待通りに平行してダウンロードが行われます。<br />
<img src="http://stevesouders.com/tests/atimport/import-import.gif" alt="figure7" title="figure7" width="200" height="40" class="size-full" /></p>
<h5>検証7: linkと@imporブロック</h5>
<p>では、linkを並べる形をとれば、その中で@importをネストしても大丈夫なのでしょうか？<br />
a.cssとb.cssを並べて読み込み、a.cssからは多くの他のファイルを@importで読み込むようにしてみます。</p>
<pre name="code" class="html">
&lt;link rel='stylesheet' type='text/css' href='a.css' /&gt;
&lt;link rel='stylesheet' type='text/css' href='b.css' /&gt;
</pre>
<p>[b.css]</p>
<pre name="code" class="css">
@import url('c.css');
@import url('d.css');
@import url('e.css');
@import url('f.css');
</pre>
<p><img src="http://stevesouders.com/tests/atimport/link-with-imports.gif" alt="figure8" title="figure8" width="400" height="96" class="size-full" /><br />
期待通りにa.cssの読み込みが終わったところで、他のファイルのダウンロードが始まっています。</p>
<h5>検証8: 大量のlinkとscript</h5>
<p>最後に、検証5で問題だったスクリプトとの実行順序を確認します。</p>
<pre name="code" class="html">
&lt;link rel='stylesheet' type='text/css' href='a.css' /&gt;
&lt;link rel='stylesheet' type='text/css' href='b.css' /&gt;
&lt;link rel='stylesheet' type='text/css' href='c.css' /&gt;
&lt;link rel='stylesheet' type='text/css' href='d.css' /&gt;
&lt;script src='one.js' type='text/javascript'&gt;&lt;/script&gt;
</pre>
<p>IEで検証しても、期待通りの動作をします。<br />
<img src="http://stevesouders.com/tests/atimport/many-links.gif" alt="figure9" title="figure9" width="400" height="82" class="size-full" /></p>
<h5>まとめ</h5>
<ul>
<li>スタイルシートから他のスタイルシートを読み込むことは、どんな方法であれ2つのCSSのロードをシーケンシャルに行わせることになります。</li>
<li>インラインで@importを使うことは、IEではパフォーマンスの劣化と異常動作を招くことになります。</li>
</ul>
<p>以上のことから、可能な限り@importは用いず、linkを使ってパラレルに読み込むことが最も推奨されます。<br />
既に稼動しているシステムで使ってしまっている場合、急に変更することは難しいと思いますが、せめてHTMLからの呼び出しは全てlinkに統一しておきましょう。</p>
<p>Related posts:<ol>
<li><a href='http://screw-axis.com/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(3)'>[Web] Google Page Speedでサイトを高速化(3)</a></li>
<li><a href='http://screw-axis.com/2011/02/16/responsive-layout1/' rel='bookmark' title='[Design] Responsive Layoutを学ぶ(1)'>[Design] Responsive Layoutを学ぶ(1)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://screw-axis.com/2009/06/07/css-import%e3%82%92%e4%bd%bf%e3%81%86%e3%81%b9%e3%81%8d%e3%81%a7%e3%81%aa%e3%81%84%e7%90%86%e7%94%b1/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>[Web] Google Page Speedでサイトを高速化(2)</title>
		<link>http://screw-axis.com/2009/06/07/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%962/</link>
		<comments>http://screw-axis.com/2009/06/07/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%962/#comments</comments>
		<pubDate>Sun, 07 Jun 2009 02:39:19 +0000</pubDate>
		<dc:creator>nao58</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://screw-axis.com/?p=400</guid>
		<description><![CDATA[前回のブラウザキャッシュの最適化に引き続き、今回は外部ファイルの取り込み時間の圧縮をやってみましょう。 最近立ち上げたサイトはこの辺の対応もしっかりしているのですが、ちょっと昔に作った管理サイトを見てみると、上位に要対応 [...]
Related posts:<ol>
<li><a href='http://screw-axis.com/2009/06/14/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%96/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化'>[Web] Google Page Speedでサイトを高速化</a></li>
<li><a href='http://screw-axis.com/2009/06/12/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%964/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(4)'>[Web] Google Page Speedでサイトを高速化(4)</a></li>
<li><a href='http://screw-axis.com/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(3)'>[Web] Google Page Speedでサイトを高速化(3)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm4.static.flickr.com/3539/3289409532_5037fdca3d_m.jpg" alt="Serve" title="Serve" width="160" height="240" class="alignright size-full" style="margin-left: 5px;" />前回の<a href="/2009/06/06/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%961/">ブラウザキャッシュの最適化</a>に引き続き、今回は<a href="http://code.google.com/intl/ja/speed/page-speed/docs/rtt.html">外部ファイルの取り込み時間の圧縮</a>をやってみましょう。</p>
<p>最近立ち上げたサイトはこの辺の対応もしっかりしているのですが、ちょっと昔に作った管理サイトを見てみると、上位に要対応とされたのが実はこの2つ。</p>
<p>CSSやJsなど、ページがリッチになっていくにつれて取り込む外部ファイルも増えていきます。これらを小さくまとめて転送量を減らす工夫をすることは、ちょうどバイキングで何度も取りに行くよりも、一度に山盛りに盛ってきた方が効率が良いようなものです。<br />
（そもそも、量を減らすことも考えなければいけませんが）<br />
<span id="more-400"></span></p>
<h5>外部JavaScriptの結合 &#8211; Combine external JavaScript</h5>
<p>開発をやる人ならわかると思いますが、Javascriptを記述する場合も、きちんとモジュール化すればファイルは多くなってしまうものです。例えばjQueryでサイトを作る場合、coreに加えてuiやpluginsを組み合わせていけば、すぐに10くらいのjsファイルを使うことになってしまいます。<br />
開発効率やメンテナンス性を考えれば間違いなくそうすべきなのですが、実際にページをブラウザで表示する段になると、細かいダウンロードが大量に発生することになってしまいます。</p>
<p>ここで、Google Page Speedでは<a href="http://code.google.com/intl/ja/speed/page-speed/docs/rtt.html#CombineExternalJS">1つの例を示して</a>います。</p>
<div style="width: 100%; overflow: auto;">
<img src="http://code.google.com/intl/ja/speed/page-speed/images/externaljs1.png" width="930" height="238" />
</div>
<p>これは13個の異なった.jsファイルを使ったページをFirefox 3.0系のブラウザで取り込んだ様子を、FirebugのNetパネルで観察したものです。<br />
各ファイルの総量は729KB。それらが全てロードされるのに要した時間は、4.46秒となっています。Javascriptだけで約5秒かかるページを、我慢強く見てくれるユーザは多くは無いでしょう。<br />
見て分かるように、ブラウザは複数のファイルをひとつひとつ順に、シーケンシャルにロードしています。これは、Firefox3.0がJsのパラレルダウンロードをサポートしていないためです。ひとつのファイルを読み込み、パースし、次のファイルを読むということを、13回繰り返しているのです。<br />
最新のブラウザでは、これらを並列に行うことができるものも出てきています。<a href="http://stevesouders.com/ua/results.php">UA Profiler</a>の「|| Scripts」の列に「yes」とあるものがパラレルダウンロード対応のブラウザですが、まだまだ数が少ないことがわかると思います。</p>
<p>Googleの実験では次に、先ほどの13ファイルを2つのファイルに結合してリロードしています。</p>
<div style="width: 100%; overflow: auto;">
<img src="http://code.google.com/intl/ja/speed/page-speed/images/externaljs2.png" width="755" height="86" />
</div>
<p>結合というのは、つまり単純に並べただけです。特別な圧縮処理などは行われておらず、ファイルの総量は729KBで変わっていませんが、所要時間は1.87秒に激減しています。<br />
これは、各ファイルをロードする際にはリクエスト/レスポンスヘッダが転送されている分が無くなっているために実際には転送量が減っているためでもありますし、パケットやレンダリングエンジンの効率など要因は様々ですが、端的に「何度も取りに行くよりも、一度にたくさん持ってきた方が早い」と思っておけば良いでしょう。</p>
<p>但し、全てを単純にひとつにまとめれば良いというわけにもいかない、幾つかの要因があります。</p>
<ol>
<li><strong>defer loading</strong><br />
そのJsファイルの実行がページの見栄えに影響を与えない場合、defer属性をつけておけば、ブラウザはスクリプトのパースを後回しにしてHTMLをレンダリングします。これはユーザの体感速度を大きく向上させます。<br />
複数のJsファイルを、deferで呼べるものとそうでないものに分けられるならば、それぞれのグループでまとめるべきです。</li>
<li><strong>プラグインのバージョン</strong><br />
あるプラグインやモジュールに異なったバージョンが存在し、ページによって使い分けたいような場合は、そのファイルを別にしておきたいでしょう。</li>
<li><strong>結合できない種類のファイル</strong><br />
例えば効果測定用や広告表示用のスクリプトなど、このようにコントロールできないファイルもあると思います。</li>
</ol>
<p>これらのことを鑑み、Googleでは出来れば2つ、多くて3つのファイルにまとめることを推奨しています。</p>
<p>まとめとして、JavaScript結合のちょっとしたルールを次のように定めるよう推奨されています。</p>
<ul>
<li>JavaScriptは2つのファイルに分ける。1つはページのレンダリング開始前にロードされていることが必要な、最低限のスクリプトをまとめたもの。もうひとつは、ページのロードが終わってから取り込まれれば良いファイル群。</li>
<li>head要素内に書かれるスクリプトファイルは可能な限り少なく、小さなサイズにする。</li>
<li>滅多に使われないファイルはそのまま持ち、リクエストがあった場合のみ取り込む。</li>
<li>キャッシュされたくない種類の小さなスクリプト（効果測定や広告など）は、外部ファイルではなくHTML内に直接記述することを検討する。</li>
</ul>
<p>最後に、スクリプトと他の外部ファイルがロードされる順番にも注意を払わなければなりません。<br />
これについては、別途説明します。</p>
<h5>外部CSSの結合 &#8211; Combine external CSS</h5>
<p>外部CSSに関しても、前項のJs同様にひとまとめにすることでRTT(Round Trip Time)を軽減できます。</p>
<p>概要はJsとほぼ同じなので省きますが、UA Profilerを見ればわかるように、CSSの方がJsに比べてパラレルダウンロードに対応されています。<br />
そのため比較的まとめ効果は出にくい面もありますが、逆にそれを活かすために注意すべき点もあります。<br />
最も重要な点は、<strong>@importを使わないこと</strong>。これについては、Google Page Speed上には詳しい説明が無いので、別途説明しようと思います。<br />
→しました。「<a href="/2009/06/07/css-import%e3%82%92%e4%bd%bf%e3%81%86%e3%81%b9%e3%81%8d%e3%81%a7%e3%81%aa%e3%81%84%e7%90%86%e7%94%b1/">CSSで@importを使ってはいけない理由</a>」</p>
<p>Related posts:<ol>
<li><a href='http://screw-axis.com/2009/06/14/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%96/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化'>[Web] Google Page Speedでサイトを高速化</a></li>
<li><a href='http://screw-axis.com/2009/06/12/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%964/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(4)'>[Web] Google Page Speedでサイトを高速化(4)</a></li>
<li><a href='http://screw-axis.com/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(3)'>[Web] Google Page Speedでサイトを高速化(3)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://screw-axis.com/2009/06/07/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%962/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[Web] Google Page Speedでサイトを高速化(1)</title>
		<link>http://screw-axis.com/2009/06/06/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%961/</link>
		<comments>http://screw-axis.com/2009/06/06/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%961/#comments</comments>
		<pubDate>Sat, 06 Jun 2009 09:15:36 +0000</pubDate>
		<dc:creator>nao58</dc:creator>
				<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://screw-axis.com/?p=360</guid>
		<description><![CDATA[つい先日Googleから公開されたPage Speedは、彼らが社内で使っていたページを高速化するためのチェックツールです。Yahoo! YSlowのGoogle版と思えば良いのだと思います。 これらはあくまで「チェック [...]
Related posts:<ol>
<li><a href='http://screw-axis.com/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(3)'>[Web] Google Page Speedでサイトを高速化(3)</a></li>
<li><a href='http://screw-axis.com/2009/06/07/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%962/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(2)'>[Web] Google Page Speedでサイトを高速化(2)</a></li>
<li><a href='http://screw-axis.com/2009/06/12/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%964/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(4)'>[Web] Google Page Speedでサイトを高速化(4)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>つい先日Googleから公開された<a href="http://code.google.com/intl/ja/speed/page-speed/docs/using.html">Page Speed</a>は、彼らが社内で使っていたページを高速化するためのチェックツールです。<a href="http://developer.yahoo.com/yslow/">Yahoo! YSlow</a>のGoogle版と思えば良いのだと思います。</p>
<p>これらはあくまで「チェック」ツールなので、診断結果を自分で最適化しなければなりません。<br />
YSlowでも「へー、知らなかった」と思うチェックポイントが幾つかありましたが、今回も考えていなかったようなポイント、知っていたものの徹底していなかった点などがあったので、そういった部分を中心に、自分の経験も踏まえてメモ。</p>
<p>まずは基本の「キ」である、ブラウザキャッシュについて。<br />
<span id="more-360"></span></p>
<h5>ブラウザキャッシュの利用 &#8211; Leverage browser caching</h5>
<p>基本的なことで忘れられがちですが、やはりブラウザキャッシュは最も効果的な高速化策のひとつです。<br />
特にほとんど変更されない画像やCSS、Js、PDFなどの静的なコンテンツにはとても有効です。<br />
また、HTMLファイルを静的コンテンツとみなすことも可能ですが、内実としては動的に作られていることも多く、細かな変更や修正も入るために一般的にはブラウザキャッシュはさせない方が良いでしょう。</p>
<p>ブラウザキャッシュを有効にする方法は、大きく分けると次の2種類があります。</p>
<ul>
<li><strong>Expire</strong>と<strong>Cache-Control: max-age</strong><br />
これらのヘッダで提供されるキャッシュは、最新ファイルの確認すら行わないので、非常に高速です。一方で当然ながら、サーバ側で更新があってもクライアント側でそれが反映されません。</li>
<li><strong>Last-Modified</strong>と<strong>ETag</strong><br />
こちらはExpireなどに比べれば弱いキャッシュで、ブラウザは2回目以降のリクエストでサーバにLast-ModifiedやETagを送信します。サーバ側ではこれらのリクエストが送られてくると手元のファイルと比較し、ブラウザが現在キャッシュしているコンテンツを使えば良いと判断した場合はステータス304を返し、コンテンツの内容は送信しません。これにより、サーバ側のディスクIOやネットワークトラフィックを軽減することができます。</li>
</ul>
<p>これに対して、推奨される対応は次のようなものです。</p>
<ul>
<li><strong>全ての静的コンテンツにキャッシュ用ヘッダをつける</strong><br />
Googleは最低でも1ヶ月、出来れば1年以上の期間、ブラウザキャッシュを有効にするよう推奨しています。<br />
これは、特にCSSやJsのようなファイルに対しては抵抗がある人も居ると思います。レイアウトが大きく狂ったり、スクリプトエラーが発生することを嫌って、全くキャッシュを効かないようにしているサイトもあるでしょう。<br />
しかし、そういった場合でもfingerprintアルゴリズムなどを使って、ファイル名が変わるような対処をすべきとしています。<br />
また、そのようにキャッシュを増やすとブラウザ側を汚してしまう懸念もありますが、通常は使われていないキャッシュは削除されていく仕組みがあるので、問題にはならないはずということです。</li>
<li><strong>fingerprintingを使った動的キャッシュ</strong><br />
ファイルが変更されるまで変わらないURLを用意してやれば、キャッシュ期間を大きくとってしまうことができます。<br />
サーバ側でファイルが変更された場合にURLを変更（当然、呼び出す側のHTMLのscriptやlinkタグも変える）すれば、自動的にブラウザは新しいファイルを要求してきます。<br />
この仕組みをどのように管理サイトに組み込むかは、各サイトの作り方によって工夫が必要です。<br />
多少は運用が難しくなりますが、これを実装すればETagなどによる毎回の確認も不要になるので、トライする価値は大きなものがあります。</li>
<li><strong>VaryヘッダをInternet Explorer対応</strong><br />
Proxyサーバでのキャッシュを制御するためのVaryヘッダがありますが、IEでは問題があり、Accept-EncodingとUser-Agent以外のヘッダを指定するとブラウザで一切のキャッシュが行われなくなります。<br />
Varyヘッダから他のフィールドを全て除去するか、Varyヘッダそのものを外してしまう必要があります。</li>
<li><strong>Firefoxでのキャッシュ衝突に注意</strong><br />
Firefoxのキャッシュファイル生成ロジックでは、<a href="http://stackoverflow.com/questions/664729/firefox-cache-hash-key-generation-algorithm-bug">パスの前後4文字ずつの計8文字しか使われません</a>。そのため、比較的容易にハッシュ値が衝突してしまう可能性があります。前述のfingerprintingやアプリケーションでURLをジェネレートするような場合、この8文字ラインが異なるようにする必要があります。</li>
<li><strong>複数サーバでのETag作成方法</strong><br />
ETagを用いる場合に、複数のWebサーバをロードバランシングしている環境では注意が必要です。多くのWebサーバではデフォルトの設定でETagの生成にi-nodeを用いるために、各サーバで同一ファイルに異なったETagをジェネレートします。結果、ラウンドロビンで割り振るとETagが全く役に立たない（転送量と確認が増える分だけ、むしろボトルネックになる）ようなことになります。そういった環境ではNASなどを用いてソースファイルを共有しているのでない限り、ETagの生成にはinodeではなくmtimeなどを利用するように設定すべきです。</li>
</ul>
<p>これらの設定をApacheなどで行うドキュメントは山ほどあると思いますので、必要なら探してみてください。<br />
このサイトではlighttpdを用いているので、せっかくですから<a href="/2009/06/06/lighttpd-expireとcompressでサイトを高速化/">lightyでのExpire設定方法</a>を別途簡単に説明しておきます。</p>
<p>Related posts:<ol>
<li><a href='http://screw-axis.com/2009/06/11/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%963/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(3)'>[Web] Google Page Speedでサイトを高速化(3)</a></li>
<li><a href='http://screw-axis.com/2009/06/07/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%962/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(2)'>[Web] Google Page Speedでサイトを高速化(2)</a></li>
<li><a href='http://screw-axis.com/2009/06/12/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%964/' rel='bookmark' title='[Web] Google Page Speedでサイトを高速化(4)'>[Web] Google Page Speedでサイトを高速化(4)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://screw-axis.com/2009/06/06/web-google-page-speed%e3%81%a7%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e9%ab%98%e9%80%9f%e5%8c%961/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

