高速化への道

Speed Indexとは何か?

2017年5月5日
著者: 竹洞 陽一郎

主なポイント

  1. ダウンロード完了時間やRender Startだけでは、表示が始まってから描画が終わるまでの途中経過が分からないため、実際の顧客体験を定量的に測ることはできません。
  2. Speed Indexは、Film Stripの計測インターバルごとの未表示領域の割合を表示完了まで足し合わせた値(IntervalScore = 計測インターバル * (1.0 - (表示完了度/100))の合計)で、数値が小さいほど早く表示されたことを意味します。
  3. Speed Indexは、Film Stripの計測インターバルによって値が変わり、SPAや動的に一部だけ変わるページ、カルーセル表示のあるページでは正しく計測できず、計測マシンのCPUやGPUなどのスペックにも大きく左右されるため、Render StartやDocument Completeなど他の指標値と併用するべきです。
  4. HTTP Archiveの2017年4月15日のデータでは、.jpのサイトのSpeed Indexの中央値は6,633でしたが、米国カリフォルニア州レッドウッド市からの計測でデータの欠損も多いため、参考程度に見るべき値です。
  5. (2026年9月追記) HTTP Archiveの計測対象URLは、現在はAlexaのランキングではなくChrome User Experience Reportから選ばれており、テストも米国内の複数のGoogle Cloudリージョンから実行されているため、記事中の計測条件とは異なります。

弊社で販売しているWebパフォーマンスの計測・監視サービスCatchpointの4月のアップデートに、Speed Indexの対応が入りました。

Speed Indexは、Googleが開発や計測サーバの展開を支援しているオープンソースのWebサイト計測Webpage Testに、2012年4月に追加された指標値です。
Webページがどれだけ迅速に表示されて、可視化されたかを表すもので、数値が小さい程、良い値となります。

従来の指標値

ダウンロード完了時間

Webパフォーマンスの指標値として、長年使用されてきたのは、ダウンロード完了時間です。
Webページを構成する全てのオブジェクトをダウンロードし終えた時間を以って、パフォーマンスの指標値としていました。

私が、Akamaiに勤め始めた2006年の当時は4秒ルールと言われていました。
それは、「ダウンロード完了時間が4秒以内に終わるべきである」という事を意味していました。

その後、私がAkamaiを辞める2009年には、「3秒ルール」と言われて、ダウンロード完了時間は3秒以内に終わるべきであると、1秒短くなっていました。

ダウンロード完了時間は、実質的には、表示速度の指標値としては、適切ではありません。
勿論、ダウンロード完了時間が速ければ速い程、表示速度が速くはなりますが、表示そのものを計測した指標値ではないです。

First Paint

この問題に最初に取り組んだのは、Microsoftです。
Microsoftは、1995年に世界で最初にWebパフォーマンスの計測サービスを開始したKeynote Systemsの大口顧客であり、計測について積極的に取り組んでいました。

2009年にリリースしたInternet Explorer8から、First Paintという指標値が取得できるAPIが組み込まれています。
ブラウザが、ブランクページではなくなった時点を判定して、その秒数を返します。
ただ、ブラウザ側で、実際に表示が開始されたかどうかを判定するわけではないので、ごく稀に、ブランクページの状態でも、First Paintの数値が記録される場合があります。

First Paintは、Keynote Systems(現Dynatrace)での計測を主に、長らく表示開始の指標値として使われてきています。

W3C Navigation Timing

ダウンロード完了時間だけでではなく、表示速度に関するプロセスに対する、標準指標を定める必要性が、ブラウザベンダーを超えて議論されました。
そこで2011年に組織されたのが、W3C Web Performance Working Groupです。

そこで、策定されて、2012年12月17日にW3C Recommendationとなったのが、Navigation Timingです。

Navigation Timing

HTMLパーサや、XMLパーサの解析処理が終わったイベントdomComplete、メイン文書の読み込みイベントonLoadが終わったloadEventEndを取得する事で、ページ読み込み処理完了の秒数は用意に取得できるようになりました。
しかし、レンダリングが実際に、何秒ぐらいで開始されているかを正確に取得することが出来ません。

Render Start

そこで、ビデオ処理を組み合わせて、実際のブラウザでのレンダリング開始時間を取得する仕組みを実装したのが、Render Startです。
ブラウザ内の表示処理開始のFirst Paintと異なり、実際に、何かしら1ピクセルでもブラウザ上に表示された時間を記録して取得するため、表示開始時間としては精度が上がります。

Film Stript

Reder Startで、ビデオ処理を使うようになったので、時間の経過と共に、どれだけブラウザのページ領域に表示が完了したのかをトラッキングできるようになりました。
それを記録に残したものが、Film Stripです。

Film Strip

表示に関する指標値の問題点

Film Stripが取得できるようになったことで、一つの問題が明らかになります。
表示開始後、全ての描画が終わるまでの表示の仕方が異なる点です。

例として、楽天市場とAmazonのトップページのFilm Stripを見てみましょう。
Render Startは楽天市場の方が速いのですが、表示されない領域がある時間が長いです。
一方で、Amazonは、Render Startは遅いものの、表示されていない領域がある時間は短いです。

楽天のトップページのFilm Strip。Speed Indexは、5,447。
AmazonのトップページのFilm Strip。Speed Indexは、4,653。

このように、Render Startの時間だけでは、実際の顧客体験は定量的には測れない事が、Film Stripから明らかになったのです。

Speed Indexの登場

Film Stripを一つ一つ視認して確認するのでは、正確性に欠けます。
そこで、定量的な、表示完了に至るまでの指標値が必要となりました。
そこで登場したのが、Speed Indexです。

例えば、2つのWebサイトがあって、それぞれの表示開始時間は100ms、表示完了時間は2秒だとします。
しかし、この2つのサイトは、途中経過での表示完了率が異なります。

