使用 HTTP 缓存防止不必要的网络请求

简介: 使用 HTTP 缓存防止不必要的网络请求

原文


通过网络获取资源既缓慢又昂贵:


大型响应需要浏览器和服务器之间的多次往返。

直到所有关键资源都完全下载后,您的页面才会加载。

如果一个人使用有限的移动数据计划访问您的网站,那么每个不必要的网络请求都是在浪费他们的钱。

如何避免不必要的网络请求? 浏览器的 HTTP 缓存是您的第一道防线。 它不一定是最强大或最灵活的方法,它对缓存响应的生命周期的控制有限,但它是有效的,所有浏览器都支持它,并且不需要太多工作。


实际上没有一个称为 HTTP 缓存的 API。 它是 Web 平台 API 集合的总称。 所有浏览器都支持这些 API:


Cache-Control

ETag

Last-Modified

HTTP cache 的工作原理

浏览器发出的所有 HTTP 请求都首先路由到浏览器缓存,以检查是否存在可用于满足请求的有效缓存响应。如果匹配,则从缓存中读取响应,从而消除网络延迟和传输产生的数据成本。


HTTP 缓存的行为由请求标头和响应标头的组合控制。在理想情况下,您可以控制 Web 应用程序的代码(将确定请求标头即 HTTP request headers)和 Web 服务器的配置(将确定响应标头即 HTTP response headers)。


Request headers: stick with the defaults (usually)

虽然有许多重要的标头应该包含在您的 Web 应用程序的传出请求中,但浏览器在发出请求时几乎总是代表您进行设置。 影响检查新鲜度的请求标头,如 If-None-Match 和 If-Modified-Since 只是基于浏览器对 HTTP 缓存中当前值的理解而出现。


这是个好消息——这意味着您可以继续在 HTML 中包含诸如下列例子之类的标签,并且浏览器会自动为您处理 HTTP 缓存,而无需额外的努力。


1

Response headers: configure your web server

HTTP 缓存设置中最重要的部分是您的 Web 服务器添加到每个传出响应的标头。 以下标头都会影响有效的缓存行为:


Cache-control: 服务器可以返回一个 Cache-Control 指令来指定浏览器和其他中间缓存应该如何缓存单个响应以及缓存多长时间。


ETAG: 当浏览器发现过期的缓存响应时,它可以向服务器发送一个小令牌(通常是文件内容的哈希)以检查文件是否已更改。 如果服务器返回相同的令牌,则文件是相同的,无需重新下载。


Last-Modified: 此标头与 ETag 的用途相同,但使用基于时间的策略来确定资源是否已更改,这与 ETag 的基于内容的策略相反。


默认情况下,某些 Web 服务器内置支持设置这些标头,而其他 Web 服务器则完全保留标头,除非您明确配置它们。 如何配置标头的具体细节因您使用的 Web 服务器而异,您应该查阅服务器的文档以获得最准确的详细信息。


省略 Cache-Control 响应标头不会禁用 HTTP 缓存! 相反,浏览器有效地猜测哪种类型的缓存行为对给定类型的内容最有意义。 您可能需要更多的控制权,因此请花时间配置您的响应标头。


在配置 Web 服务器的响应标头时,您应该涵盖两个重要的场景。


Long-lived caching for versioned URLs

假设您的服务器指示浏览器将 CSS 文件缓存 1 年(Cache-Control: max-age=31536000),但您的设计人员刚刚进行了一个需要立即推出的紧急更新。您如何通知浏览器更新文件的“陈旧”缓存副本?你不能,至少不能不改变资源的 URL。在浏览器缓存响应后,缓存版本将一直使用,直到它不再是最新的,这由 max-age 或 expires 决定,或者直到它因某些其他原因从缓存中被驱逐——例如,用户清除他们的浏览器缓存。因此,在构建页面时,不同的用户最终可能会使用不同版本的文件:刚刚获取资源的用户使用新版本,而缓存较早(但仍然有效)副本的用户使用其旧版本回复。您如何获得两全其美:客户端缓存和快速更新?您更改资源的 URL 并强制用户在其内容更改时下载新响应。通常,您可以通过在文件名中嵌入文件的指纹或版本号来实现这一点,例如 style.x234dff.css。


当响应包含“指纹”或版本信息且其内容永远不会改变的 URL 请求时,请将 Cache-Control: max-age=31536000 添加到您的响应中。


设置这个值告诉浏览器,当它需要在接下来的一年内的任何时候(31,536,000 秒;支持的最大值)加载相同的 URL 时,它可以立即使用 HTTP 缓存中的值,而无需向网络发出请求 你的网络服务器。 太好了 - 您立即获得了避免网络带来的可靠性和速度!


像 webpack 这样的构建工具可以自动化将哈希指纹分配给资产 URL 的过程。


Server revalidation for unversioned URLs

不幸的是,并非您加载的所有 URL 都是版本化的。


也许您无法在部署 Web 应用程序之前包含构建步骤,因此您无法向资产 URL 添加哈希值。 并且每个 Web 应用程序都需要 HTML 文件——这些文件(几乎!)永远不会包含版本信息,因为如果他们需要记住要访问的 URL 是 https://example.com,那么没有人会费心使用您的 Web 应用程序 /index.34def12.html。 那么你能对这些 URL 做些什么呢?


