web-dev-qa-db-ja.com

キャッシュを保持する必要がある画像のHTTPリクエストを行うためにブラウザを停止します-mod_expires

ここで多くの記事といくつかの質問を読んだ後、私はついにApache mod_expiresをアクティベートしてブラウザに1年間画像をキャッシュしなければならないことを伝えました

<filesMatch "\.(ico|gif|jpg|png)$">
  ExpiresActive On
  ExpiresDefault "access plus 1 year"
  Header append Cache-Control "public"
</filesMatch>

ありがたいことに、サーバーの応答は正しいようです:

HTTP/1.1 200 OK 
Date: Fri, 06 Apr 2012 19:25:30 GMT 
Server: Apache 
Last-Modified: Tue, 26 Jul 2011 18:50:14 GMT 
Accept-Ranges: bytes 
Content-Length: 24884 
Cache-Control: max-age=31536000, public 
Expires: Sat, 06 Apr 2013 19:25:30 GMT
Connection: close
Content-Type: image/jpeg 

まあ、これはブラウザがダウンロードを停止し、1年もサーバーに画像を問い合わせることさえあると思いました。しかし、それは部分的に真実です:原因ブラウザーを閉じて再度開くと、ブラウザーはサーバーから画像をもうダウンロードしませんしかし、ブラウザは各画像のHTTPリクエストでサーバーに問い合わせます

各画像のHTTPリクエストをブラウザに強制的に停止させるにはどうすればよいですか?これらのHTTPリクエストに続いてダウンロードされるイメージがなくても、サーバーへのリクエストであるため、待ち時間が不必要に長くなり、ページのレンダリングが遅くなります!

私はすでにブラウザに画像を1年間キャッシュに保存しなければならないことを伝えました!なぜブラウザーは、画像をダウンロードしなくても、各画像についてサーバーに問い合わせるのですか?!


FireBugのネットワークグラフ(メニューFireBug> Net> Images)を見ると、さまざまなキャッシュの動作を見ることができます(ブラウザーのキャッシュを完全に空にして明らかに始め、「すべての履歴をクリア」を使用してブラウザーでキャッシュを削除しました):

  • ページが最初にロードされると、すべての画像がダウンロードされます(そして、ブラウザのページの再読み込みボタンをクリックしてページの再読み込みを強制すると、同じことが起こります)。 これは理にかなっている!

  • サイトをナビゲートして同じページに戻ると画像はまったくダウンロードされず、ブラウザはいずれの画像についてもサーバーに問い合わせてはいけません。 これは理にかなっています(ブラウザが閉じているときにもこの動作を確認したいです!

  • ブラウザを閉じて同じページで再度開くと、愚かなブラウザはとにかく画像ごとに1回サーバーにHTTPリクエストを行います:画像をダウンロードしませんが、それでもHTTPリクエスト。ブラウザが画像についてサーバーに問い合わせるようなものです(サーバーは200 OKで応答します)。 これは私をイライラさせるものです!

興味がある場合は、以下のグラフも添付します。

enter image description here

enter image description here

編集:FireFox 3.6が古すぎる問題ではないことを確認するために、FireFox 11.0でもテストしました。同じことが起こります!!! GoogleサイトとStackoverflowサイトもテストしました、どちらもCache-Control: max-age=...を送信しますが、ブラウザはまだブラウザが閉じられて同じページで再度開かれると、画像ごとにHTTPリクエストをサーバーに送信し、サーバーの応答後、ブラウザは画像をダウンロードしません(上で説明したように)まだページを見る時間を増やすいまいましい要求をします。

EDIT2:提案されたLast-Modifiedヘッダーの削除 ここ は、問題を解決せず、違いはありません。

45
Marco Demaio

リクエストの分析に間違ったツールを使用していました。

本当に便利なFirefoxアドオンLive HTTP headersをお勧めします。そうすれば、ネットワークで実際に何が起こっているかを確認できます。

念のため、サーバーをssh/PuTTYして、次のようなことを行うことができます。

tail -f /var/log/Apache2/access.log
14
Oliver Kurmis

表示されている動作は意図したものであり(詳細については RFC7234 を参照)、指定された動作です。

最新のブラウザはすべて、キャッシュステータスに関係なく、表示されるすべてのページ要素に対してHTTPリクエストをサーバーに送信します。これは、HTTPサーバーがすべての要素のすべての表示の記録を維持できるようにするために、Webサービス(特に広告ネットワーク)の要求で行われた設計上の決定でした。

ブラウザーがこれらの要求を行わなかった場合、サーバーはユーザーに画像が表示されたことを通知されません。広告ネットワークの場合、これは壊滅的です。早い段階で、広告ネットワークは、ランダムに生成された名前(例: 'coke_ad_1_98719283719283.gif')を使用して同じ広告画像を配信することにより、この問題を回避しました。ただし、ISPの場合、ユーザー全員がこれらの同一の広告画像を再ダウンロードし、ISPが動作しているキャッシング/プロキシサーバーをバイパスするため、この方法によりデータ転送が大幅に増加しました。

停戦に達しました。期限切れになっていないキャッシュされた要素であっても、ブラウザは常にHTTPリクエストを送信します。サーバーはHTTP 304ステータスコード(「変更なし」)で応答します。これにより、サーバーは、イメージがクライアントに表示されたことを記録できます。その結果、広告ネットワークが一般的にネットワークキャッシュサーバーをバイパスするためにランダム化されたイメージ名の使用を停止しました。

これにより、広告ネットワークに必要なもの(表示されたすべての画像の記録)が提供され、ISPに必要なもの(キャッシュ可能な画像と静的コンテンツ)が提供されました。

そのため、ブラウザがキャッシュされたページ要素のHTTPリクエストを送信するのを防ぐためにできることはあまりありません。

ただし、html5に付属する他の利用可能なクライアント側ソリューションを見ると、リソースの読み込みを防ぐスコープがあります

  1. キャッシュマニフェスト (その落とし穴にもかかわらず)
  2. IndexedDB (素敵な非同期機能、blobストレージを許可)
  3. ローカルストレージ (非同期ではない)
28
Jason Buberel

「リロード」と「リフレッシュ」には違いがあります。通常、戻るボタンと進むボタンを使用してページに移動しても、新しいHTTPリクエストは開始されませんが、特にF5を押してページを「更新」すると、ブラウザーはキャッシュを再確認します。これはブラウザに依存しますが、FFおよびChrome(つまり、ネットワークトラフィックを簡単に監視できるブラウザ))の標準であるようです。次に「実行」します。これにより、ページがリロードされますが、ページ上のアセットは再確認されません。

