Skip to content

HTTP缓存机制

一: HTTP缓存简介

HTTP缓存机制是Web开发中用于提高性能和减少网络流量的关键机制。它通过在客户端和服务器之间存储资源的副本,以便在将来的请求中直接使用这些缓存的资源,而无需重新请求服务器。以下是HTTP缓存机制的关键概念和常见的缓存策略:

1. 缓存控制头部:

HTTP缓存机制主要通过一系列的缓存控制头部来实现。常见的缓存控制头部包括:

  • Expires: 由服务器返回,指定资源的过期时间,即资源将在此时间后失效。

    http
    Expires: Wed, 21 Oct 2022 07:28:00 GMT
  • Cache-Control: 提供更灵活的缓存控制,包括max-age(资源在缓存中的最长时间)等。

    http
    Cache-Control: max-age=3600
  • Last-Modified 和 If-Modified-Since: 服务器通过Last-Modified头部指定资源的最后修改时间,客户端可以通过If-Modified-Since头部将上一次的最后修改时间发送给服务器,以检查资源是否发生了变化。

    http
    Last-Modified: Tue, 20 Oct 2022 10:00:00 GMT
    If-Modified-Since: Tue, 20 Oct 2022 10:00:00 GMT
  • ETag 和 If-None-Match: 服务器通过ETag头部指定资源的唯一标识符,客户端可以通过If-None-Match头部将上一次的ETag值发送给服务器,以检查资源是否发生了变化。

    http
    ETag: "abc123"
    If-None-Match: "abc123"

2. 缓存策略:

常见的缓存策略包括:

  • 强缓存: 客户端直接使用本地缓存而不与服务器进行交互。通过设置ExpiresCache-Control中的max-age实现。

  • 协商缓存: 缓存过期,但客户端与服务器协商是否需要重新获取新的资源。通过使用Last-ModifiedIf-Modified-SinceETagIf-None-Match实现。

  • 禁用缓存: 使用Cache-Control头部中的no-storeno-cache指令,或设置Expires为过去的时间,来禁用缓存。

    http
    Cache-Control: no-store
    Cache-Control: no-cache
    Expires: Thu, 01 Jan 1970 00:00:00 GMT
  • 刷新缓存: 使用Cache-Control头部中的must-revalidate指令,表示缓存过期后必须向服务器验证资源是否仍然有效。

    http
    Cache-Control: must-revalidate
  • 代理缓存: 通过设置Cache-Control头部中的publicprivate指令,控制代理服务器是否可以缓存资源。

    http
    Cache-Control: public
    Cache-Control: private

这些缓存策略可以根据资源的性质和应用程序的需求进行调整,以达到最佳的性能和用户体验。在制定缓存策略时,需要权衡资源更新频率、网络成本和用户体验。

二: HTTP缓存补充

http缓存是通过在客户端(浏览器)和服务器之间存储响应的一种机制,以便在将来的请求中直接使用缓存的响应,而无需重新请求服务器。这有助于提高网站性能,减少对服务器的请求次数,并加快页面加载速度。

HTTP缓存的两种主要类型:

  1. 强缓存(Freshness): 缓存不过期,客户端直接使用本地缓存而不与服务器进行交互。
    • Expires头部: 指定缓存的过期时间,由服务器返回。
    • Cache-Control头部: 提供更灵活的缓存控制,可以指定最大缓存时间,如max-age
http
Expires: Wed, 21 Oct 2022 07:28:00 GMT
Cache-Control: max-age=3600 
// 缓存中最长保存1小时
  1. 协商缓存(Validation): 缓存过期,但客户端与服务器协商是否需要重新获取新的资源。
    • Last-Modified头部: 指示资源的最后修改时间。
    • ETag头部: 提供一个资源的唯一标识符,由服务器生成。
http
Last-Modified: Tue, 20 Oct 2022 10:00:00 GMT
ETag: "abc123"

HTTP状态码304:

当客户端发起一个请求时,如果本地缓存尚未过期,但需要验证是否仍然有效,客户端会发送一个包含If-Modified-SinceIf-None-Match头部的请求。服务器会根据这些头部的值,判断资源是否发生了变化。

