この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
いわさです。
CloudFrontにはコンテンツを圧縮して配信する機能が備わっています。
以下の記事ではBrotliの設定方法や圧縮されていることを確認しています。
CloudFront側では本日時点でGzipとBrotliの2つの圧縮形式がサポートされていますが、一方でブラウザ毎のコンテンツ圧縮形式のサポート状況は異なっています。
CDN側でそのあたりをどのように吸収しているのか、CloudFrontを使って挙動とキャッシュ動作を確認してみました。
※各ブラウザで何がサポートされているのかについてはこの記事では触れません。
圧縮設定
CloudFront側でコンテンツ圧縮を有効化するには2つの設定が必要です。
- キャッシュビヘイビアでの「オブジェクトを自動的に圧縮」を有効化します。
- キャッシュポリシーの圧縮サポートを有効化します。
デフォルトのキャッシュポリシーであればCachingOptimized
が圧縮サポートの有効化がされています。
圧縮サポートはGzip、Brotliそれぞれで有効化が可能です。
圧縮の確認
オリジン設定されたS3バケットに適当なHTMLファイルをコンテンツアップロードし確認してみます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1000, initial-scale=1.0">
<title>Document</title>
</head>
<body>
ああああああああ
...
ああああああ
</body>
</html>
CloudFrontでは、サイズが 1,000~10,000,000 バイトのオブジェクトを圧縮する仕様なので、その範囲内のファイルサイズであることを確認します。
また、圧縮するかどうかのファイルタイプもContent-Type
ヘッダーを使って判断されます。
クライアント毎にレスポンスを圧縮するか判断する仕組み
CloudFrontではリクエストのAccept-Encoding
にgzip
, br
, またはその両方が含まれていることによって圧縮を行います。
例えば、圧縮設定を有効にしたInternet Explorer 11だとgzip
のみ送信されbr
はサポートされていないので送信されません。
また、ChromeやFiregfoxを使った場合でもHTTPS利用時のみgzip,brを送付するなどブラウザによって対応状況や挙動は異なっています。
本日はcurlを使ってAccept-Encoding
ヘッダーを指定しレスポンスヘッダーを確認してみます。
無圧縮リクエスト
ここではContent-Encoding
を確認しレスポンスが圧縮されているかを判断します。
curlのデフォルトではAccept-Encoding
ヘッダーは付与されないので、圧縮されません。
iwasa.takahito@hoge 20211219cloudfront % curl -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 105555
Connection: keep-alive
Date: Sat, 18 Dec 2021 23:26:25 GMT
Last-Modified: Sat, 18 Dec 2021 23:20:30 GMT
ETag: "eac7a9e486d059b18d5d841a740c9aa8"
Accept-Ranges: bytes
Server: AmazonS3
Vary: Accept-Encoding
X-Cache: Hit from cloudfront
Via: 1.1 04c2f7c6be96060d3defd0bb02b9dbde.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: NRT12-C3
X-Amz-Cf-Id: Gwzpjl0cD6DsTEVFsCRZnVaqCuGXr0DoETIVhjc9Y1FGF61vusxjJg==
Age: 585
Gzip
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:gzip' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html
HTTP/1.1 200 OK
Content-Type: text/html
Server: AmazonS3
Content-Encoding: gzip
Vary: Accept-Encoding
Brotli
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:br' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html
HTTP/1.1 200 OK
Content-Type: text/html
Content-Encoding: br
Vary: Accept-Encoding
GzipとBrotliが混在
多くのブラウザではGzipもBrotliもどちらもサポートされており、それをリクエスト時に伝えます。
その場合はAccept-Encoding
にサポート形式が全て格納されて伝わります。
両方サポートされている場合、CloudFrontではBrotliを優先します。
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:br,gzip' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html
HTTP/1.1 200 OK
Content-Type: text/html
Content-Encoding: br
Vary: Accept-Encoding
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:gzip,br' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html
HTTP/1.1 200 OK
Content-Type: text/html
Content-Encoding: br
Vary: Accept-Encoding
なお、優先
なので、CloudFront側のキャッシュポリシーでBrotliがサポートされていない場合はGzipが次点で選択されます。
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:gzip,br' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html
HTTP/1.1 200 OK
Content-Type: text/html
Content-Encoding: gzip
Vary: Accept-Encoding
また、このキャッシュポリシー状態でクライアントがBrotliのみ要求する場合は無圧縮でレスポンスされます。
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:br' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html
HTTP/1.1 200 OK
Content-Type: text/html
Vary: Accept-Encoding
キャッシュの確認
同一リクエストでもAccept-Encoding
に応じて複数の圧縮形式でレスポンスされることがわかりました。
もうひとつこの記事で確認しておきたいのが、圧縮形式ごとのキャッシュの取り扱いです。
圧縮形式のサポート状況が異なる複数のブラウザからアクセスされた場合にどのような挙動になるでしょうか。
この時点ではキャッシュキーに明示的にAccept-Encoding
は指定していません。
キャッシュを全て削除し、圧縮パターンごとに2回づつアクセスしたところ以下のような結果となりました。
iwasa.takahito@hoge 20211219cloudfront % curl -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html
X-Cache: Miss from cloudfront
iwasa.takahito@hoge 20211219cloudfront % curl -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html
X-Cache: Hit from cloudfront
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:gzip' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html
Content-Encoding: gzip
X-Cache: Miss from cloudfront
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:gzip' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html
Content-Encoding: gzip
X-Cache: Hit from cloudfront
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:br' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html
Content-Encoding: br
X-Cache: Miss from cloudfront
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:br' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html
Content-Encoding: br
X-Cache: Hit from cloudfront
それぞれの1回目のアクセスでキャッシュされていますね。
当然だとは思いますが、異なる圧縮形式間でキャッシュを共有してしまうことはありませんでした。
CloudFrontはキャッシュキーに自動でAccept-Encoding
を含める仕様になっています。
逆に、明示的にキャッシュポリシーに指定した場合は圧縮しなくなってしまうようです。
念の為、異なるAccept-Encoding
が指定された場合にキャッシュがクリアされてしまわないことも確認しました。
iwasa.takahito@hoge 20211219cloudfront % curl -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html
X-Cache: Hit from cloudfront
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:gzip' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html
Content-Encoding: gzip
X-Cache: Hit from cloudfront
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:br' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html
Content-Encoding: br
X-Cache: Hit from cloudfront
まとめ
本日は、Accept-Encoding
を指定した圧縮の確認と形式ごとのキャッシュの取り扱いについて確認してみました。
- CloudFrontは
Accept-Encoding
リクエストヘッダーに基づいてレスポンスの圧縮形式を判断している Accept-Encoding
を暗黙的にキャッシュキーに含まれてキャッシュされる
圧縮形式としてサポートされているのはgzipとbrですが、Accept-Encoding
の標準仕様にCloudFrontが則っていることを確認することが出来ました。いいですね。