Update:前後のナビゲーション動作の明確化。ブラウザでは「バックフォワードキャッシュ」またはBFCacheと呼ばれます。戻る/進むボタンを使用してナビゲートするときの目的は、自分のタイムラインでページを見たときとまったく同じように表示することです。サーバーキャッシュヘッダーが特定のアイテムの有効期限が切れていると言っても、前後に使用する場合、サーバー要求は行われません。

開発者のネットワークパネルに(200 OK BFCache)と表示されている場合、サーバーはヒットしませんでした-if-modified-sinceを要求することもありません。

http://www.softwareishard.com/blog/firebug/firebug-tip-what-the-heck-is-bfcache/

12
chugadie

F5またはF5 + Ctrlを使用して強制的に更新すると、要求が送信されます。ただし、ブラウザを閉じて再度URLを入力すると、要求は送信されません。リクエストが送信されているかどうかをテストする方法は、リクエストが送信されていない場合でもサーバー上の開始リクエストでブレークポイントを使用することで、7ミリ秒の待機を行ったとしてFirebugに表示されます。

7
Peter Lundsby

ここで説明していることは、私の経験を反映していません。コンテンツがno-storeディレクティブで提供される場合、または明示的な更新を行う場合は、はい、Originサーバーに戻ることを期待します。そうでない場合は、ブラウザーの再起動時にキャッシュされる必要があります(許可され、書き込みが可能な場合)キャッシュファイル)。

あなたの滝をもう少し詳しく見ると(少し小さくぼやけているので注意が必要です)、ブラウザは正確にすべきことをしているように見えます-それhas画像のエントリ-しかし、これらはローカルキャッシュからをロードするだけで、Originサーバーからではなく-応答の「Date」ヘッダーを確認します(秒ではなくミリ秒かかっていると思われますか?)。だから色が違うのです。

6
symcbean

妥当な答えを探すのにかなりの時間を費やした後、以下のリンクが最も有用であることがわかり、ここで尋ねられた質問に答えています。

