ブログやサイト運営において、運用コストやパフォーマンスなどのメリットからJekyll, Gatsby, Hugo, Next.jsなどの静的サイトジェネレーターと静的サイトホスティングサービスという構成が増えています。
ホスティングサービスを選ぶ際にもいろいろな比較観点がありますが、その中でも通信速度は誰しも気になるポイントの1つではないかと思います。
今回は有名な静的サイトホスティングサービスである以下5つを速度の面で比較します。
※AWS Amplifyは公式のFAQにて「グローバルに利用可能なコンテンツ配信ネットワーク (CDN) 上でホスティングします」と書かれています。またAWS Japanの公式YouTube動画でもCloudFrontやS3を用いている旨が述べられており、AWSのホスティングでよくあるCloudFront+S3という構成においても今回の実験結果が当てはまると思いますのでご参考にしてみてください。
比較方法
同じ内容のサイトをそれぞれのサービスにデプロイし、アクセスするときの速度を測定しました。CDNキャッシュが存在しそれが返された場合と、キャッシュが無くオリジンからダウンロードがされたパターンのそれぞれを測定しました。
環境
実際のサイトへのアクセス状況に近い方がいいと考え、クラウド上のサーバーなどではなく手元の端末からアクセスしています。
いろいろな通信経路を試してみたいという観点で、自宅の固定回線とモバイル回線の2通りで試しました。どちらも端末からは無線LAN接続です。
エリア概要 | 回線 | |
---|---|---|
光回線 | 某政令指定都市の近郊 | 家庭向け光回線 |
モバイル | 某政令指定都市の近郊 | 個人向けモバイル回線 |
測定方法
abコマンド(Apache Bench)で速度を計測しました。
% ab -V
This is ApacheBench, Version 2.3 <$Revision: 1903618 $>
実際のコマンドは以下の形式。
ab -n 50 -c 1 -v 2 -H "Accept-Encoding: gzip, deflate, br
Accept-Language: ja,ja-JP
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \
${TARGET_URL}
並列数1で50回のリクエストを行います。ヘッダーはCDN側の挙動に影響がありえるため実際のブラウザから送られるものを設定しています。
Webサイトから取得できるHTMLファイル内で指定されているCSSやスクリプトなどは読み込まず、レンダリングなどもしないので、あくまで1つのファイルのダウンロードの速度に着目した実験です。
通信速度には様々な要因によるブレがあるため、50回実行した上での統計値を記載します。
データ内容
以下のサンプルページを作りました。サイズは約33KBです。
サービス | URL |
---|---|
Netlify | https://sample-site-netlify.rkd3.dev/posts/sample/ |
Firebase hosting | https://sample-site-fb.rkd3.dev/posts/sample/ |
Vercel | https://sample-site-vercel.rkd3.dev/posts/sample/ |
Cloudflare Pages | https://sample-site-cf.rkd3.dev/posts/sample/ |
AWS Amplify | https://sample-site-amplify.rkd3.dev/posts/sample/ |
基本的には各サービスのデフォルト設定をしているのですが、一部例外があります。
設定内容(キャッシュあり)
Cloudflare Pagesでの設定
まずCloudflareに関してはデフォルトではHTMLファイルをキャッシュしません。
Cloudflare does not cache HTML resources automatically.
― Customize Caching with Cloudflare Rules
今回の実験ではまさにHTMLファイルを取得する速度を計測するのでこれではダメですね。
Page Rulesでキャッシュレベルを設定することができるので、今回は以下のようにすべてのコンテンツをキャッシュさせるように設定しました。
AWS Amplifyでの例外設定
次にAWS Amplifyでは、手元で実験したところデフォルトではレスポンスヘッダーに Cache-Control: max-age=0, s-maxage=2
が設定されていました。
つまり、ブラウザではキャッシュせず、CDNでも2秒しかキャッシュしないという設定です。
これでは今回のCDNでのキャッシュを前提とした実験では不利になってしまう可能性があるため、カスタムヘッダーの設定から以下のようにCDNのキャッシュ期間を伸ばすようにしました。
設定内容(キャッシュなし)
CDNでキャッシュさせない方法は各サービスで様々です。
Netlify
netlify.tomlファイルに以下を記載してデプロイします。
[[headers]]
for = "/*"
[headers.values]
Netlify-CDN-Cache-Control = '''
max-age=0,
no-cache,
no-store,
must-revalidate'''
参考: Custom headers | netlify docs
Firebase
firebase.jsonファイルに以下を記載してデプロイします。
"headers": [
{
"source": "**/*",
"headers": [
{
"key": "Cache-Control",
"value": "no-store"
}
]
}
]
参考: ホスティング動作を構成する | Firebase Hosting
Vercel
VercelだけはCDNキャッシュを返さないようにするという動作がどうしても実現できませんでした。なんとしてでもキャッシュを使わせたいという強い意志を感じます。
今回はキャッシュなしのパターンからは除外しています。
AWS Amplify
上記にあるとおり、カスタムレスポンスヘッダーに Cache-Control: public, max-age=0, s-maxage=0
を指定しました。
結果
以下ではキャッシュありの場合とキャッシュなしの場合それぞれに対して、各サービスでダウンロードにかかった時間を記載します。ダウンロード完了までにかかった時間の最小値、中央値、95パーセンタイル値を比較します。
キャッシュあり
まずはキャッシュありの場合です。ただしキャッシュヒットしないリクエストが3件以上あったものについては、カッコをつけて90パーセンタイル値を記載します。
単位はすべてミリ秒です。
光回線
サービス | min | median | 95パーセンタイル |
---|---|---|---|
Netlify | 350 | 360 | (392) |
Firebase | 73 | 83 | 120 |
Vercel | 48 | 52 | 69 |
Cloudflare | 65 | 75 | 150 |
Amplify | 52 | 57 | 95 |
以下のグラフは中央値の昇順に並べ替えています。
モバイル回線
サービス | min | median | 95パーセンタイル |
---|---|---|---|
Netlify | 500 | 581 | (909) |
Firebase | 209 | 265 | 495 |
Vercel | 210 | 271 | 535 |
Cloudflare | 242 | 317 | (456) |
Amplify | 231 | 278 | 471 |
以下のグラフは光回線のグラフと同じ順に並べています。
キャッシュなし
次にキャッシュなしの場合です。CDNを使っていても、リクエストの条件によってはキャッシュヒットしなかったり、アクセス頻度の低いサイトではキャッシュの有効期限が切れている場合も多いと思われ、意外とキャッシュヒットしなかった場合の速度も重要ではないでしょうか。
前述の通りVercelはキャッシュをさせない設定ができなかったためこの比較実験からは除外しています。
単位はすべてミリ秒です。
光回線
サービス | min | median | 95パーセンタイル |
---|---|---|---|
Netlify | 578 | 626 | 934 |
Firebase | 134 | 170 | 370 |
Vercel | - | - | - |
Cloudflare | 103 | 181 | 333 |
Amplify | 79 | 121 | 211 |
以下のグラフは中央値の昇順に並べ替えています。
モバイル回線
サービス | min | median | 95パーセンタイル |
---|---|---|---|
Netlify | 716 | 763 | 907 |
Firebase | 282 | 332 | 589 |
Vercel | - | - | - |
Cloudflare | 256 | 339 | 719 |
Amplify | 258 | 313 | 403 |
以下のグラフは光回線のグラフと同じ順に並べています。
考察
以上の結果を元に、私なりの見方で考察をいくつか書いてみようと思います。
Netlifyの遅さ
まず目立つのはNetlifyの遅さですね。中央値を見ても他のサービスは差がせいぜい数十ミリ秒程度ですが、Netlifyだけはキャッシュありで200〜300ミリ秒程度、キャッシュなしで400〜500ミリ秒程度の差があります。これは他のブログでもよく言われており、CDNのキャッシュサーバーおよびオリジンサーバーが地理的に遠い可能性が指摘されています。
調べてみると公式のサポートフォーラムでは東京のエッジサーバーは “High-Performance CDN” とされており、 “Regular CDN” で日本から近そうなのはシンガポールでした(シンガポールは地理的に近い上に海底ケーブルも接続されています)。
ただし、どうしたら “High-Performance CDN” が使えるのかはよくわかりませんでした。
少なくとも今回の実験では日本のエッジサーバーは使われていなかったのではないかと推測されます。
中央値での順位付け
次に中央値の比較で順位付けをしてみます。
キャッシュあり
光回線 (キャッシュあり) | モバイル回線(キャッシュあり) | |
---|---|---|
1 | Vercel | Firebase |
2 | Amplify | Vercel |
3 | Cloudflare | Amplify |
4 | Firebase | Cloudflare |
5 | Netlify | Netlify |
個人的に面白いと感じたのは光回線では4位だったFirebaseがモバイルでは1位だったことです。回線によってここまで結果に差が出るというのは、CDNサービスが一律で速い/遅いが語れるものではないということがよくわかります。(ただし、Firebaseがモバイル回線からは速いということまでは言えないことにご注意ください。今回の実験では特定の場所から特定の時間帯に2つの回線で測定しただけですので、あくまで通信の経路によって速度が変わるということまでしか言えません。)
キャッシュなし
光回線 (キャッシュなし) | モバイル回線(キャッシュなし) | |
---|---|---|
1 | Amplify | Amplify |
2 | Firebase | Firebase |
3 | Cloudflare | Cloudflare |
4 | Netlify | Netlify |
キャッシュなしではAmplifyが安定して速いのも印象的でした。エッジからオリジン(CloudFrontからS3)の速度の速さが現れていそうです。
中央値の差の絶対値(キャッシュあり)
実際の値の差を詳しく見てみます。まずはキャッシュありにおける中央値の差です。各回線環境における中央値の1位との差を記載すると以下の通りでした(単位はミリ秒)。
サービス | 光回線(キャッシュあり) | モバイル回線(キャッシュあり) |
---|---|---|
Netlify | 308 | 323 |
Firebase | 31 | - |
Vercel | - | 6 |
Cloudflare | 23 | 52 |
Amplify | 5 | 13 |
光回線ではVercelとAmplifyが5ミリ秒と僅差、モバイル回線ではFirebase, Vercel, Amplifyが13ミリ秒以内の差でした。VercelとAmplifyはどちらの環境でも安定して速い結果となりました。特にVercelはどちらの回線においても爆速ですね。
続いてCloudflareとFirebaseも最大で30〜50ミリ秒差でした。数値で見ると差があるとは言え、実際にサイトを閲覧する場合においてはサードパーティのリソースのダウンロードや、HTMLの解析、スクリプトの実行が動くことなどを考えると、50ミリ秒差はほとんどの場合においてほぼ気にならない程度と言えるのではないでしょうか。
95パーセンタイル値の差の絶対値(キャッシュなし)
最後にキャッシュなしの場合の95パーセンタイル値の1位との差を見てみます。最悪でどれくらい遅くなるかという観点です。
サービス | 光回線(キャッシュなし) | モバイル回線(キャッシュなし) |
---|---|---|
Netlify | 723 | 504 |
Firebase | 159 | 186 |
Cloudflare | 122 | 316 |
Amplify | - | - |
Amplifyが他サービスに大きな差をつけていることがわかります。最低でも120ミリ秒以上の差ということで、速度にこだわるような場面だと多少差を感じるようになるかもしれません。
まとめ
静的サイトのホスティング先という想定で、サンプルサイトをNetlify, Firebase Hosting, Vercel, Cloudflare, Amplify (CloudFront) の5サービスにデプロイし、複数の環境から速度計測をして比較を行いました。
各サービスごとに特色がありつつ、Netlify以外であれば実際にサイトを閲覧する場面においては大きく体験に差が出ることは無さそうです。その中でもVercelとAmplifyは安定して速いという結果となりました。特にキャッシュヒットしない最悪のケースでもAmplifyは速度の低下が抑えられているという結果でした。
またホスティングサービスの選定という観点では、もちろん速度も重要ではありますが、それに加えてデプロイ方法、コスト、モニタリング、セキュリティなどなど多くの要素が絡んできます。
あくまで各サービスのほんの一面を切り取っているだけである、という前提を忘れず、今回の結果を参考にしていただければと思います。