欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > 浏览器缓存

浏览器缓存

2024/10/26 3:24:30 来源:https://blog.csdn.net/weixin_51416826/article/details/141713225  浏览:    关键词:浏览器缓存

浏览器缓存是一种存储机制,它允许浏览器将网页的部分或全部内容(如HTML文件、图像、JavaScript文件等)存储在用户的本地设备上。这样,当用户再次访问同一个网站时,浏览器可以从缓存中加载这些资源,而不需要重新从服务器下载,从而加快了页面的加载速度并减少了网络流量。

以下是关于浏览器缓存的一些关键概念和技术细节:

类型

  1. 强制缓存 (MUST-Cache):

    • Expires Header: 指定资源过期的时间点。
    • Cache-Control Header: 包含max-age指令来指定资源的有效时间。
  2. 验证缓存 (Validate Cache):

    • 当资源可能已经过期但仍然可能有效时,浏览器会使用条件请求向服务器验证资源是否已更新。
    • Last-Modified 和 If-Modified-Since Headers: 用于检查资源是否已有新的修改版本。
    • ETag 和 If-None-Match Headers: 使用唯一标识符来确定资源是否改变。

如何工作

浏览器第一次加载资源,服务器返回200,浏览器从服务器下载资源文件,并缓存资源文件和response header,以供下次加载时对比使用;

下次加载资源时,由于强制缓存优先级更高,所以会执行强制缓存策略。

基于Expires字段实现的强缓存

在以前,我们通常会使用响应头的Expires字段去实现强缓存。该字段的作用是,设定一个强缓存时间。在此时间范围内,则命中强缓存,直接从内存(或磁盘)中读取缓存返回。但是该字段存在问题:过度依赖本地时间。

基于Cache-control实现的强缓存(代替Expires的强缓存实现方法)

字段在http1.1中被增加,Cache-control完美解决了Expires本地时间和服务器时间不同步的问题。是当下的项目中实现强缓存的最常规方法。

Cache-control的使用方法很简单,只要在资源的响应头上写上需要缓存多久就好了,单位是秒。

Cache-Control: max-age=3600

该字段还有其他属性,详情见:https://blog.csdn.net/hyupeng1006/article/details/126599764

如果资源过期,则表明强制缓存没有被命中,则开始执行协商缓存策略。

基于last-modified的协商缓存

基于 Last-Modified 的协商缓存是一种机制,用于确定客户端(通常是浏览器)中的缓存副本是否仍然是最新的。这种机制依赖于服务器端的 Last-Modified 响应头和客户端发出的 If-Modified-Since 请求头。其具体策略是:

1.在第一次请求时,服务器返回响应,并在响应头中包含 Last-Modified 字段,指示该资源最后一次被修改的时间;

2.缓存资源;

3.再次发送请求访问相同资源,浏览器在请求头中包含 If-Modified-Since 字段,其值为上次接收到的 Last-Modified 值;

4.服务器检查资源的最后修改时间是否与 If-Modified-Since 中的时间相同;

  • 如果资源没有被修改,则服务器返回一个 304 Not Modified 响应,则客户端直接从缓存中加载资源。
  • 如果资源已被修改,则服务器返回一个新的 200 OK 响应,其中包含新的 Last-Modified 时间戳以及资源的新内容,同时更新缓存。
const http = require('http');
const fs = require('fs');const server = http.createServer((req, res) => {const filePath = 'example.html';// 获取文件的最后修改时间fs.stat(filePath, (err, stats) => {if (err) {res.writeHead(500);res.end('Internal Server Error');return;}const lastModifiedTime = stats.mtime.toUTCString();const ifModifiedSince = req.headers['if-modified-since'];// 检查是否需要发送304响应if (ifModifiedSince === lastModifiedTime) {res.writeHead(304);res.end();} else {// 发送200响应res.writeHead(200, { 'Last-Modified': lastModifiedTime });fs.createReadStream(filePath).pipe(res);}});
});server.listen(3000, () => {console.log('Server running on port 3000');
});
优点
  • 减少了不必要的数据传输,提高了性能。
  • 降低了服务器负载。
缺点
  • 只能精确到秒,如果资源在同一秒内多次修改,可能会导致缓存问题。
  • 如果资源经常在短时间内被修改,可能会导致额外的网络请求。
基础ETag的协商缓存

为了克服 Last-Modified 的缺点,通常会结合使用 ETagETag 提供了一个唯一的标识符(文件指纹)来区分资源的不同版本,即使是同一秒内的修改也能被识别出来。

其具体流程与last-modified类似,只不过是将标识符赋给if-None-Match字段,并进行对比。

const http = require('http');
const fs = require('fs');const server = http.createServer((req, res) => {const filePath = 'example.html';// 获取文件的哈希值作为ETagfs.readFile(filePath, (err, data) => {if (err) {res.writeHead(500);res.end('Internal Server Error');return;}const etag = `"${Buffer.from(data).toString('base64')}"`; // 使用文件内容的Base64编码作为ETagconst ifNoneMatch = req.headers['if-none-match'];// 检查是否需要发送304响应if (ifNoneMatch === etag) {res.writeHead(304);res.end();} else {// 发送200响应res.writeHead(200, { 'ETag': etag });res.end(data);}});
});server.listen(3000, () => {console.log('Server running on port 3000');
});

总结:

浏览器缓存有许多优势,主要体现在以下几个方面:

  1. 提高加载速度:

    • 浏览器可以直接从缓存加载资源,而无需从服务器获取,这显著加快了页面的加载速度。
  2. 减少网络流量:

    • 由于减少了重复的数据传输,网络流量得到节约,这对于移动网络环境尤为重要。
  3. 降低服务器负载:

    • 服务器不必频繁地处理重复的请求,减轻了服务器的压力。
  4. 改善用户体验:

    • 快速加载的页面让用户感觉更流畅,提升了整体的用户体验。
  5. 节省带宽成本:

    • 对于需要支付带宽费用的网站运营者来说,减少数据传输可以节省成本。
  6. 离线访问能力:

    • 即使在网络连接不稳定或断开的情况下,用户仍然可以访问之前缓存的内容。
  7. 提高应用性能:

    • 对于单页应用(SPA)和 Progressive Web Apps (PWA),合理的缓存策略能够提升应用的响应速度和可用性。
  8. 减少延迟:

    • 通过减少从远程服务器获取数据所需的往返时间,缓存可以降低延迟。
  9. 支持快速重载:

    • 用户刷新页面时,浏览器可以从缓存中快速加载页面,而不是每次都从服务器获取最新内容。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com