「レンダリングを妨げるリソースの除外」の3つの対策法
「PageSpeed Insightsで『レンダリングを妨げるリソースの除外』という項目が表示されたけど、改善方法がよくわからない」という方に向けて、前提となる仕組みや具体的な対策手順を解説します。
ページスピードを高めて、ユーザー体験、CV率、検索順位などを改善したい方はぜひご覧ください。
レンダリングを妨げるリソースとは
「レンダリングを妨げるリソース」とは、「Webページを表示するために必要な処理(レンダリング)」の開始を遅らせるリソース(※)のことです。
※ 「リソース」は、Webページを構成するデータのことで、HTML、CSS、画像、フォントなどを指します。
WebページはHTMLやCSSなどによって構成されていますが、私たちは「データそのもの」ではなく、それらを元に描画された「ページ」を見ています。この「データ → ページ」の変換の処理のことをレンダリングと言います。
レンダリングを経ないと、ブラウザ上にページを表示させることができません。
そのため、ページの表示速度を早める上で「レンダリングを妨げるリソース」をできるだけ排除することは重要です。
では具体的にどのようなリソースがレンダリングを妨げるのかというと、下記が該当します。
CSS | JavaScript |
---|---|
|
|
つまり、これらを最小限に抑える形で実装することが必要になります。以下で、その具体的な方法を解説します。
レンダリングを妨げるリソースへの対策方法
レンダリングを妨げるリソースの対策をする上では、下記の3つのアプローチが考えられます。
- ファーストペイントに必要なリソースをインライン化
- ファーストペイント以外の部分で必要なリソースを非同期化
- 不要なリソースを削除
ファーストペイントに必要なリソースをインライン化
まず前提として、Webページの表示は段階的におこなわれます。ページの最下部までのすべての読み込みがが完了してからページの描画がスタートするのではなく、準備ができたところか順次描かれていきます。
そして、Webページが表示される時の最初の描画(ファーストペイント)に必要なリソースのことをクリティカルリソース、クリティカルリソースを元にファーストペイントがなされる過程をクリティカルレンダリングパスと言います。
Webページの表示速度を早めるためには、まずはクリティカルレンダリングパスを最速で終わらせる必要があります。
※ 実際、「レンダリングを妨げるリソース」の「レンダリング」はページ全体のレンダリングではなくクリティカルレンダリングのことを指しています。
これを踏まえると、レンダリングを妨げるリソースの改善のための第1ステップは、クリティカルなリソースとクリティカルでないリソースを識別することにあると言えます。
その上で、クリティカルなリソースを最短で処理できるようにインライン化し、クリティカルでないリソースがクリティカルレンダリングを妨げないように非同期化することが必要になります。
クリティカルなCSSとJavaScriptのインライン化
インライン化は、別ファイルを <link rel="stylesheet" href="">
や <script src="">
などで読み込むのではなく、HTMLに直接記述することを指します。
インライン化するメリットは、そのリソースのダウンロードが必要無くなることです。
<link rel="stylesheet" href="style.css">
や <script src="script.js">
などのように外部ファイルとして読み込む場合は、HTMLファイル以外にstyle.cssやscript.jsをサーバーからダウンロードする必要性がまず発生します。
一方、インライン化すれば、HTMLファイルにすでに含まれているため別ファイルのダウンロードが必要無くなり、それが速度の観点で有利に働きます。
インライン化する上での注意点
ただし、リソースのインライン化には注意点もあります。
- 対象のコードを最小限に抑える
- 保守性を考慮する
対象のコードを最小限に抑える
インライン化することで別ファイルのダウンロードの必要性は無くなりますが、下記のデメリットも存在します。
- キャッシュできない
- それ自体が後続のコードの処理の妨げになる
そのため、インライン化するコードは最小限に抑えなければ逆効果を被る恐れもあるので、要注意です。
具体的には、above-the-foldの描画に必要なコードのサイズが(ほとんどのサーバーにおける最初のパケットである)14 KBを下回ることを目標として考えるのがよいでしょう。
Googleの開発者ブログでも下記のように14 KBが挙げられています。
最初のレンダリングまでのラウンドトリップ回数を最小限に抑えるため、スクロールせずに見える範囲のコンテンツは 14 KB(圧縮時)以下にします。
保守性を考慮する
インライン化はあくまでもブラウザに渡すHTMLファイル上の話です。開発環境においては、head
に直接書くのではなく、専用のファイルで管理した方が保守性を担保しやすいでしょう。
例えばWordPressなら、wp_add_inline_style()
関数を使うことで別ファイルとして切り出したCSSファイルをインライン形式で出力できます。
ファーストペイント以外の部分で必要なリソースを非同期化
非同期とは、ある処理を、別の処理をおこないながら並行して実行することです。
つまりリソースの処理を非同期化することで、レンダリングという処理をできるだけ妨げずに、それと並行して進めることができるようになります。
以下で、CSSとJavaScriptそれぞれでの非同期化の実装方法を解説します。
CSSの非同期化
CSSの場合、rel="preload"
属性によってダウンロードを非同期でおこなうことができます。これを用いる際は、ダウンロードするファイルをhref
属性で、そのファイルタイプをas
属性でそれぞれ指定します。
<link rel="preload" href="style.css" as="style">
ただし、この記述だけだとダウンロードしたCSSの解析やページへの適用はおこないません。そのため、通常のrel="stylesheet"
と併用する必要があります。
しかし、HTML上でrel="stylesheet"
を持つlinkタグまで解析がたどり着いた段階でその解析が始まってしまい結局レンダリングがブロックされてしまいます。
CSSには後述するJavaScriptと違いこの課題を直接的に解決するための機能はありませんが、Googleが紹介している以下のようなテクニックを用いることで対処が可能です。
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>
まず、rel="preload"
によってCSSファイルを非同期にダウンロードすることができます。レンダリングを妨げずに並行して必要なファイルをダウンロードしておくことができ、解析や実行はまだされません。
そして、onload
属性のthis.rel='stylesheet'
によって、すべてのリソースの読み込みが完了した後に、rel
属性の値をpreload
からstylesheet
に変えて、CSSの解析と適用をおこないます。this.onload=null;
は、一部のブラウザではrel属性を変更することでonloadで指定したコードが2回実行される可能性があるため、それを防ぐための記述です。
<noscript>
の行は、JavaScriptが無効になっている環境でCSSが適用されないことを防ぐための記述です。
JavaScriptの非同期化
JavaScriptでは、defer
属性とasync
属性を使うことで非同期処理を実装できます。
defer/async無し | defer | async |
---|---|---|
script タグまでたどり着いた段階でHTMLの解析をストップして、JavaScriptのダウンロードと実行をおこなう。それが完了したらHTMLの解析を再開する。 | script タグまでたどり着いた段階で、HTMLの解析と並行してJavaScriptをダウンロードする。HTMLの解析が完了したらJavaScriptを実行する。 | script タグまでたどり着いた段階で、HTMLの解析と並行してJavaScriptをダウンロードする。そして、ダウンロードが完了した段階でHTMLの解析を止めてJavaScriptを実行する。その後、HTMLの解析を再開する。 |
上記を図解すると下記のようになります。
defer
もasync
もJavaScriptのダウンロードを非同期的に実行できるため、そのフェーズでレンダリングを妨げてしまうことが無くなります。
その上で、async
はダウンロードが完了したらHTMLの解析を止めてJavaScriptを実行するため、ダウンロードがHTMLの解析よりも前に済んだ場合はそのフェーズでレンダリングをブロックします。
一方、defer
はHTMLの解析が完了してからJavaScriptを実行するため、レンダリングが妨げられる可能性が低くなります。
また、async
がJavaScriptが読み込まれたタイミングで順次実行されるのに対して、defer
は<script defer src="...">
の記載順で実行されるという違いもあります。
不要なリソースを削除
ページにとって必要無いリソースは、非同期化ではなく削除すべきです。
特にWordPressの場合はプラグインのCSSやJavaScriptがサイト全体で読み込まれてしまうことが多いため、注意が必要です。
WordPressで不要なリソースを削除する方法は以下のコラムにまとめていますので併せてご参照ください。