• このエントリーをはてなブックマークに追加
  • このエントリーをはてなブックマークに追加

CSSもページ表示速度を落とす要因になります

「なんだか自分のサイトのページの表示速度が遅いなあ…」

もしかしたら、CSSが原因の1つになっているのかも?CSSを見直す良い機会かもしれません。

ブラウザはページ内容を表示する時レンダリングを行っています。

レンダリングとは、データ(今回の場合だとHTML)に書かれている情報を解析し、その通りにディスプレイに表示させることを指します。

外部CSSはこのレンダリングをブロックしてしまうリソースの1つで、運用方法によっては、これが原因でページ内容を表示するのが遅くなることがあり得ます。

どこを、どうやって改善するといい?

  1. CSSをインライン化する
  2. セレクタを見直す
  3. HTTPリクエスト数を減らす

大きくこの3点です。以下より実際の改善方法をご紹介いたします!

1. CSSをインライン化する

CSSを、外部ファイルにではなく直接HTMLファイル内に<style>で書いてやると、ブラウザはページのレンダリングを続けることができます。

ただ、内部CSSの量が多いと今度はHTMLファイルの容量が大きくなり、HTMLファイルの読み込みが遅くなってしまうので注意が必要です。

そのため外部CSSの内容を全てHTMLファイル内に移すのではなく、FV(ファーストビュー:ユーザーがブラウザでアクセスした時に初めて目にする範囲)で使用するCSSのみ移すと、内部CSSの量を抑えることができます。

残りのCSSを記述した外部CSSの読み込みをFVの後まで遅らせると、FVのレンダリングの妨げになりません。

「ページを開いたけどFVの表示が遅い」といったストレスを軽減できる可能性があります。

ですがlink要素はhead要素の中に入れるものなので、ここ以外に入れてしまうと文法上エラーとなってしまいます。

ではどうすればいいのでしょうか。

文法エラーを回避したうえで読み込みを後回しにするには?

<script>なら<body>の中に書けるので、JavaScriptを使って外部CSSをFVの後で読み込むようにしましょう!

<body>の中に書くJS

<script>
  var link = document.createElement('link');
  link.href = 'http://hoge.jp/css/style.css';
  link.rel = 'stylesheet';
  link.type = 'text/css';
  var head = document.getElementsByTagName('head')[0];
  head.appendChild(link);
</script>

元のHTMLファイル

<head>
  <meta charset="UTF-8">
  <title>読み込みテスト</title>
</head>

ChromeのDeveloper Toolsで確認
JavaScriptで外部CSSを追加

JSで<link>を生成し、<head>に追加しています。

ブラウザはHTMLファイルを上から順に読み込んで処理を行うので、外部CSSへのリンクを追加するJSを最後の方に書けば、それまでのソースを読み込んだ後に実行してくれます。

参考:JavaScriptでスタイルシートを読み込む方法|薫のHack

インライン化といっても、style属性はダメです

複数のタグに同じ「padding: 0;」を適用するなどコードの不要な重複に繋がる可能性があるので、できるだけ避けましょう。

また、W3Cで定められた「Content Security Policy 1.0」にてブロックされてしまいます。

2. セレクタを見直す

セレクタはなるべく短くしましょう

例えば下記のようなセレクタの場合。

div p a.hoge {  }

左のセレクタからマッチする要素を探しているのかと思いきや、実は右から探していきます。(実は私もずっと勘違いしていました)

a.hoge を探す → 親要素は<p>か → その親要素は<div>か…となり、その分解析に時間を要します。

そのため、子孫セレクタをどうしても使わなければいけない時を除き、なるべくセレクタは短くするよう心がけましょう。

現在使用していないセレクタは削除しましょう

無駄なセレクタは、余計な解析の手間がかかりページの表示速度を遅くしてしまう要因になりかねません。

使用しないセレクタは削除し、常日頃から整理しましょう。

3. HTTPリクエスト数を減らす

パーツごとに「style.css」「common.css」と外部CSSファイルを分けてしまいがちですが、ファイル数の数だけHTTPリクエストが発生して時間がかかるので、1つにまとめてリクエスト数を減らしましょう。

@import の使用は避けましょう

@importも複数の外部CSSファイルを読み込む時に使うものなので、上記と同様にその分HTTPリクエスト数が発生します。

また、外部CSSファイルはほとんどのブラウザで同時に読み込まれますが、@importで複数ファイルを読み込む場合は1つ1つ順番にダウンロードされてしまいます。

つまり、「外部CSSファイルを読み込む時間×ファイル数」だけの時間がかかるということです。

@importの使用は避けましょう。

Data URIスキームはHTTPリクエスト数を減らせるけど…

通常、画像ファイルは「ファイル名.png」といったように書くのですが、Data URIスキームを使用すると「data:image/png;base64,~」と記述することが可能です。

参考:http://duri.me/

上記ツールを使うと、画像をテキストデータに変換することができます。そのためHTTPリクエスト数を減らせるメリットがあるのですが、画像データの容量が元のファイルの約3割増しになるデメリットがあります。

画像データが大きいほどData URIスキームが長くなりCSSのサイズが大きくなってしまうので、大きな画像データには不向きです。

外部CSSだけではありませんが、読み込み速度が遅くならないよう、Data URIスキームを使うのであればアイコンなどの小さい画像データだけに留めましょう。

終わりに

運用している外部CSSの量が多いほど、見直しが大変になってくると思います。常日頃から意識して整理しておくことが大切になってきます。

まずはCSSファイルを統合していって、HTTPリクエストの削減を目指すところから始めてみてはいかがでしょうか?

少しでも、ページ表示の速度改善の手助けになれますと幸いです。

原田