Skip to content

浅析浏览器缓存

什么是浏览器缓存?

浏览器缓存是指浏览器在本地磁盘对用户访问过的网页资源进行存储的一种机制。这些资源包括HTML页面、JavaScript文件、CSS样式表、图片等静态资源。当用户再次访问相同的资源时,浏览器可以直接从本地加载,而不需要重新向服务器请求。

为什么需要浏览器缓存?

浏览器缓存的重要性体现在以下几个方面:

  1. 提升页面加载速度:从本地读取资源比从服务器获取要快得多
  2. 减少服务器负载:降低了服务器的请求压力
  3. 节省网络带宽:减少了不必要的网络传输
  4. 改善用户体验:更快的响应速度带来更好的用户体验

浏览器缓存的分类

浏览器缓存主要分为三大类:

1. 强缓存(Strong Cache)

强缓存是指在缓存期间不需要请求服务器,直接使用本地缓存的一种机制。通过以下HTTP头部字段来控制:

  • Expires(HTTP/1.0)

    • 指定资源的过期时间(GMT格式)
    • 受限于客户端时间,如果客户端时间不准确会有问题
  • Cache-Control(HTTP/1.1)

    • 更细粒度的缓存控制
    • 常用指令:
      • max-age:缓存的最大有效时间(秒)
      • no-cache:强制向服务器验证,跳过强缓存
      • no-store:不缓存任何内容
      • private:仅浏览器可以缓存
      • public:所有中间节点都可以缓存

2. 协商缓存(Negotiation Cache)

当强缓存失效后,浏览器会携带缓存标识向服务器发起请求,由服务器决定是否使用缓存。主要通过以下两对HTTP头部字段实现:

  • Last-Modified/If-Modified-Since

    • Last-Modified:服务器响应资源的最后修改时间
    • If-Modified-Since:客户端再次请求时带上的上次响应的Last-Modified值
  • ETag/If-None-Match

    • ETag:服务器响应资源的唯一标识
    • If-None-Match:客户端再次请求时带上的上次响应的ETag值
    • 比Last-Modified更精确,但计算ETag值会消耗服务器资源

3. 启发式缓存(Heuristic Caching)

当服务器响应中没有设置任何缓存控制头(如Cache-Control或Expires)时,浏览器会采用启发式缓存策略:

  • 如果响应中包含Last-Modified头,浏览器会根据资源的最后修改时间来估算缓存时间
  • 不同浏览器有不同的启发式缓存策略:
    • Firefox:会将响应时间和当前时间之差的10%作为缓存时间
    • Chrome:通常将资源缓存很短的时间(几秒到几分钟不等)
    • Safari:也有自己的启发式算法,具体策略可能随版本变化
  • 例如:在Firefox中,如果一个资源的Last-Modified标识它在10天前被修改,则启发式缓存可能会将其缓存1天

由于不同浏览器的启发式缓存策略不同且可能随版本更新而变化,为了确保一致的缓存行为,强烈建议始终明确设置缓存控制头。

缓存流程

  1. 强缓存流程

    • 浏览器首次请求资源,服务器返回资源,并在响应头中设置缓存控制字段
    • 在缓存有效期内,浏览器直接使用本地缓存,不会发送请求到服务器
    • 状态码显示为200(from disk cache或from memory cache)
  2. 协商缓存流程

    • 强缓存失效后,浏览器携带缓存标识发起请求
    • 服务器根据缓存标识判断资源是否变化
    • 如果资源未变化,返回304 Not Modified,浏览器使用本地缓存
    • 如果资源已变化,返回200和新的资源内容

缓存设置及最佳实践

1. 服务器配置示例

Nginx配置示例

nginx
# 静态资源缓存设置
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    expires 7d;  # 设置过期时间为7天
    add_header Cache-Control "public, no-transform";
}

Node.js Express示例

javascript
app.use(express.static('public', {
    maxAge: '7d',  // 设置静态资源缓存7天
    setHeaders: function (res, path, stat) {
        res.set('Cache-Control', 'public, no-transform');
    }
}));

2. 最佳实践

  1. 针对不同资源采用不同的缓存策略

    • HTML入口页面:禁用缓存(no-store),确保每次都获取最新版本
    • CSS、JS、图片等静态资源:强缓存,设置较长过期时间,依靠入口页打包时引用资源路径变化而更新
    • API响应:根据数据实时性要求设置适当的缓存策略
  2. 使用版本号或哈希

    • 为静态资源文件名添加版本号或哈希值
    • 当资源内容更新时,文件名变化,自动破除缓存
  3. 合理设置缓存时间

    • 频繁变动的资源设置短期缓存或不缓存
    • 静态资源设置长期缓存
    • 考虑用户体验和服务器负载的平衡
  4. 使用CDN

    • 结合CDN的缓存机制
    • 配置适当的缓存控制头
  5. 避免常见错误

    • 不要对经常变化的资源设置长期缓存
    • 记得为缓存设置合适的失效策略
    • 注意移动端的缓存特性

通过合理配置浏览器缓存,可以显著提升网站性能,改善用户体验。在实际应用中,需要根据具体场景和需求,选择合适的缓存策略。

本站所有内容均为原创,转载请注明出处