これらの推奨事項を実装した後、疑問が生じます。正確に最適化するものは何ですか? ほとんどの場合、これはすべての要素を含むページを完全にロードする時間です。 ただし、これは必ずしも必要なものではありません。 実際、ユーザーが重要な機能要素(タイトル、テキスト、製品の説明など)を含むページの「最初の画面」を取得するのにかかる時間、つまりページがレンダリングを開始する瞬間が重要です。 これは、クリティカルレンダリングパスが発生する場所であり、ブラウザがページのレンダリングを開始するために実行する必要があるすべてのアクションを定義します。 このことについては記事で説明します。
クリティカルパスとは何ですか?
クリティカルレンダリングパスは、ページの描画を開始するために最低限必要なアクション、リソース、および計算のセットです。
クリティカルパスは、クリティカルリソースの数、最小ロード時間(RTTで測定)、およびクリティカルリソースの量(バイト単位)で測定できます。
説明のために、最も単純な例を見てみましょう。外部リソースのないサイズが1 kbのHTMLページです。 クリティカルパスは、1リソース(HTMLドキュメント)、1 RTT(最小)、1 kbのトラフィックです。 ただし、そのような単純なページは自然界ではほとんど見つけることができないため、実際のWebページでクリティカルパスを特定する方法を示します。
クリティカルパスの識別
実際のWebページは、HTMLドキュメントと多数の外部リソース(CSSファイル、JSファイル、フォント、画像など)で構成されています。最新のブラウザーは、ページの読み込みプロセスを最適化して、できるだけ早くレンダリングを開始しようとします。 ただし、ブラウザーはCSSとJSの仕様によって制限されているため、厳密な順序でページを構築する必要があります。 クリティカルパスの最終段階は、ブラウザがレンダリングを開始できるレンダーツリーの構築です。
クリティカルパスに含まれる主な手順を見てみましょう。
- HTMLドキュメントを取得します。
- 含まれるリソースのHTMLを解析します。
- DOMツリー(ドキュメントオブジェクトモデル)を構築します。
- 重要なアイテムのリクエストを送信します。
- すべてのCSSコードを取得します(JSファイルのリクエストも実行します)。
- CSSOMツリーを構築します。
- 受信したすべてのJSコードを実行します。
- DOMツリーを再構築します(必要な場合)。
- レンダーツリーを構築し、ページのレンダリングを開始します。
このシーケンスからいくつかの重要な結論を引き出すことができます。
まず、CSSおよびJSコードを持つリソースがクリティカルパスに関与します。 他の外部リソースは考慮されていません。
第二に、すべてのCSSリソースが受信されてCSSOMツリーが構築されるまで、JSコードを実行できません。
第三に、JSコードが実行される前にページをレンダリングすることはできません。DOMツリーを変更できるためです。
しかし、すべてがそれほど単純ではありません。問題は、いつものように詳細にあります。 私たちのタスク:ページのクリティカルレンダリングパスを最小化する。
クリティカルパスを削減する方法
たとえば、jQuery UIのAutocompleteプラグインのデモからページコードを取得します。
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>jQuery UI Autocomplete - Default functionality</title> <link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css"> <script src="http://code.jquery.com/jquery-1.10.2.js"></script> <script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <script> $(function() { var availableTags = [ "ActionScript", "AppleScript", "Scheme" ]; $( "#tags" ).autocomplete({ source: availableTags }); }); </script> </head> <body> <div class="ui-widget"> <label for="tags">Tags: </label> <input id="tags"> </div> </body> </html>
このページのクリティカルパスはどの要素で構成されていますか?
- ページ自体(HTML)。
- 2つのCSSファイル。
- ページの先頭にある2つのJSファイルとJSコード。
JSファイルの並列ロードの条件下では、3 RTT(最小)が得られます。
クリティカルレンダリングパスを短くします。 この場合にできること:
- 2つのCSSを1つのファイルに結合します。
- JSを1つのファイルに結合します。
- ページの末尾の/ bodyの前に、JSファイル呼び出しと埋め込みJSコードを配置します。
- オートコンプリート要素のCSS読み込みを延期します。
最初の2つの最適化は、SPDYまたはHTTP / 2なしの通常のHTTPを使用する場合にのみ関連することに注意してください。この場合、リクエストの数は重要ではありません。 明るい未来(HTTP / 2)がもうすぐそこにあり、SPDYが既に存在するため、ファイルの接着は処理しません。
3番目と4番目の最適化について説明します。 JSファイル呼び出しをドキュメントの最後に移動すると、ブラウザーはページのレンダリングをより早く開始できます。 jQuery UIからのCSSの読み込みの遅延は、このファイルのスタイルが(フィールドに入力した後)オートコンプリート要素を表示するためにのみ必要であるという事実のために可能です。
これは、ページの最終バージョンの外観です。
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>jQuery UI Autocomplete - Default functionality</title> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> </head> <body> <div class="ui-widget"> <label for="tags">Tags: </label> <input id="tags"> </div> <script>document.addEventListener("DOMContentLoaded", function(event) { var availableTags = [ "ActionScript", "AppleScript", "Scheme" ]; $( "#tags" ).autocomplete({ source: availableTags }); }); </script> <script>document.addEventListener("DOMContentLoaded", function(event) { $('head').append('<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" type="text/css">'); });</script> <script src="http://code.jquery.com/jquery-1.10.2.js"></script> <script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script> </body> </html>
注:jQuery UIプラグインの呼び出しは、構造にラップされています。
document.addEventListener("DOMContentLoaded", function(event) { // plugin code });
これにより、ページ上の任意の場所にjQueryとそのプラグインに依存するコードを配置できます。 同じ方法を使用して、CSSファイルの遅延ロードが実行されました。
現在、クリティカルパスは1リクエスト(CSS)だけ削減されており、レンダリングを開始するためにそのロード(トラフィック)は必要ありません。 すべてのJSコードがドキュメントの最後に移動されるため、このコードが実行される前でもブラウザーはレンダリングを開始できます。
後で実行できるスクリプト(たとえば、カウンタースクリプト、ソーシャルプラグインなど)がページにある場合、async属性を使用してそれらをクリティカルレンダリングパスから除外できます。
<script src=1.js async></script>
ただし、これはjQueryとそのプラグインでは実行できません(非同期ロードの方法がありますが、かなり面倒です)。 したがって、上記のソリューションを使用します。
結果
何が起こったかを確認してください。 Chromeで両方のファイルをダウンロードします。 開発者ツールを開き、「デバイスモードの切り替え」を有効にし、ネットワークを450 Kbps 150 ms RTに制限し、キャッシュなしで読み込みます。 ダウンロードするとき、「タイムライン」タブにあります。
ページのレンダリングが開始された瞬間に興味があります(最初のペイントイベントは緑色で表示されます)。 最適化されていないバージョンの場合:5000ミリ秒、最適化された500ミリ秒の場合。
説明した手法を使用すると、特にページがJS機能で飽和し、大量のCSSコードを持っている場合、ページのレンダリングを大幅に高速化できます。 最適化を行うときは注意してください。すべての変更をテストします-JSライブラリの起動順序を変更すると、機能が破損する可能性があります。