DevelopersIOブログの記事配信がCloudFront経由になりました

DevelopersIOブログの記事配信を CloudFront のアップデートを取り入れて最適化。動的生成(SSR)されるトップページのキャッシュヒット率を98%台まで向上、LCPなどの改善を実現しました。
2023.09.12

2023年9月6日(水)、 当ブログサイト(DevelopersIO)の記事配信をCloudFrontに切り替えるメンテナンスを実施しました。 その内容と現時点の結果について共有させて頂きます。

構成

メンテナンス後

20-構成図(メンテ後)

  • CloudFront経由で、記事、記事一覧ページが配信されるようになりました。

  • Nginxは CloudFrontのオリジンとして、パスルーティング管理、リダイレクト、各種ヘッダーの設定に利用しています。 Nginxを利用したページキャッシュは廃止、高性能な実行環境を必要としなくなったため、暫定的に App Runner上 で動作させています。

Nginx リバースプロキシの実行環境としてApp Runnerを利用してみた

メンテナンス前

20-構成図(メンテ前)

  • 従来、Nginxのページキャッシュをインスタンスストアに蓄えるために EC2 Autoscallingで 利用していました。
  • AWS Global Accelerator をネットワークの最適化のため 利用していました。
  • WordPressをヘッドレスCMSとして利用するアプリケーション(Vue)は、継続利用しています。

参考URL

Lighthouse測定

トップページ表示

Chrome拡張の Lighthouse を利用して、ブログの トップページ を対象としたパソコン表示の性能をCloudFrontの有無で測定、比較を試みました。

  • Performance: 84 → 93
  • LCP (Largest Contentful Paint) : 2.6s → 1.6s

  • CloudFrontあり

10-lighthouse-トップページ(CloudFrontあり)

  • CloudFrontなし

11-lighthouse-トップページ(CloudFrontなし)

記事ページ表示

Lighthouse スコアの改善、記事ページについても確認できました。

  • 記事ページ別Lighthouse スコア
記事 Performance LCP (秒)
【2022年版】使いやすいフリーイラスト素材サイト12選【商用利用OK】 65 -> 94 4.3 -> 1.5
[Microsoftアカウント]と[職場または学校アカウント]の違い 64 -> 89 5.2 -> 1.7
Linux OSのバージョン確認方法をまとめてみた 56 -> 85 4.6 -> 2.4
AWS re:Invent 2014 Keynote 1 リアルタイムレポート #reinvent 58 -> 80 4.4 -> 1.6

LCPは望ましい目安とされる 2.5s 以下を達成できました。

採用したCloudFrontの機能

「stale-while-revalidate」サポート

2023年5月にリリースされた CloudFrontのアップデートの活用を試みました。

CloudFrontのオリジンとなるNginxで、「/」ページのレスポンスヘッダーに「stale-while-revalidate=180」を付与。

  • Nginx location 設定
location = / {
    proxy_hide_header Cache-Control;
    add_header Cache-Control "max-age=90, stale-while-revalidate=180";
    proxy_set_header Host $backend;
    proxy_pass https://$backend;
  }

Nginxを参照する CloudFront側のキャッシュ更新を非同期にする指定としました。

Cache-Control: max-age=90, stale-while-revalidate=180 のレスポンスを受け取ったCloudFrontは、有効期限(90秒)が経過した後、次のリクエスト受け付けた時点でキャッシュの更新を試みますが、失効直後 180秒間は キャッシュを即再利用する設定としました。

レスポンスヘッダーポリシー

CloudFrontのレスポンスヘッダーポリシーを利用して「Cache-Control」を上書き、 ブログ閲覧者のブラウザキャッシュが効きすぎる事態を回避するため、「stale-while-revalidate」は削除しました。

レスポンスヘッダーポリシーは、ページ性質に応じて複数を用意。

トップページや一定時間の表示を維持するため 「stale-if-error」指定を追加。

個別の記事ページは、記事URLの変更や記事公開中止が行われる可能性があるため、「stale-if-error」の設定は見送り。

  • トップページ用のレスポンスヘッダーポリシー設定
    Type: AWS::CloudFront::ResponseHeadersPolicy
    Properties: 
      ResponseHeadersPolicyConfig: 
        Comment: ResponseHeadersPolicy Cache-Control TopPage
        CustomHeadersConfig: 
          Items: 
          - Header: Cache-Control
            Value: 'max-age=45, stale-if-error=21600'
            Override: True

GoogleのサーチコンソールでLCPの問題が報告されている 著者ページなどについては、強めのキャッシュ設定を行うなどの調整を実施予定です。

  • Googleサーチコンソール: LCPの問題

devio2023-renew-200

ECDSA P 256

CloudFrontで利用する証明書のキーアルゴリズムは「ECDSA P 256」。

