webpagetest.orgを利用したWEBページの表示速度測定とチューニング

WEBページの表示速度は、ブラウザに備え付けのデバッグツールを使えば十分測定できるものの、かゆいところに手が届かない部分も多い。webpagetest.orgという、WEBページの表示速度を測定するためのサービスがあるが、このツールには非常に多くの機能があり、うまく使いこなせばブラウザのデバッグツールよりも効率よくキメ細やかな測定ができる。
この資料ではwebpagetest.orgの使い方や、表示速度をチューニングする際のポイントについて説明する。

## webpagetest.orgを利用するメリット

筆者は普段Chromeを利用している。webpagetest.orgで計測できる指標としては、Chromeのdevtoolsで見れるものとほぼ同等だが、下記のようなメリットがある。

1. 計測結果をパーマリンクで共有できる
- Chrome devtoolsよりもネットワークやCPUのスロットリングが実際の挙動に近い
    - webpagetest.orgでは選択されたデバイスを実際に利用してリモートデバッグしているので、より実態に則した計測結果が得られる
    - たとえばネットワークのスロットリングは、ブラウザの実装的には機械的にsleepさせているだけのようで、遅いネットワークで起きるようなパケットロスなどは発生しない
- 計測値だけでなく項目ごとの評価が見れるので、どこがパフォーマンスのボトルネックなのかを把握しやすい
- 計測結果をダウンロードしてChrome devtoolsにインポートできる
- 全体的にChrome devtoolsよりも見やすい・使いやすい
    - 選択してコピーみたいな作業にストレスがない

## webpagetest.orgの基本的な使い方 

1. https://www.webpagetest.org にアクセス
1. 「Enter a Website URL」欄に測定対象のURLを入力
1. 「Test Location」や「Browser」などを選択
1. 「First view and repeat view」をチェック
    - この項目はオプションだが、キャッシュがちゃんと効いているかなどを把握するために2回目のアクセス時の結果を見ることも重要
1. 「START TEST」をクリック後、1-2分待ったら測定結果が出る


なお、ログインなどの処理が必要なページでは、ブラウザの操作をエミュレートするスクリプトを書くことができる。Twitterへのログイン処理はこんな感じだ。

```
navigate  https://mobile.twitter.com/login
setValue  name=session[username_or_email] YOUR_USER_NAME
setValue  name=session[password] YOUR_PASSWORD
click     type=submit
```

スクリプトの詳細については[ドキュメント](https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/scripting)を参照のこと。

## 測定結果サンプル

いくつかのページで実際に測定して結果を見てみる。

### 1. Google Maps

- 対象URL: https://www.google.com/maps
- 測定結果: https://www.webpagetest.org/result/170418_ZE_QQH/

測定結果画面の右上に表示されているのが、各測定項目の評価（Grade）だ。[Waterfallページ](https://www.webpagetest.org/result/170418_ZE_QQH/1/details/#waterfall_view_step1)を開き、リクエストの詳細を上から見てみる。

1-6番目のリクエストで、ドキュメント本体やフォントファイルを取得しているのが分かる。7-21番目は初期状態のマップに表示される地図が分割された画像ファイルだ。HTTP/2で通信しているからだろう、7-21のリソース取得開始が一直線に揃っていることが分かる。その後22-24はGoogle Mapのメニューのアイコンなどが続く。25で420KBのスクリプトが取得されているが、これはおそらく地図上に表示される座標データのようなものだろう。34-58は地図上に表示されるアイコンなどが並ぶ。その後ふたたび87から地図の画像が取得されていて、これは初期状態で表示されている領域のすぐ外側の地図のようだった。

このことから、まずユーザーに初期表示をなるべく速く見せるように作られていることが分かる。地図のディテールや、ユーザーが操作しなければ見えない領域の画像は遅延で取得することで、表示も速くかつユーザーにストレスを与えないUXを提供するような設計になっていると言えるだろう。

### 2. Twitter（モバイル）

- 対象URL: https://mobile.twitter.com/
- 測定結果: https://www.webpagetest.org/result/170418_RE_e684110ba5b0608a82c610233c817cd8/

次に、最近PWA化したことで話題になったTwitterのモバイル表示を見てみる。テストの設定では「Moto G (gen 4)」と「Moto G4 – Chrome」を選択した。ログインページだけを見るのもパッとしないので、テスト用にアカウントを作成して、ログインページとログイン後のページの表示速度を一緒に計測した。

評価にはズラッとAが並んでいるが、「Cache Static Content」の項だけがCとなっている。測定結果がログイン画面とログイン後のホーム画面の2つの評価の平均をとっているようで、ログイン後のタイムライン画面ではキャッシュできるリソースが少ないためにこうなっているのだろう。評価だけを見るとGoogle Mapと比べても遜色ないといったところだが、計測時間を見てみると圧倒的に速い。リクエストが少ないことの影響もあるだろうが、「DOM interactive」や「Document Complete」がこれだけ速いのは、細かいチューニングの賜物であろう。

[Waterfall view](https://www.webpagetest.org/result/170418_RE_e684110ba5b0608a82c610233c817cd8/1/details/#step2_request4)を見ると、ホーム画面に必要なデータや未読の通知、DMの通知など、画面の各部分のデータを取得するAPIリクエストが細かく分割されていることが分かる。0.5秒ごとにレンダリングされた画面のスクリーンショットが見れる[Filmstrip view](https://www.webpagetest.org/video/compare.php?tests=170418_RE_e684110ba5b0608a82c610233c817cd8-r:1-c:0)も興味深い。1.0秒の時点でTwitterアイコンが中央に配置されたスプラッシュ画面が表示されているのが分かる。Google Mapと同様に、早い段階でユーザーに初期表示を見せることを意識した設計になっていると推測される。



## ページ表示速度チューニングのポイント

Webページ／アプリケーションのコンテンツや挙動によってチューニング方法は変わるが、一般的な内容としては以下のような点を検討すると良い。

- 初期表示でユーザーに見える部分をなるべく早くレンダリングできるようにリソースの取得順を調整する
    - Filmstrip viewから0.5秒ごとのレンダリング結果のスクリーンショットと計測されたタイムラインを見比べられる
    - ユーザーが操作しないと表示されない部分のリソースや、サードパーティのウェジェットなどは遅延でロードさせる
        - defer属性などを利用する
- クリティカルレンダリングパスに含まれるファイル（JavaScript、CSS）のダウンロードをなるべく早く始めることで、ドキュメントをなるべく早い段階でinteractiveにする
    - リソースへのpreload, prefetch属性を活用する。やりすぎ注意。
- 名前解決すべきオリジンが多く、DNS解決に時間がかかっている場合はdns-prefetch属性を利用する
- CDNを利用する
- HTTP/2を使ってリクエストを並列化できるようにする
- リソースのファイルサイズを数を減らし、1つ1つを小さくする
    - JavaScriptやCSSファイルの結合、minify、圧縮
    - 画像ファイルの圧縮
- そもそも不要なリソースを読み込んでいないか確認する
- クライアントキャッシュを活用する
    - 適切なレスポンスヘッダをつける
    - ServiceWorkerを利用する