如果资源未发生变化,服务器会返回状态码304(Not Modified),告诉客户端可以使用本地缓存,从而避免重新传输整个资源。这可以减少带宽使用和加快加载速度。

前端实战如何使用HTTP状态码304:

  1. 使用Last-Modified和If-Modified-Since:

    在请求头中添加If-Modified-Since,将上一次服务器返回的Last-Modified值传递给服务器。

    javascript
    const lastModified = getLastModifiedDate(); // 从本地缓存或其他地方获取上次修改时间
    fetch(url, {
        method: 'GET',
        headers: {
            'If-Modified-Since': lastModified,
        },
    }).then(response => {
        if (response.status === 304) {
            // 使用本地缓存
        } else {
            // 处理新的响应
            updateLocalCache(response);
        }
    });
  2. 使用ETag和If-None-Match:

    在请求头中添加If-None-Match,将上一次服务器返回的ETag值传递给服务器。

    javascript
    const etag = getETag(); // 从本地缓存或其他地方获取上次ETag值
    fetch(url, {
        method: 'GET',
        headers: {
            'If-None-Match': etag,
        },
    }).then(response => {
        if (response.status === 304) {
            // 使用本地缓存
        } else {
            // 处理新的响应
            updateLocalCache(response);
        }
    });

在实际应用中,选择使用Last-Modified还是ETag取决于服务器的支持情况和资源的特性。通常来说,ETag更为精确,但会增加一些计算开销。前端开发者可以根据项目的具体情况来选择适当的方式。

三: 利用HTTP缓存是前端优化中的重要策略之一,它可以显著提高网站性能,减少页面加载时间。

以下是一些利用HTTP缓存来优化网站性能的方法:

1. 设置合适的缓存头部:

确保服务器返回适当的缓存头部,包括Cache-ControlExpiresLast-ModifiedETag等。通过设置合适的缓存头部,可以控制资源的缓存时间、过期策略以及协商缓存。

http
Cache-Control: max-age=3600
Expires: Wed, 21 Oct 2022 07:28:00 GMT
Last-Modified: Tue, 20 Oct 2022 10:00:00 GMT
ETag: "abc123"

2. 使用强缓存:

通过Cache-Controlmax-ageExpires头部,实现强缓存,使得浏览器能够直接从本地缓存中获取资源,而不必再次请求服务器。

http
Cache-Control: max-age=3600

3. 使用协商缓存:

通过Last-ModifiedIf-Modified-SinceETagIf-None-Match头部,实现协商缓存,允许服务器验证资源是否已经发生变化,避免不必要的数据传输。

http
Last-Modified: Tue, 20 Oct 2022 10:00:00 GMT
If-Modified-Since: Tue, 20 Oct 2022 10:00:00 GMT

4. 版本控制:

在资源的URL中添加版本号或哈希值,以确保每次更新时,URL都会发生变化,从而强制浏览器获取新的资源。

html
<link rel="stylesheet" href="styles.css?v=1.0">

5. 使用Service Worker:

利用Service Worker可以实现更灵活的缓存策略,包括离线缓存和动态缓存。Service Worker可以拦截网络请求,从缓存中返回资源,或者向缓存中存储新的资源。

6. 使用CDN:

使用内容分发网络(CDN)可以将静态资源分布到全球多个服务器节点上,减少资源的加载时间,同时CDN通常会自动处理缓存机制,提高访问速度。

7. 缓存资源文件:

将不经常变化的静态资源文件如图片、样式表、脚本等进行缓存,减少不必要的网络请求,加快页面加载速度。

html
<link rel="stylesheet" href="styles.css" />
<img src="image.jpg" alt="Image" />
<script src="script.js"></script>

8. 使用响应式图片:

通过使用srcset属性,提供多个不同尺寸的图片,浏览器可以根据设备的屏幕大小选择适当的图片,减少不必要的下载。

html
<img srcset="image-1x.jpg 1x, image-2x.jpg 2x" src="image-1x.jpg" alt="Image">

综合使用这些策略,可以最大程度地减少资源加载时间,提高网站性能,增强用户体验。在实际应用中,需要根据具体的项目需求和特点来选择和调整缓存策略。