这是您需要承认失败的一种情况。 单独的 HTTP 缓存不足以完全避开网络 request. 但是你可以采取一些步骤来确保网络请求尽可能快, 并尽可能高效。


以下 Cache-Control 值可以帮助您微调未版本控制的 URL 的缓存位置和方式:


no-cache: 这会指示浏览器每次使用 URL 的缓存版本之前都必须与服务器重新验证。

no-store: 这会指示浏览器和其他中间缓存(如 CDN)从不存储文件的任何版本。

private: 浏览器可以缓存文件,但中间缓存不能。

public: 响应可以由任何缓存存储。

Etag 使用例子


image.png

浏览器从服务器请求 /file 并包含 If-None-Match 标头以指示服务器仅在服务器上文件的 ETag 与浏览器的 If-None-Match 值不匹配时才返回完整文件。 在这种情况下,这 2 个值确实匹配,因此服务器返回 304 Not Modified 响应,并说明文件应缓存多长时间(Cache-Control: max-age=120)。


总结

HTTP Cache 是一种提高负载性能的有效方式,因为它减少了不必要的网络请求。 它在所有浏览器中都受支持,并且不需要太多设置。


以下 Cache-Control 配置是一个好的开始:


Cache-control: no-cache - 对于每次使用前应与服务器重新验证的资源


Cache-control:no-store: - 不应该缓存的资源


Cache-control: max-age=31536000:版本化资源


相关文章
|
12天前
|
JSON 网络协议 数据格式
网络协议基础:HTTP请求与响应详解
【7月更文挑战第11天】HTTP协议作为Web通信的核心,其请求与响应机制是理解网络通信的关键。本文详细介绍了HTTP请求与响应的格式、过程以及常用的请求方法,帮助读者更好地理解HTTP协议的工作原理和应用场景。在实际应用中,HTTP协议的可定制性和灵活性使其能够适应多种
|
20天前
|
安全 网络协议 Java
Java中的网络通信:HTTP详解
Java中的网络通信:HTTP详解
|
28天前
|
缓存 网络协议 安全
Android网络面试题之Http基础和Http1.0的特点
**HTTP基础:GET和POST关键差异在于参数传递方式(GET在URL,POST在请求体),安全性(POST更安全),数据大小限制(POST无限制,GET有限制),速度(GET较快)及用途(GET用于获取,POST用于提交)。面试中常强调POST的安全性、数据量、数据类型支持及速度。HTTP 1.0引入了POST和HEAD方法,支持多种数据格式和缓存,但每个请求需新建TCP连接。**
28 5
|
25天前
|
缓存 负载均衡 NoSQL
Redis系列学习文章分享---第十四篇(Redis多级缓存--封装Http请求+向tomcat发送http请求+根据商品id对tomcat集群负载均衡)
Redis系列学习文章分享---第十四篇(Redis多级缓存--封装Http请求+向tomcat发送http请求+根据商品id对tomcat集群负载均衡)
40 1
|
1月前
|
域名解析 存储 缓存
HTTP请求流程概览:浏览器构建请求行含方法、URL和版本;检查缓存;解析IP与端口
【6月更文挑战第23天】 HTTP请求流程概览:浏览器构建请求行含方法、URL和版本;检查缓存;解析IP与端口;TCP连接(HTTP/1.1可能需排队);三次握手;发送请求头与体;服务器处理并返回响应;TCP连接可能关闭或保持;浏览器接收并显示响应,更新缓存。HTTP版本间有差异。
37 5
|
27天前
|
缓存 网络协议 Android开发
Android网络面试题之Http1.1和Http2.0
HTTP/1.1 引入持久连接和管道机制提升效率,支持分块传输编码和更多请求方式如PUT、PATCH。Host字段指定服务器域名,RANGE用于断点续传。HTTP/2变为二进制协议,实现多工处理,头信息压缩和服务器推送,减少延迟并优化资源加载。HTTP不断发展,从早期的简单传输到后来的高效交互。
26 0
Android网络面试题之Http1.1和Http2.0
|
10天前
|
网络协议 安全 Python
我们将使用Python的内置库`http.server`来创建一个简单的Web服务器。虽然这个示例相对简单,但我们可以围绕它展开许多讨论,包括HTTP协议、网络编程、异常处理、多线程等。
我们将使用Python的内置库`http.server`来创建一个简单的Web服务器。虽然这个示例相对简单,但我们可以围绕它展开许多讨论,包括HTTP协议、网络编程、异常处理、多线程等。
|
18天前
|
缓存 JSON 算法
http【详解】状态码,方法,接口设计 —— RestfuI API,头部 —— headers,缓存
http【详解】状态码,方法,接口设计 —— RestfuI API,头部 —— headers,缓存
23 0
|
20天前
|
安全 网络协议 网络安全
计算机网络之HTTP和HTTPS的区别(文末送书福利)
计算机网络之HTTP和HTTPS的区别(文末送书福利)
|
20天前
|
缓存 网络协议 小程序
计算机网络——HTTP 状态码
计算机网络——HTTP 状态码