2022年にACMでサポートされた、より高い安全性と 最近のCPUであれば 効率的な処理が期待できる楕円曲線デジタル署名アルゴリズムのものを利用しました。

HTTP/3

記事ページ、各種アセットなどの配信も HTTP/3 サポートとなりました。

ブログ画像の配信には、2022年8月から HTTP/3を利用していました。

オリジンシールド

キャッシュヒット率の向上と、オリジン負荷の軽減のため、2020年にリリースされたオリジンシールドを有効化しました。

Amazon CloudFrontにオリジンへのリクエストを軽減するキャッシュレイヤー(Origin Shield)が追加されました

現時点でオリジンシールドの効果は見定められていませんが、海外と推測されるlocationから、 海外のロケーションから一定数 オリジンシールドの利用までは確認できました。

今後、Origin Shield 1万件のリクエスト毎に発生する、0.0090 USD に見合う効果が確認できた場合、利用継続とする予定です。

  • オリジンシールドが利用されたリクエスト抜粋
result_type x_edge_detailed_result_type time_to_first_byte location
Hit OriginShieldHit 0.298 DUB56-P1
Hit OriginShieldHit 0.19733334 IAD55-P4
Hit OriginShieldHit 0.349 MAD53-P1
Hit OriginShieldHit 0.236 DUS51-P1
Hit OriginShieldHit 0.222 LAX50-P3
Hit OriginShieldHit 0.202 ATL59-P6
Hit OriginShieldHit 0.248 OSL50-C1
Hit OriginShieldHit 0.233 FRA6-C1
Hit OriginShieldHit 0.24 VIE50-P2
Hit OriginShieldHit 0.2422 AMS58-P1
Hit OriginShieldHit 0.407 SIN52-C2
Hit OriginShieldHit 0.263 FCO50-P3
Hit OriginShieldHit 0.3105 SOF50-P1
Hit OriginShieldHit 0.257 HEL50-C1

CloudFrontキャッシュ効果の確認

メンテナンス実施後のCloudFrontアクセスログを確認、トップページ「/」表示性能について確認を試みました。

ステータス 「RefreshHit」の「time-to-first-byte」(リクエストしてから、サーバーから最初の情報を受信するまでの時間)は、ステータス「Hit」時と同等でした。

  • 時間帯、キャッシュステータス(x-edge-result-type)別 、「time-to-first-byte」 (平均値)
時間帯 Hit RefreshHit Miss
9時 0.0040 0.0035 0.2276
10時 0.0041 0.0045 0.2685
11時 0.0043 0.0040 0.2576
12時 0.0040 0.0040 0.2268
13時 0.0044 0.0040 0.2148
14時 0.0043 0.0044 0.2299
15時 0.0036 0.0055 0.2318
16時 0.0041 0.0040 0.2587
17時 0.0041 0.0038 0.2287
18時 0.0037 0.0065 0.2463

キャッシュステータス 「RefreshHit」の割合が向上したことで、キャッシュミス率は2%台まで抑制する事ができました。

  • 時間帯別、キャッシュステータス(x-edge-result-type)別 の割合
時間帯 Hit RefreshHit Miss
9時 92.28% 6.22% 1.50%
10時 90.24% 8.28% 1.47%
11時 90.39% 7.80% 1.81%
12時 92.41% 6.19% 1.40%
13時 90.17% 7.84% 1.99%
14時 90.31% 8.09% 1.60%
15時 91.94% 6.79% 1.27%
16時 92.08% 6.24% 1.68%
17時 92.06% 6.55% 1.39%
18時 92.00% 6.38% 1.62%

以前の環境、トップページのキャッシュ有効時間は5分の設定でしたが、キャッシュのヒット率は90%未満、時折大きくキャッシュヒット率が低下する事もありました。 メンテナンス後は、CloudFrontのキャッシュを、より高いキャッシュヒット率で利用可能になりました。

  • 時間帯別、キャッシュヒット率の比較(メンテ前後)
時間帯 メンテ前 メンテ後
9時 86.68% 98.50%
10時 86.26% 98.53%
11時 88.77% 98.19%
12時 91.13% 98.60%
13時 87.21% 98.01%
14時 83.88% 98.40%
15時 87.05% 98.73%
16時 88.13% 98.32%
17時 87.98% 98.61%
18時 91.33% 98.38%

まとめ

CloudFrontを導入したメンテナンス、一週間経過時点の中間報告とさせて頂きました。

トップページについてはある程度最適化したキャッシュ設定が実現できましたが、 個別の記事ページ、特にGoogle サーチコンソールで LCPの警告が出ている執筆者ページなどの改善を引き続き進めていきたいと思います。

CloudFront、CDN設定に関係した副作用、表示異常など、お気づきの点がありましたら、 フッターメニューに存在する「お問い合わせ」→「DevelopersIOについて」のフォームからお知らせください。