浏览器缓存

浏览器缓存是一种存储机制,它允许浏览器将网页的部分或全部内容(如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';
  
  // 获取文件的哈希值作为ETag
  fs.readFile(filePath, (err, data) => {
    if (err) {
      res.writeHead(500);
      res.end('Internal Server Error');
      return;
    }

    const etag = `"${Buffer.from(data).toString('base64')}"`; // 使用文件内容的Base64编码作为ETag
    const 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. 支持快速重载:

    • 用户刷新页面时,浏览器可以从缓存中快速加载页面,而不是每次都从服务器获取最新内容。
  • 31
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值