Google推奨のブラウザレンダリングに関する4つのベストプラクティス
Googleが推奨する、ブラウザレンダリングに関する4つのベストプラクティスについて紹介します。
この記事は「Optimize browser rendering」を参考に書き起こしたものです。
元記事は2012年3月28日に更新されたものです。記事には5つの項目がありますが、残りの1つは情報がやや古いようなので割愛しました。
解釈が間違っている部分がありましたらどこかでつぶやいてください。
1.CSSセレクタを効率的に使用する
基本として、CSSのレンダリングは、記述されたセレクタについて、一番右端のセレクタ(キーセレクタ)から開始し、右から左方向に評価します。
で、多くの要素に一致するような非効率的なキーセレクタを避けることで、ページのレンダリングをスピードアップできるようです。
以下の子孫セレクタは非効率な例です。
キーセレクタがユニバーサルセレクタの子孫セレクタ
body * { ... }
.hide-scrollbars * { ... }
キーセレクタが要素セレクタの子孫セレクタ
ul li a { ... }
#footer h3 { ... }
* html #atticPromo ul li a { ... }
非効率な理由は、ブラウザは各要素に対して一致するか、ルート要素に到達するまでDOMツリーをトラバースして評価する必要があるためです。
次の子セレクタも同様の理由で非効率ですが、子孫セレクタよりはましなようです。
キーセレクタがユニバーサルセレクタの子セレクタ
body > * { ... }
.hide-scrollbars > * { ... }
キーセレクタが要素セレクタの子セレクタ
ul > li > a { ... }
#footer > h3 { ... }
また冗長なセレクタも不必要に評価されてしまいます。IDセレクタを利用する場合、要素セレクタを指定する必要はありません。
ul#top_blue_nav { ... }
form#UserLogin { ... }
非リンク要素への擬似セレクタは、IE7/8でレンダリング速度が落ちるようです。
h3:hover { ... }
.foo:hover { ... }
#foo:hover { ... }
div.faa :hover { ... }
1項のまとめです。
- ユニバーサルキーセレクタを避ける
- 子セレクタや子孫セレクタを避ける
- 冗長な修飾は行わない
- クラスセレクタやIDセレクタを使用する
ただし劇的に速度が上がる訳ではないようなので、既存のCSSを修正する場合は費用対効果を考えた方がよさそうです。
その他、本項では「未使用のCSSを削除すればパフォーマンスが改善する」とも書かれています。
2.CSSをHTMLドキュメントの最初の方に配置する
CSSのlink要素はhead要素の中の上部に記述します。
理由は、ブラウザはすべての外部スタイルシートがダウンロードされるまで、Webページをレンダリングブロックするためです。
スタイルシートを最初にダウンロード・解析されることで、ブラウザは徐々にページをレンダリングできます。
なお、CSSのlink要素を並べて記述すればパラレルに取得できます。以下は「Minimize round-trip times」からの引用です。
良い例
<head>
<link rel="stylesheet" type="text/css" href="stylesheet1.css" />
<link rel="stylesheet" type="text/css" href="stylesheet2.css" />
<link rel="stylesheet" type="text/css" href="stylesheet3.css" />
<script type="text/javascript" src="scriptfile1.js" />
<script type="text/javascript" src="scriptfile2.js" />
</head>
レンダリング動作
悪い例
<head>
<link rel="stylesheet" type="text/css" href="stylesheet1.css" />
<script type="text/javascript" src="scriptfile1.js" />
<script type="text/javascript" src="scriptfile2.js" />
<link rel="stylesheet" type="text/css" href="stylesheet2.css" />
<link rel="stylesheet" type="text/css" href="stylesheet3.css" />
</head>
レンダリング動作
また、@importを併用すると、パラレルに取得できるCSSがパラレルに取得できなくなる可能性があるため、「Don't use」と書かれています。
その他、style要素はhead要素に記述しないとレンダリングに影響があるように書かれています(そもそもstyle要素はHTML仕様でhead要素に記述することになっているので、body要素に記述したケースを想定して書かれているのかもしれません)。
2項のまとめです。
- CSSのlink要素はhead要素の最初の方に記述する
- @import文を使用しない
- 複数のCSSのlink要素は並べて記述する
- style要素はhead要素に配置する
3.画像のサイズを指定する
画像を表示するとき、画像のサイズ(幅と高さ)を指定することでレンダリングのパフォーマンスが向上します。
理由は、サイズを指定することで、ブラウザは画像のダウンロード前にレイアウトを算出することができ、ページ表示にかかる時間を短縮できるためです。
指定するのは、img要素のwidth属性とheight属性または、img要素の親ブロックレベル要素のいずれかです。
<img src="..." width="60" height="60" alt="..." />
または
<style>
.image {
width: 60px;
height: 60px;
}
</style>
...
<div class="image"><img src="..." alt="..." /></div>
親ブロックレベル要素に指定する場合、直接の親要素ではない要素に指定しないでください。
また、指定する場合は、画像と一致するサイズを指定します。サイズを拡大・縮小するサイズを指定するとパフォーマンスが劣化します。
3項のまとめです。
- 画像と同じサイズを指定する
- サイズは、img要素または直接の親ブロックレベル要素に指定する
4.キャラクタセット(文字セット)を指定する
当たり前すぎる内容なのであまり言及されている記事がありませんが、HTML文書にmeta要素でキャラクタセット(文字セット)を指定することで、HTMLと実行スクリプトの構文解析をすぐに開始することができます。
<meta charset="UTF-8" />
キャラクタセットの指定が必要な理由は、ブラウザが画面上へレンダリングする際に文字エンコード情報を使用するためです。
ほとんどのブラウザでは、キャラクタセットを検索しながら任意のJavaScriptを実行したり、ページを描画する前に、特定のバイト数をバッファリングします(Internet Explorer6/7/8は例外)。
レンダリングに必要なバイト数をバッファリングしたあと、デフォルトと一致しないキャラクタセットがみつかった場合、ページをレンダリングするために、ブラウザは入力を再解析してページを再描画する必要があり、この部分でパフォーマンスへの影響が発生します。
- YouTube動画にキャプションをつけてテキストを回り込ませる方法
- 画像を下揃えにしてテキストを回り込ませる方法
- style要素にCSSの擬似要素は記述可能か?
- position:relativeを設定すると他の要素がずれる場合の対処
- CSSでタブ切り替えする方法
- :target擬似クラスのまとめ
- CSSでヘッダを固定したスクロールテーブルを作る方法
- レスポンシブウェブデザインで画像を縮小する方法
- disabledなボタンのhoverのスタイルを無効にする方法
- HTML要素を別の要素を基点にしてCSSで絶対配置する方法
- :not擬似クラスでCSS3のサポートをチェックする方法
- :checked擬似クラスでチェックボックスに連動して要素を表示させる方法
- ol要素の入れ子で親の番号を子に割り当てる方法
- チェックボックスやラジオボタンを大きくする方法
- CSSで中央に配置する方法