サイトAは、全体の殆どが最初に表示され、最後の100msで残りの25%が表示されます。
サイトBは、全体の殆どが最後の100msに表示されます。

表示領域の表示完了率

顧客体験としては、最初に殆ど表示されるサイトAの方が良いです。
これを定量的に数値化して表すには、どうすればいいでしょうか?

未表示領域の割合をFilm Stripの計測インターバル毎に足し合わせた面積を表示完了まで求める事で指標化したのです。
未表示領域のFilm Strip計測インターバル単位での積分です。

IntervalScore = 計測インターバル * (1.0 - (表示完了度/100))
SpeedIndex = SUM(IntervalScore)

計測インターバルは、Film Stripでのミリ秒となります。
Film Stripを100msで取得する場合は、計測インターバルは100msになります。

サイトAの未表示領域の推移

Film Stripの計測インターバルが100msの場合、サイトAは、以下のような計算になります。

サイトAのSpeed Indexの計算(Film Strip計測インターバル100ms)
経過時間(ms)表示完了度未表示領域IntervalScore
10075%25%25
20080%20%20
30090%10%10
40095%5%5
50095%5%5
60095%5%5
70095%5%5
80095%5%5
90095%5%5
100095%5%5
110095%5%5
120095%5%5
130095%5%5
140095%5%5
150095%5%5
160095%5%5
170095%5%5
180095%5%5
190095%5%5
2000100%0%0
Speed Index135
サイトBの未表示領域の推移
サイトBのSpeed Indexの計算(Film Strip計測インターバル100ms)
経過時間(ms)表示完了度未表示領域IntervalScore
1005%95%95
20015%85%85
30015%85%85
40015%85%85
50015%85%85
60015%85%85
70015%85%85
80015%85%85
90015%85%85
100015%85%85
110015%85%85
120015%85%85
130015%85%85
140015%85%85
150015%85%85
160015%85%85
170015%85%85
180015%85%85
190095%5%5
2000100%0%0
Speed Index1545

Speed Indexの弱点

Film Strip計測インターバルで値が変わる

Speed Indexの値は、Film Strip計測インターバルで値が変わってしまうので、その点は注意です。
WebpageTestでは1000msです。
Catchpointでは、Film Stripのインターバルは、以下の値を選べます。

500ミリ秒のFilm Strip計測インターバルで、上述の二つのサイト、AとBのSpeed Indexを計算してみます。

サイトAのSpeed Indexの計算(Film Strip計測インターバル500ms)
経過時間(ms)表示完了度未表示領域IntervalScore
50095%5%25
100095%5%25
150095%5%25
2000100%0%0
Speed Index75
サイトBのSpeed Indexの計算(Film Strip計測インターバル500ms)
経過時間(ms)表示完了度未表示領域IntervalScore
50015%85%425
100015%85%425
150015%85%425
2000100%0%0
Speed Index1275

レンダリングが完了してページの一部だけが変わる場合、正しく計測できない

動的に変更されるページや、SPA(Single-page Application)についてのトランザクション計測(ページ遷移が発生する計測)では、値が有利になります。
未表示領域は、存在せず、動的に変わる部分だけが値に影響するからです。

また、カルーセル表示を実装したページは、その変更する秒数によって、Speed Indexの値が不利になる可能性があります。

マシンのハードウェアスペックに大きく左右される

ビデオ処理された画面上を追うため、CPUやGPUなど、計測マシンのスペックに大きく依存します。

他の指標値との併用が大事

Speed Indexは、従来使われてきた、Reder StartやDocument Completeといった、表示に関する指標値を置き換えるものではありません。
上述のように、いくつかの弱点があります。
従って、他の指標値と併用して使われるべき指標値です。

日本のWebサイトのSpeed Index

HTTP Archiveの2017年4月15日のデータから、ドメイン名が.jpのものだけを抜き出して、Speed Indexのヒストグラムを作成してみました。

日本のWebサイトのSpeed Indexの分布
Speed Index — 2017年4月15日 — 日本
平均値最小値
(0パーセンタイル)
25パーセンタイル中央値
(50パーセンタイル)
75パーセンタイル最大値
(100パーセンタイル)
標本の大きさ
7,5675794,3906,6339,57692,51011,013

最頻値は、5,001〜6,000の層です。
しかし、この値は、米国カルフォルニア州レッドウッド市からのアクセスであるため、日本からアクセスした場合のSpeed Indexとは異なります。
(HTTP Archiveのデータは、WebpageTestの米国カルフォルニア州レッドウッド市にある計測ノードから、毎月1日と15日に、Alexa Top 1,000,000のサイトに対して3回アクセスされます。)

Alexa Top 10,000の.comサイトのSpeed Index

HTTP Archiveの2017年4月15日のデータから、ドメイン名が.comのもので、AlexaのランクTop10,000のものだけを抜き出して、Speed Indexのヒストグラムを作成してみました。

Alexa 上位10,000.comサイトのSpeed Indexの分布
Speed Index — 2017年4月15日 — Alexa Top 10,000 .com
平均値最小値
(0パーセンタイル)
25パーセンタイル中央値
(50パーセンタイル)
75パーセンタイル最大値
(100パーセンタイル)
標本の大きさ
7,9684714,6286,9589,864104,7004,939

最頻値は、5,001〜6,000と、6,001〜7,000の層です。
生データを見ると、「このサイトがこのSpeed Index?」というものが多く、Catchpointで計測してみると、より小さいスコアで出ます。
また、半数以上、データが欠損しているため、WebpageTestの計測マシンのハードウェアスペックに大きな影響を受けていると考えられます。

ですので、上記の二つのデータについては、参考程度に見て下さい。