https://webmasters.stackexchange.com/questions/25342/headers-to-prevent-304-if-modified-since-head-requests

4
dev-vb

Chromeは実際のHTTPリクエストの記録ではありません-アセットリクエストの記録です。Chromeはアセットを表示するためにこれを行いますただし、このビューは実際にリクエストが行われているかどうかを示すものではありません。アセットがキャッシュされている場合、Chromeは実際に基になるHTTPリクエストを作成しません。

これを確認するには、タイムラインの紫色のセグメントにカーソルを合わせます。キャッシュされたリソースには(from cache)ツールチップ。

実際のHTTPリクエストを確認するには、下位レベルを調べる必要があります。一部のブラウザでは、これはプラグイン(ライブHTTPヘッダーなど)で実行できます。

しかし実際には、要求が実際に行われていないことを確認するには、サーバーログを確認するか、CharlesやFiddlerなどのデバッグプロキシを使用する必要があります。これはHTTPレベルで機能し、リクエストが実際に発生していないことを確認します。

0
wharding28

この質問には、ウェブマスターのスタック交換サイトでより良い答えがあります here .

上記のリンクでも引用されている詳細情報は、 httpwatch にあります。

記事によると:

キャッシュされたエントリが有効かどうかを確認する必要があるInternet Explorerの状況はいくつかあります。

  • キャッシュされたエントリには有効期限がなく、ブラウザセッションで初めてコンテンツにアクセスしています
  • キャッシュされたエントリには有効期限がありますが、有効期限が切れています
  • ユーザーが[更新]ボタンをクリックするか、F5を押して、ページの更新を要求しました

    ここにコードを入力してください

0

キャッシュの検証と304応答

キャッシュされたエントリが有効かどうかを確認する必要があるInternet Explorerの状況はいくつかあります。

  • キャッシュされたエントリには有効期限がなく、ブラウザセッションで初めてコンテンツにアクセスしています

  • キャッシュされたエントリには有効期限がありますが、有効期限が切れています

  • ユーザーが[更新]ボタンをクリックするか、F5を押してページの更新を要求しました

キャッシュされたエントリに最終変更日がある場合、IEはGET要求メッセージのIf-Modified-Sinceヘッダーでそれを送信します。

GET /images/logo.gif HTTP/1.1
Accept: */*
Referer: http://www.google.com/
Accept-Encoding: gzip, deflate
If-Modified-Since: Thu, 23 Sep 2004 17:42:04 GMT
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;)
Host: www.google.com

サーバーはIf-Modified-Sinceヘッダーをチェックし、それに応じて応答します。指定された日付/時刻以降にコンテンツが変更されていない場合、ステータスコード304およびヘッダーのみを含む応答メッセージで応答します。

HTTP/1.1 304 Not Modified
Content-Type: text/html
Server: GWS/2.1
Content-Length: 0
Date: Thu, 04 Oct 2004 12:00:00 GMT

応答にはコンテンツが含まれておらず、IEが必要なデータをキャッシュから読み取るため、実際にはローカルブラウザーキャッシュへのリダイレクトのようになります。

要求されたオブジェクトがIf-Modified-Sinceヘッダーの日付/時刻以降に実際に変更された場合、サーバーはステータスコード200で応答し、変更されたバージョンのリソースを提供します。

0
Rakesh

生死の問題の場合(この方法でページの読み込みを最適化したい場合、またはサーバーの負荷を可能な限り削減したい場合)、IS =回避策。

HTML5ローカルストレージを使用して、初めて要求された後の画像をキャッシュします。

  • [+]ブラウザがHTTPリクエストを送信しないようにすることができます。 、ctrl + F5、ページの再訪など)

  • [-]このために、javascriptサポートにいくつかの特別な努力をする必要があります。

  • [-]画像はbase64に保存されます(バイナリデータは保存できません)。そのため、クライアント側で毎回デコードされます。これは通常かなり高速で大したことではありませんが、それでもクライアント側での余分なCPU使用量であり、留意する必要があります。

  • [-]ローカルストレージは制限されています。ドメインごとに最大5 MBのデータを使用することを目的とすることができます(注:base64は画像の元のサイズに最大30%を追加します)。

  • [?]majorityのブラウザでサポートされています。 http://caniuse.com/#search=localstorage

テスト

0
djeendo