僕がWebフロントエンドの世界に飛び込んでから数年経った。しかし、恥ずかしながらこれまでアプリケーションのパフォーマンスについてあまり深く考えたことがなかった。僕がWebに飛び込む前から、そして飛び込んだ後もWebページの高速化は日に日にその重要性を増してきており、最低限の知識や考え方を持っていないと成果を出すどころか同僚との議論にすら全くついていけなくなる有様だ。
パフォーマンスの世界への入り口として 超速本 を読了したので自分なりにまとめてみることにした。
基本戦略
とにかく計測から入る
推測するな、計測せよ
は様々な領域で言われていることだが、改めてこの言葉を噛みしめることになった。
考え方としては、
- ボトルネックを探して対応することが成果への近道
- 手段から入るのは間違い
の2つが特に重要そう。
高速化のためのポイント
高速化と言っても、ボトルネックの正体やそれに合わせた対応を考えると様々である。
しかし、主に軽量化(取り扱うデータ量を削減する)や最適化(実行の順番やデータ経路などのチューニング)を意識することになる。
具体的には、下記のようなことを考えることになる。
- ネットワーク処理
- データの転送量をなるべく小さくすること
- データの転送回数をなるべく少なくすること
- データの転送距離をなるべく短くすること
- レンダリング処理
- UIの応答速度
- 100ms以内を目指す
- FPS
- テレビ: 30fps, アニメ・映画: 24fps
- Webでは60fpsを目標とする
- UIの応答速度
- スクリプト処理
計測手段
計測に用いるツールについて
ここまでで、Webのパフォーマンスアップに対する考え方や着目点を知ることが出来たが、重要なのは計測することである。計測手段はいくつかあるので、それぞれ見ていく。
Chrome DevTool
おそらく最も多くのWebフロントエンジニアに馴染み深いツール。DevToolの各タブで出来ることを見ていく。
Networkタブ
個人的には、DevToolの中でも使用頻度が高いタブ。ページ内の関連リソースの通信状況を確認できる。
Yahoo!JAPAN でnetworkタブを開いてみるとこんな感じ。
ページ上部
ページ上部にはページ読み込み完了までのリソース読み込み状態が表示されている。
ここで、青と赤の赤線に注目したい。
- 青い縦線がDOMContentLoadedが完了したタイミング
- 赤い縦線がLoadが完了したタイミング
上記のリソース読み込み状態の下には、Waterfallが表示されている。ここでは、リソースがダウンロードされる順番や、各リソースをダウンロードするのにかかった時間がわかる。それぞれのリソースの詳細も見られる。
Perfomanceタブ
Webサイトのパフォーマンスを計測できる。これまであまり使ったことがなかった。
AbemaTVのもの
-
この値が小さいほど、より速く画面が更新され動くことを示す。
CPU
このグラフが示すのはCPUの負荷の大きさで、色によってそれぞれ意味が異なる。
- 青/Loading: HTTPリクエスト、パース
- 黄/Scripting: JavaScriptでの処理
- 紫/Rendering: スタイル評価、レイアウト算出
- 緑/Painting: ペイント処理、画像のラスタライズ
- 灰色/Other: その他
NET
ネットワーク通信状態を示す。優先度の髙い/低いリソースへのアクセスを表す。
PageSpeed Insights
Googleが提供しているツール。URLを入力することで、そのWebページのPC/SPでの表示速度を計測できる。
久しぶりに自分のWebページに対してチェックをかけてみたら一見良さそうな値が出てきた。一見早く見えるが、単純にコンテンツが無いだけ。
複雑なWebページであればあるほどスコアは落ちてくるが、改善項目をサジェストしてくれるのでその項目を精査、改善するだけでも結構違う。
WebPagetest
合成モニタリングを行うサービス。実際に特定のリージョンからアクセスを実行し、ChromeDeveloperToolsのNetworkタブに相当するデータを取得できる。
こちらに詳しい。
自分のWebページに対して実行してみた結果。有料の合成モニタリングサービスとしては、 SpeedCurve
が有名。
表示速度の指標
上記のツールを用いてパフォーマンスの改善を図る場合に、どのタイミング/段階の数値を改善するのかを追いかける方がより良い改善ができる。表示速度においては、ナビゲーションからのパフォーマンスを示す複数の指標がある。
具体的な指標の数々
- First Paint
- ナビゲーション後に、ページ内の何かが表示され始めたタイミングのこと
- クリティカルレンダリングパスの改善が有効
- First Contentful Paint
- ナビゲーション後に、ページ内のコンテンツが表示され始めたタイミングのこと
- これら2つの指標は、サブリソースのロード状況やクリティカルレンダリングパスの状態などを示す
- パフォーマンスの指標となりうる
- ユーザー体験に直接影響する数値ではない
- Paint Timingで取得可能
- First Meaningful Paint
- ユーザーにとって意味のある表示になったタイミング
- あいまいな指標
- 標準化が難しい
- User Timingを利用して計測もしくは計測ツールでスクリーンキャプチャを撮って画像比較で判定
- Time to Interactive
- ロードが完了し、ユーザー操作に確実に応答できるようになったとき
- RAILモデルのIdleを満たす状態
- SPAのようにJSの初期化やAPIとのやり取りに時間がかかるアプリケーションなどで有効な指標
- こちらも、標準化には至っていない
- Speed Index
- ATF(Above the fold)
- スクロールせずに閲覧可能な画面領域
- ATFでの表示性能を数値化
- ファーストビューにおける描画量のスコア
- ATF(Above the fold)
こういった指標が挙げられ、それぞれに効果的な改善を模索、実行していくことになる。ここで意識しておきたいのは、 最も重要視するべき指標はプロダクトによって変わってくる
ことである。プロダクトでの各指標がどうなっているかを継続的に計測すること、改善するために何が出来るかをチームで議論して実践することが何より大事っぽい。
その他、取り組みたいキーワード
- Resource Hints
- https://www.w3.org/TR/resource-hints/
- link要素を利用したリソースの先読み
- TCPの事前接続/リソースの事前ダウンロードなど…
- 対応ブラウザはまだ多くない
- 通信内容の軽量化
- キャッシュ戦略
- ServiceWorkerを用いたキャッシュ戦略
- 優先度の髙いリソースをキャッシュしたりする
- 画像の圧縮
- メタデータの削除
- 減色、圧縮
- フォントのサブセット化
- Unicodeのコードポイントで分割
- ブラウザが必要なフォントファイルのみロードすることを補助する
まとめ
いろいろ考えることがあって混乱してしまうのが正直なところだが、まずは計測する仕組みする仕組みを整えること、それぞれの指標/フェーズにおいて何が出来るのかを一つずつ明らかにしていくのが良さそう。
計測による可視化がなければ闇雲かつ場当たり的な対策しか出来ず、パフォーマンスを改善したとは言えない。特にWebは多種多様な環境でのアクセスが当然のように起こる世界なので、チーム/プロダクトで協力して様々な環境を用意し、定期的なモニタリングと評価、改善が肝要なのだと知ることが出来た。