画像のフィンガープリントを使用してページ読み込み速度を向上させる
ウェブサイトやウェブアプリケーションが視覚的な豊かさと機能を拡張するにつれて、ページ速度の最適化がますます重要になります。静的アセットはページ速度の大きな部分を占め、頻繁に変更されることはないため、毎回発信元のウェブサーバーに戻るのではなく、キャッシュ(ユーザーのブラウザーまたはCDN)からリロードすることが重要です。
サーバーレベルでのHTTPヘッダーとファイルレベルでのフィンガープリントの組み合わせを使用することで、変更されていないアセットが常にキャッシュから来るように実質無限の有効期限を設定しつつ、アセットが更新された場合には強制的にリフレッシュを促すことができます。この投稿では画像のフィンガープリントのベストプラクティスについて探求しますが、一般的な原則はCSSやJavaScriptファイルなどの他の静的アセットにも適用されます。
インフラストラクチャにキャッシュ戦略を実装することで、キャッシュを簡素化し、排出に関わる手作業を排除することができます。これには、キャッシュ層が最も最近使用されたものを使用するアプローチ(LRU)を使用しているという前提があります。(ウェブトラフィックを扱うほとんどのキャッシュ層がそうしています。)
画像の一般的なキャッシュ戦略
キャッシュは、画像の有効期限を設定し、変更があったときに追跡するという2つの基本的なニーズをカバーする階層的な戦略として最もよく実装されます。最終目標は、アプリサーバーへの往復を最小限に抑え、可能な限りキャッシュからアセットを取得することです。画像ファイルすべてにフィンガープリントを設定し、その Cache-Control: max-age=31536000
を設定することをお勧めします。 その理由は以下の通りです。
HTTPヘッダーは、画像がキャッシュに保持できる期間を明示的に設定する2つの方法を提供します。
Expires
: 有効期限の日時を設定します(HTTP 1.1日付形式、GMT時間)Cache-Control: max-age=xxxx
: 有効期限を秒単位で設定します
2つの中で、max-age
はより実装が簡単であり、理解しやすく、フォーマットやタイムゾーンの問題によるエラーの可能性が少ないため、より優れた選択肢です。1 画像の場合、max-age
を1年(31536000秒)に設定することで、ユーザーの視点からは有効期限が事実上無限になります。max-age
は Expires
が存在する場合にはそれを上書きします。
HTTPヘッダーには画像が変更されたかどうかを検証する2つの方法もあります。
Last-Modified
: アプリサーバーでファイルが最後に更新された日付を通信します(HTTP 1.1日付形式、GMT時間)ETag
: ファイルメタデータとノードから生成されたユニークID
両方がキャッシュによってファイル自体を検査することなく、キャッシュ内のファイルとアプリサーバー上のファイルを比較するために使用されます。負荷分散されたサーバー環境(>1ノード)では、異なるノードが異なるETagを生成し、サーバー間で一貫性のない応答を生じさせる可能性があるため、Last-Modified
がより良い選択です。
一般的に、Expires
または max-age
のいずれかを指定する必要があります。両方を指定するのは冗長です。
注意: imgixでは、Cache-Control
ヘッダーの設定が、imgixが処理しないファイル(SVGなど)のキャッシュミスを減らし、処理する画像を元に戻さないようにするのに役立ちます。Amazon S3を使用しており、バケット内の既存のファイルを更新する必要がある場合は、s3cmdのようなスクリプトを実行して、アップロード後にヘッダーを設定できます。
フィンガープリントのベストプラクティス
画像はCSSやJavaScriptなどの他の静的ファイルタイプよりも変更されることが少ないため、max-age
設定をCache-Controlヘッダーに高く設定することができます。ただし、画像が変更されたときに更新された画像がユーザーに届くように「キャッシュを破壊する」方法も必要です。ファイル内容のハッシュをファイル名に追加することで画像にフィンガープリントを付けることが、いくつかの理由で最良の方法です:
-
ファイル内容だけからハッシュを作成すると、スタック内のすべてのサーバーでフィンガープリントが一貫性を持ちます。これは
Etag
によって生成されるユニークIDとは異なります。 -
ほとんどの現代のウェブフレームワークには、ビルド時に自動的にフィンガープリントを作成するヘルパーがありますので、手動で画像ファイルの名前を変更する必要はありません。(Railsの例)
-
クエリストリングとしてフィンガープリントを追加する(もう一つの一般的な方法)は、常に認識されるわけではありません。2 また、imgixのURLパラメータと競合する可能性もあります。
ファイルフィンガープリント(またはチェックサム)は、ファイル内のコンテンツを分析して、その内容を表す16進数の文字列(ハッシュ)を生成することで作成されます。チェックサムは次のようになります:bea8252ff4e80f41719ea13cdf007273
。
チェックサムは一貫性のあるフィンガープリントを生成するために繰り返し可能なハッシュ戦略を使用します。これは単にバージョン番号を増やすよりも信頼性の高い方法です。ファイルフィンガープリントを生成するための一般的なハッシュアルゴリズムは MD5 です。コマンドラインでMD5を試すことができます:echo "Hello, World\!" | md5
。
フィンガープリントとimgixとの相互作用
imgixはキャッシュ管理のためにフィンガープリントベースのアプローチを強く推奨しています。これは、APIに対してパージリクエストを発行する必要がないためです。フィンガープリント付きの画像を更新すると、ファイル名が変更されたため新しい画像がソースから要求されます。
古いOrigin Assetは、それが要求されなくなったため、それ以降はカウントされません。古いOrigin Assetと新しいOrigin Assetの両方が、切り替えが行われた月の月次合計にカウントされますが、月に何千もの画像を変更しない限り、影響は最小限です。ストレージに対して保存されたバイト数の料金が発生する場合は、古いOrigin Assetをオリジンストレージから削除することを検討するかもしれません。
結論と詳細情報
これはキャッシングとフィンガープリントに関する簡単な概要です。サーバー、バックエンドコード、キャッシング戦略によっては、さらに詳細な制御が可能です。このトピックについて深く掘り下げたい場合は、次の包括的なリソースをチェックしてください:
Footnotes
-
Expires vs. max-age – Mark Nottingham, 2007年5月5日 ↩
-
Revving Filenames: don’t use querystring – Steve Souders; 2008年8月23日 ↩