Edited at

フロントエンドパフォーマンス分析 はじめの一歩

More than 1 year has passed since last update.

Webパフォーマンス Advent Calendar 2017 8日目です。

私がフロントエンドのパフォーマンスを始めて4ヶ月程経ちました。

フロントエンドにおけるパフォーマンス分析を行うにあたり、学んでおくべきことの概要としての記事を書いておきたいと思います。

尚、フロントエンドとは言うものの、どちらかというと「フロントエンドからわかること」を分析する、という方向性なので、改善策自体はバックエンドやインフラストラクチャーの部分になる場合もあります。


分析と計測の方法


ウォーターフォールチャート

ウォーターフォールチャートというのは、Chrome DevTools の Network タブにあるアレです。開発手法のアレとは特に関係ありません。

Chrome DevTools のウォーターフォールチャート

ウォーターフォールチャートを確認することで、どのファイルのダウンロードにどの程度時間がかかっているのか確認することができます。

これは基本的にリクエストを送る前から、ダウンロード完了までについて調査する際に必要となる図です。

読み方については、Google のドキュメントが参考になります。

また、それぞれの色の部分が何を示すかについては少し理解しづらいので、Resource Timing についても読んでおくと良いでしょう。

最初の HTML のダウンロードに時間がかかっていれば、バックエンド又はインフラが重い。画像等静的コンテンツのダウンロードに時間がかかっている場合は、ファイルサイズが極端に重いわけでない場合、インフラが重い…など、色々わかることがあります。

JavaScript が早い段階で読み込まれ過ぎている場合、defer や async を使っても良いかもしれません。

また、WebPageTest.org でもウォーターフォールチャートはサポートされています。

Screenshot_20171205_112308.png

こちらでは、読み込む物理的な場所 (東京、香港、ロンドン、等) や、回線 (光、LTE、等) も指定できますので、比較的実際のユーザーの環境に近い環境で実施できます。

モバイルサイトの速度のテストを、オフィスの光回線でやっても、実際の LTE 回線の速度より高速な結果が出るでしょうし、グローバルサイトの速度のテストを東京だけでやっても意味がありません。(例えば東京にしかサーバーがなければ、当然ロンドンでは非常に重くなります。)


ランタイムパフォーマンス

Chrome DevTools の Performance タブで、JavaScript など、フロントエンド側の処理について分析します。どの JavaScript ファイルで、どの程度処理に時間がかかっているか、などがわかります。

Chrome DevTools のパフォーマンスタブ


フィルムストリップ

下記の画像のように、何ミリ秒の時点で、ページがどれだけ表示されているかを確認するためのスクリーンショット群です。First Paint などのタイミングを測る時に重要になります。

フィルムストリップ

Chrome DevTools のネットワークタブで、カメラマークを押すと取得できます。


Synthetic monitoring

SpeedCurveCatchpoint などのツールで、パフォーマンスの監視を行うことができます。

今のところ無償のサービスは聞いたことがありませんので、「はじめの一歩」としてはちょっと微妙かもしれませんが。

基本機能としては、WebPageTest.org と同じような機能を備えているのですが、その他に、下記のグラフのように、表示などの速度の推移を監視することができます。

表示速度のグラフ (Catchpoint)

例えば娯楽系のサービスでは、一般に夜にアクセスが集中し重くなりますから、日中の業務時間中には、夜よりも高速な結果が得られますので、あまり参考になりません。

常にパフォーマンスを監視することで、重くなっている時間がないか、把握することができます。

サービスによっては、AWS の回線での計測だけではなく、実際のユーザーが用いる回線 (OCN の光とか docomo LTE とか) での計測結果を示してくれるものもあります。


RUM - Real User Monitoring

ページに JavaScript を埋め込み、ユーザーがページを閲覧した際の表示速度を取得してきます。

これも SpeedCurve や Catchpoint などのツールに機能があります。オープンソースでは、HubSpot が作っている Bucky というものがありました。


JavaScript の計測系 API

Navigation Time API など、JavaScript で DOMContentLoaded や load などの時間を取得できる API があります。

Real User Monitoring と同様のことを、自分で実装することもできます。

大体はツールでも取得することができますので、私は今のところ頻繁には使いませんが、存在だけは頭の片隅に置いておくと良いと思います。


2. 分析の指標

パフォーマンス分析の際に注目すべき指標がいくつかあります。


DOMContentLoaded, Load までの時間

HTML のパースが完了したタイミングを DOMContentLoaded、全ての画像・CSS・JavaScript のダウンロードと実行が完了したタイミングを load と呼びます。

DOMContentLoaded 及び load のタイミングの速さが、速度のひとつの指標になります。

以前程は重要視されなくなっている指標のようですが、基本として理解しておくべきだと思います。


First Paint 等までの時間

こちらが最近主に注目されている指標のようです。下記のように、どの程度まで読み込まれたかを示すタイミングの名前として、


  • Navigation Start

  • First Paint

  • First Contentful Paint

  • First Meaningful Paint

  • Visually Ready

  • Time to Interactive

  • Fully Loaded (≒ load)

という指標があります。

古川洋介さんのスライドがわかりやすいので、丸パクリ引用します。

First Paint などの指標

出典: You need to know SSR - Yosuke Furukawa

First Paint や First Contentful Paint は Navigation API で取得可能ですので、明確な数値として取得することが可能です。First Meaningful Paint は今のところできません。


Speed Index

こちらも最近重要な指標のようです。

どれだけの速度で、どれだけの面積が描画されているか、という考え方で計算される指標です。

計算式に積分の記号が出てくるなど、算出の仕方は少々複雑なようです…

参考: Speed IndexというWebパフォーマンスの指標


その他


asyncdefer

JavaScript を読み込む際、そのまま <script src="/path/to/code.js"> などと書くと、JavaScript のダウンロードや実行が、HTML の DOM 構築をブロックしてしまいます。

deferasync などの属性を用いることで、ダウンロードを HTML の DOM 構築と並列に実行したり、実行を遅らせたりできます。

詳細は以前 <script> タグに async / defer を付けた場合のタイミング という記事に書いたので、こちらを参照して下さい。


Critical Rendering Path

Critical Rendering Path とは、HTML や、そこに紐付いている画像・CSS・スクリプトなどのダウンロードから、First Paint までに、ブラウザー内部で行われる処理のことを言います。

具体的には、HTML や CSS の構文解析、DOM や CSSOM の構築や、どの位置にどのオブジェクトが描画されるべきかの座標計算などが行われます。

つまり、<script> タグを何度も追加したり、CSS のプロパティを JavaScript で頻繁に変更したりすると、このクリティカルレンダリングパスが何度も実行されて重くなります。

少し長いですが、Google Web Fundamentals に9ページほどの資料があります。

もう少し短いものが良ければ、以前私が訳した Catchpoint Systems の記事もありますので、こちらもよろしければどうぞ。


RAIL モデル

RAIL とは、


  • Response

  • Animation

  • Idle

  • Load

の略です。

フロントエンドにおいて、これらの処理にかかる時間は何秒以内であるべきか、ということを示したモデルで、Google が提唱しているようです。

それぞれ、


  • Response - ユーザーの入力から100ms以内にレスポンスを返す

  • Animation - 1フレームあたりで JS コードによる処理が10ms以内

  • Idle - アイドル時間に実行される処理は50ms以内の処理に小分けする

  • Load - ページの読み込みは1s以内

と決まっています。

本家 Google のRAIL モデルでパフォーマンスを計測するや、

@ahomu さんのRAIL という Web パフォーマンスモデルの概要が参考になるでしょう。