キャッシュの目的は、クライアントとサーバー間のデータ送信を削減して、サーバーへの負荷を軽減し、クライアント エクスペリエンスを最適化することです。たとえば、サイトでは、一部の依存リソースは 10 年間変更されない場合がありますWeb
。リソースの種類はキャッシュに非常に適しています。よく言われるキャッシュには、「強キャッシュ」と「ネゴシエーションキャッシュ(弱キャッシュ)」の2種類があります。
Http1.1
プロトコル仕様
強力なキャッシュ キャッシュ制御
主な用途はCache-control
レスポンス ヘッダーです。たとえばCache-Control:max-age=3600
、リソースがリクエスト ヘッダーを設定し、1 時間以内にリソースを再度キャッシュするとき ( url
)、サーバーに再度リクエストするのではなく、キャッシュから直接読み取ります。上のZhihuのとあるページで読み込まれたスクリプトjavascript
リクエストヘッダに設定されていますcache-control:max-age=31536000
この秒数は1年に換算されます 1年以内に再訪問した場合はサーバーにはリクエストしません ブラウザもステータスをリクエストしていますメモリキャッシュからマークされた後のコード ( from memory cache
)
ネゴシエーション キャッシュ Etag
リソースをリクエストすると、サーバーはetag
レスポンス ヘッダーと呼ばれる特性値を返します。強力なキャッシュの有効期限が切れると、ブラウザは自動的に という名前のリクエスト ヘッダーを送信しますIf-None-Match
。その値は、レスポンス ヘッダーによって返される値ですetag
。これは、ロゴを使用してサーバーにアクセスするのと同じであり、このリソースが現在更新されるべきか、返されるかどうかは200
サーバー304
に完全に依存します。
- を返し
304
、リソースが変更されていないことをクライアントに伝え、その使用を継続し、強力なキャッシュ時間 (設定されている場合) の計算を再開します。 - return
200
、リソースを削除できることをクライアントに伝え、サーバーは新しいリソースを返します
実践検証用の静的サーバーを構築する
理解しやすいように、これはテストを容易にするための単純な構成nginx
として使用されます。8080
ポートは次のように構成され、/Users/mongielee/cache-demo
独自のサイト パスに変更されます。サイトには 2 つのファイルのみが必要です。1 つとindex.html
1 つだけです。main.js
server {
listen 8080;
server_name localhost;
location / {
root /Users/mongielee/cache-demo;
index index.html index.htm;
}
location ~ \.js$ {
root /Users/mongielee/cache-demo;
add_header Cache-Control max-age=10;
}
}
复制代码
这里的配置主要是add_header Cache-Control max-age=10
,该配置为所有js
后缀的资源都添加了10s
都缓存时间,文件内容如下
启动或重启nginx
服务后,访问localhost:8080
可以看到响应头中携带着文件标识etag
和强缓存比标记cache-control
,此时十秒内再次访问main.js
资源,浏览器不会再发请求而是使用内存缓存
当10
秒过后再访问main.js
,浏览器就在请求头带上If-None-Match
标记,值为上一次请求的响应头中的etag
,带上If-None-Match
这一步浏览器会自动处理,此时返回的状态码就是304
,说明文件没有被修改,此时重新计算Cache-Control
的值
如果在二次请求前,服务器文件被修改,那么在强缓存过期后,协商缓存会返回200
状态码,原因是请求头的etag
值与服务器计算的不一致,下面图中,服务端新返回的etag
是xxx-1e
,而请求头带的是xx-1a
,说明文件被修改过
Http1.0
协议规范
之所以和1.1
有不同的内容,原因是1.0
并没有设计好,与Cache-Control
和etag
相对应的是Expires
和Last-Modified
强缓存Expires
使用该响应头返回客户端一个时间值,那么导致的问题就是如果客户端修改了时间,那么缓存直接就失效了,以及需要注意的地方是,当cache-control
和expires
同时设置时,会忽略掉expires
,使用cache-control
。在Expires
的指定时间内(客户端时间),都会从缓存中读取
协商缓存If-Modified-Since
時間が経過するとExpires
、リソースが再度アクセスされるときにリソース リクエスト ヘッダーが追加され、If-Modified-Sice
値は前のリクエストの応答ヘッダーの値になりますLast-Modified
。サーバーはファイルの最終変更時刻とリクエスト ヘッダーを比較しますIf-Modified-Since
。と が同時に設定されている場合は、それが優先304
されます。etag
last-modified
etag
1.1
1.0
この方法の欠点は、精度が第 2 レベルまでであるため、1 秒以内にファイルが 2 回 (複数回) 変更されると、結果が正しくなくなることです。以下の図の 2 つの時間比較は一貫しているため、返される304
1.1 仕様のキャッシュ制御と etag を優先する必要があります。
どのファイルをキャッシュする必要がありますか?
この質問に対する標準的な答えはありません。プロジェクトの要件に完全に依存しますが、サイトのホームページをキャッシュしてはなりません。キャッシュしないと、バージョン反復後の新しいコンテンツが読み込まれなくなります。ただし、一般的なブラウザではこの砂像の動作が禁止されます。
以上:)