第八篇 提升网页性能:深入解析HTTP请求优化策略(三)

简介: 第八篇 提升网页性能:深入解析HTTP请求优化策略(三)


HTTP请求优化策略中,缓存策略设计与实施是提高页面加载速度、减少服务器负载并改善用户体验的关键手段。

1. 缓存策略设计

1.1 HTTP缓存机制

1.1.1 强缓存(Cache-Control/Expires)

通过Cache-Control头部字段或旧版的Expires头部指定资源的有效期,浏览器在有效期内直接使用本地缓存而不发起网络请求。例如,设置Cache-Control: max-age=3600表示资源在接下来的一个小时内可以直接从缓存读取。

用法与原理

强缓存是指在客户端再次发起同一资源请求时,浏览器根据本地存储的缓存信息判断是否可以直接使用缓存中的资源,无需向服务器发送请求确认资源的有效性。这种情况下,即使服务器上的资源已经更新,只要缓存未过期,浏览器仍会直接使用本地缓存。

设置方式

  • Cache-Control HTTP头部字段:现代浏览器广泛支持该字段,可以设置如max-age=<seconds>来指定资源在多少秒内有效。例如,Cache-Control: max-age=3600表示资源在接下来的一个小时内可被强缓存。
  • Expires HTTP头部字段:这是HTTP/1.0时代的做法,用来设置一个绝对时间点,在这个时间之前资源被认为是新鲜的。例如,Expires: Wed, 21 Oct 2024 07:28:00 GMT

何时使用

强缓存通常用于那些变化不频繁的静态资源,比如CSS样式文件、JavaScript脚本、图片等。这些内容在版本不变的情况下不需要每次访问都重新下载,因此通过强缓存策略可以显著降低网络延迟和带宽消耗。

1.1.2 协商缓存(ETag/Last-Modified)

当强缓存过期后,浏览器会发送条件GET请求询问服务器资源是否已改变。通过ETag(实体标签)或Last-Modified(最后修改时间)来判断资源是否需要更新。

用法与原理

当强缓存失效(即超过max-ageExpires设定的时间)后,浏览器不再信任本地缓存,这时它会向服务器发送一个条件GET请求,询问资源是否有更新。协商缓存依赖于以下两个HTTP头部:

ETag(Entity Tag):服务器为每个资源生成一个唯一标识符,通常基于内容哈希值或其他唯一算法得出。浏览器在后续请求中携带If-None-Match头部,并附上之前收到的ETag值,服务器比较新旧ETag,如果一致,则表示

  • 资源未改变,返回304 Not Modified,浏览器继续使用本地缓存;否则,服务器返回新的资源及对应的ETag
  • Last-ModifiedIf-Modified-Since:服务器在首次响应时告知资源最后修改时间(Last-Modified),浏览器下次请求时带上If-Modified-Since头部,服务器对比时间戳,若资源未在该时间之后修改则返回304状态码。

何时使用

协商缓存适用于可能动态变化但又希望利用缓存以提升性能的场景,尤其是对时效性有一定要求但不那么严格的资源。例如博客文章的内容可能会有修订,但不是每次访问都会有改动,这时协商缓存既能确保用户看到最新内容,又能避免不必要的重复下载。

示例

对于一个静态图片资源,服务端可能这样设置响应头:

HTTP/1.1 200 OK
Date: Mon, 06 Jul 2020 15:00:00 GMT
Last-Modified: Wed, 01 Jul 2020 10:00:00 GMT
ETag: "3a489f14"
Cache-Control: max-age=3600, must-revalidate

[... 图片数据 ...]

当缓存过期后,浏览器会带上相应的条件请求头部进行协商缓存验证:

GET /image.jpg HTTP/1.1
Host: example.com
If-None-Match: "3a489f14"
If-Modified-Since: Wed, 01 Jul 2020 10:00:00 GMT

若服务器确定资源未变,则回复:

HTTP/1.1 304 Not Modified
Date: Mon, 06 Jul 2020 16:00:00 GMT

1.2 缓存位置

1.2.1 浏览器缓存

用户浏览器端存储资源,适用于图片、CSS、JavaScript等静态内容。

浏览器缓存的具体存储位置因浏览器和操作系统而异,但通常它们会被保存在以下路径中:

Windows

  • Internet Explorer(旧版):缓存文件位于C:\Users\[用户名]\AppData\Local\Microsoft\Windows\Temporary Internet Files目录下。
  • Microsoft Edge:缓存文件位于C:\Users\[用户名]\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\AC\MicrosoftEdge\User\Default\Cache

Google Chrome:缓存文件可能位于C:\Users\[用户名]\AppData\Local\Google\Chrome\User Data\Default\Cache 或者 C:\Users\[用户

名]\AppData\Local\Microsoft\Windows\INetCache\Google\Chrome (根据版本和系统配置不同)。

  • Mozilla Firefox:缓存文件通常位于C:\Users\[用户名]\AppData\Local\Mozilla\Firefox\Profiles\[profile.id]\Cache

2.macOS

  • Safari:缓存位于~/Library/Caches/com.apple.Safari/或者~/Library/Caches/com.apple.WebKit.PluginProcess/内。
  • Google Chrome:缓存文件位于~/Library/Caches/Google/Chrome/Default/Cache
  • Mozilla Firefox:缓存文件位于~/Library/Caches/Firefox/Profiles/[profile.id]/Cache

Linux

  • Chromium / Google Chrome:缓存通常位于~/.cache/chromium/Default/Cache~/.cache/google-chrome/Default/Cache
  • Mozilla Firefox:缓存位于~/.cache/mozilla/firefox/[profile.id]/Cache

要查看确切的缓存位置,可以在浏览器设置或通过开发者工具找到相关选项来查看缓存内容。对于查看具体文件,可能需要在文件管理器中按照上述路径查找。此外,由于浏览器更新可能会改变缓存存放的位置,因此建议查阅对应浏览器的最新文档以获取准确信息。

1.2.2 代理服务器缓存

代理服务器缓存是一种在网络层面上进行的缓存机制,常见于CDN(内容分发网络)服务、反向代理服务器(如Nginx)或其他类型的网络代理中。这类缓存系统通常位于客户端与原始服务器之间,能够减轻源站服务器的压力,同时降低网络延迟,特别是在地理位置分布广泛的用户群中效果明显。


代理服务器缓存的工作原理类似于浏览器缓存,它根据HTTP协议的缓存规则存储和提供请求过的资源。当用户通过代理服务器请求资源时,如果代理服务器上已有该资源的有效缓存,则直接将缓存的内容返回给用户,避免了向原始服务器发起请求。


例如,在Nginx配置中,可以通过proxy_cache模块实现对后端服务器响应内容的代理级缓存:

http {
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m;

    server {
        location / {
            proxy_pass http://upstream_server;
            proxy_cache my_cache;
            proxy_cache_valid 200 304 1d; # 对200和304响应状态码的资源缓存一天
        }
    }
}

通过这样的配置,Nginx将作为代理服务器缓存来自上游服务器的响应,并依据指定的缓存策略为后续相同请求提供服务。

1.3 缓存策略选择

1.3.1私有缓存

对于用户特定数据或受权限控制的内容,可以设置为私有缓存(如Cache-Control: private),确保这些信息不会被共享给其他用户。

浏览器的私有缓存指的是存储在用户本地(即客户端)的、仅对该用户可见且不被共享给其他用户的缓存资源。这些资源通常与用户的会话或个人数据相关,如登录后的网页内容、个性化设置等。

私有缓存的设置

要将一个HTTP响应指定为私有缓存,可以通过设置Cache-Control头部字段来实现。具体来说,当服务器返回HTTP响应时,包含以下指令:

Cache-Control: private

这告诉浏览器和其他中间缓存层(如果存在),这个响应应该被缓存在用户的私人存储区中,而不是公共或者共享缓存中,这样可以防止其他用户或代理服务器获取并使用该缓存内容。

另外,有时候对于动态生成但对特定用户长期有效的内容,也可以考虑加上一个较短的有效期限,例如:

Cache-Control: private, max-age=<seconds>

这里 <seconds> 表示的是以秒为单位的有效时间长度,虽然内容是私有的,但仍允许在一定时间内从缓存中读取,减少对服务器的请求。

访问私有缓存

浏览器自身管理私有缓存,并在满足条件时自动使用缓存中的内容。用户一般无法直接访问或查看私有缓存的具体内容,它们是由浏览器在后台处理和使用的。


当用户重新访问同一网站时,浏览器会根据缓存策略检查是否有可用的私有缓存资源,如果有并且资源未过期,则可以直接从缓存中加载,否则,它会向服务器发起新的请求以获取最新版本的数据

1.3.2 公共资源缓存

对于公共、不变的静态资源,应尽量实现长期可缓存,以充分利用客户端缓存优势。

为了实现公共资源的长期可缓存,可以在HTTP响应头中设置:

  • Cache-Control: public 表示任何缓存都可以存储此响应。
  • Cache-Control: max-age=<seconds> 指定资源在指定秒数内有效,浏览器在这段时间内无需重新验证资源。
  • 或者,可以使用 Expires 头部来设置一个绝对过期时间。

例如:

Cache-Control: public, max-age=31536000

这将指示浏览器和其他中间缓存设备,在接下来的一年(即31536000秒)内可以直接从缓存中获取资源,而不需要重新请求服务器。当然,具体的有效期限应根据资源的实际更新频率进行调整。

1.4 Vary头部

当响应头包含Vary头部时,指示缓存系统应基于请求中的哪些头部信息进行缓存区分,如Vary: Accept-Encoding意味着缓存应根据Accept-Encoding头部的不同值存储不同的版本。

2. 缓存实施细节

CSS、JavaScript文件以及图片资源在网页加载过程中通常都是通过HTTP GET 请求来获取的。当浏览器解析HTML文档时,遇到标签引用CSS文件、


如果服务器端没有设置任何缓存相关的HTTP头部信息(如Cache-Control、Expires、Last-Modified或ETag等),浏览器仍然可能会根据其自身的默认策略来决定是否缓存响应内容,尤其是对于静态资源(例如图片、CSS样式文件和JavaScript脚本等)。不过这种默认行为通常较为保守,并且各个浏览器可能有所不同。


现代浏览器的默认策略趋向于至少在短时间内缓存某些资源以提升用户体验,但这样的缓存并不一定可靠且易于控制,因为不同的浏览器对无明确缓存指示的响应处理方式可能存在差异。


为了确保网页资源缓存行为的一致性和可控性,最佳实践是推荐由服务器端明确设置合适的HTTP缓存头部信息。

2.1 服务端配置

  • 设置合适的Cache-Control头部,比如针对静态资源设置较长时间的max-age,而对于经常变化的数据则缩短有效期或禁用缓存。
  • 生成并返回有意义的ETag,以便于浏览器进行后续的条件请求。

在Nginx中,可以通过location块来配置针对不同类型的资源设置不同的Cache-Control头部和ETag生成策略。以下是一个简单的Nginx配置示例:

http {
    # 设置全局缓存相关选项(可选)
    proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m inactive=60m;

    server {
        listen 80;
        
        # 针对静态资源的缓存设置
        location ~* \.(jpg|jpeg|png|gif|css|js)$ {
            # 开启缓存并设置较长时间的max-age
            expires 30d; # 假设设置为30天
            add_header Cache-Control "public, max-age=2592000"; # 对应于30天
            
            # 如果服务器端有对应的文件,则启用etag生成
            etag on;
            
            # 可以考虑开启代理缓存或FastCGI缓存(如果适用)
            # proxy_cache my_cache;
            # fastcgi_cache my_cache;
        }

        # 针对经常变化的数据,禁用缓存或设置很短的有效期
        location /api/ {
            # 禁止浏览器缓存
            add_header Cache-Control "no-cache, no-store, must-revalidate";
            add_header Pragma "no-cache";
            add_header Expires "0";

            # 虽然不建议缓存动态内容,但如果确实需要根据ETag做条件请求,可以保留下面一行
            etag on;

            # 其他如proxy_pass、fastcgi_pass等转发配置
            # ...
        }
    }
}

这段配置包括:

  • 对于静态资源(图片、样式表、脚本),设置了较长的缓存有效期,允许浏览器缓存这些内容长达30天,并且开启了ETag生成。
  • 对于经常变化的API数据,通过Cache-Control头部明确禁止了缓存,并清除了Pragma和Expires头部信息,确保浏览器每次都会向服务器请求最新数据。

请注意,具体的缓存路径、缓存区域大小以及是否启用代理或FastCGI缓存需根据实际情况调整。

2.2 前端开发

  • 使用HTML <meta> 标签对网页整体进行缓存控制。
  • 对于动态加载的资源,可以在URL后面添加查询参数作为版本标识,如/static/js/app.js?v=1.0,每次文件更改时更新版本号以绕过缓存。

在HTML中,<meta> 标签可以用于设置网页缓存策略,但它的效果相比服务器端通过HTTP头部(如Cache-ControlExpiresETag)发送的缓存指令较弱,并且不是所有浏览器都完全遵循 <meta> 标签设置的缓存规则。然而,在某些情况下,特别是对于不支持HTTP/1.1缓存头信息的老式浏览器,使用<meta>标签进行缓存控制仍具有一定意义。

以下是一个使用<meta>标签设置缓存控制的例子:

<!-- 在<head>部分添加如下代码 -->
<meta http-equiv="Cache-Control" content="max-age=3600, public">
<meta http-equiv="Pragma" content="cache">
<meta http-equiv="Expires" content="Sat, 12 Jan 2024 12:00:00 GMT">

<!-- 解释:
- Cache-Control: max-age=3600 表示资源在接下来的一个小时内有效,此后浏览器需要重新验证。
- public 表示该响应可被任何缓存区缓存(包括共享缓存)。
- Pragma: cache 告诉一些老式浏览器应该缓存此页面。
- Expires: 设置了一个绝对时间戳,过了这个时间点后,浏览器会认为缓存过期,需重新请求资源。
-->

请注意,现代浏览器更倾向于优先处理HTTP响应头部中的缓存指示。因此,最佳做法是结合服务端配置(如Nginx、Apache等服务器软件中的配置)来精确控制缓存策略,同时也可以在HTML文档中使用<meta>标签作为补充手段。如果可能的话,直接配置服务器端发送合适的HTTP缓存头部更为可靠和有效。

2.3 HTTP/2特性利用

  • HTTP/2引入了HPACK压缩头部,使得重复请求相同资源时的头部开销减小。
  • Server Push功能允许服务器预测客户端可能需要的资源并提前推送至客户端缓存。

HTTP/2 中的 Server Push(服务器推送)是一项旨在优化网页加载性能的功能。在传统的HTTP/1.x协议中,浏览器发起请求后,服务器才会逐个响应客户端所需的资源。而在HTTP/2协议下,Server Push 允许服务器在客户端请求一个资源时,预测到客户端可能还需要其他资源,并主动将这些资源“推”送到客户端缓存中,而无需等待客户端显式地发起请求。


例如,当服务器接收到对HTML文档的请求时,它分析文档中的 <link> 或 <script> 标签,识别出页面需要哪些CSS或JavaScript文件,并立即向客户端发送这些文件,而不是等待浏览器解析HTML并逐个发起请求。这样可以减少网络往返时间(RTT),提前加载资源,从而加快页面渲染速度。


要实现Server Push,服务器会通过HTTP/2的PUSH_PROMISE帧来通知客户端即将推送的资源及其相应的优先级,客户端可以选择接受或拒绝推送的资源。


需要注意的是,Server Push 需要合理的策略以避免不必要的带宽消耗和缓存失效问题。实际应用中,开发人员和服务器配置应当根据网站的实际内容和用户行为进行精细化设置。

2.4 Service Worker

在支持的浏览器环境中,利用Service Worker实现更精细的离线缓存和自定义缓存策略,如使用Workbox库创建预缓存策略和网络优先/缓存优先策略。

总之,精心设计并合理实施缓存策略能够显著提升Web应用性能,减轻服务器压力,并提供更好的用户体验。开发者应当结合实际业务需求,灵活运用多种缓存技术,最大化发挥其效能。

相关文章
|
5月前
|
数据采集 数据可视化 API
QUIC协议优化:HTTP/3环境下的超高速异步抓取方案
本文介绍了一种基于QUIC和HTTP/3的异步爬虫方案,用于抓取知乎热榜数据并生成趋势图。通过HTTPX与aioquic结合实现高性能连接复用,配合代理IP绕过反爬限制,提取标题、热度等信息。利用Python代码示例展示了异步抓取流程,并借助Matplotlib绘制话题热度变化图表。分析显示突发热点生命周期短,而深度话题热度更稳定。此方案可优化内容运营策略,快速捕捉潜在爆款话题。
188 4
QUIC协议优化:HTTP/3环境下的超高速异步抓取方案
|
3月前
|
缓存 监控 搜索推荐
301重定向实现原理全面解析:从HTTP协议到SEO最佳实践
301重定向是HTTP协议中的永久重定向状态码,用于告知客户端请求的资源已永久移至新URL。它在SEO中具有重要作用,能传递页面权重、更新索引并提升用户体验。本文详解其工作原理、服务器配置方法(如Apache、Nginx)、对搜索引擎的影响及最佳实践,帮助实现网站平稳迁移与优化。
456 68
|
2月前
|
缓存 网络协议 UED
深度解析HTTP协议从版本0.9至3.0的演进和特性。
总的来说,HTTP的演进是互联网技术不断发展和需求日益增长的结果。每一次重要更新都旨在优化性能,增进用户体验,适应新的应用场景,而且保证了向后兼容,让互联网的基础架构得以稳定发展。随着网络技术继续进步,我们可以预期HTTP协议在未来还会继续演化。
344 0
|
2月前
|
数据采集 JSON Go
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
|
5月前
|
网络协议 API 开发者
分析http.client与requests在Python中的性能差异并优化。
合理地选择 `http.client`和 `requests`库以及在此基础上优化代码,可以帮助你的Python网络编程更加顺利,无论是在性能还是在易用性上。我们通常推荐使用 `requests`库,因为它的易用性。对于需要大量详细控制的任务,或者对性能有严格要求的情况,可以考虑使用 `http.client`库。同时,不断优化并管理员连接、设定合理超时和重试都是提高网络访问效率和稳定性的好方式。
124 19
|
4月前
|
网络协议 API Python
解析http.client与requests在Python中的性能比较和改进策略。
最后,需要明确的是,这两种库各有其优点和适用场景。`http.client` 更适合于基础且并行的请求,`requests` 则因其易用且强大的功能,更适用于复杂的 HTTP 场景。对于哪种更适合你的应用,可能需要你自己进行实际的测试来确定。
124 10
|
5月前
|
域名解析 网络协议 网络安全
SSL证书验证全攻略:DNS/HTTP/手动解析怎么选?
SSL证书在网络安全中至关重要,1Panel提供三种验证方式:DNS验证、HTTP验证和手动解析。DNS验证便捷,适合CDN网站;HTTP验证快速,需服务器在线;手动解析灵活,但操作复杂。根据需求选择合适确认方式,定期检查证书状态。
627 2
|
5月前
|
安全 网络协议 算法
HTTP/HTTPS与SOCKS5协议在隧道代理中的兼容性设计解析
本文系统探讨了构建企业级双协议隧道代理系统的挑战与实现。首先对比HTTP/HTTPS和SOCKS5协议特性,分析其在工作模型、连接管理和加密方式上的差异。接着提出兼容性架构设计,包括双协议接入层与统一隧道内核,通过协议识别模块和分层设计实现高效转换。关键技术部分深入解析协议转换引擎、连接管理策略及加密传输方案,并从性能优化、安全增强到典型应用场景全面展开。最后指出未来发展趋势将更高效、安全与智能。
188 1
|
6月前
|
安全 网络安全 数据安全/隐私保护
HTTP 与 HTTPS 协议及 SSL 证书解析-http和https到底有什么区别?-优雅草卓伊凡
HTTP 与 HTTPS 协议及 SSL 证书解析-http和https到底有什么区别?-优雅草卓伊凡
303 3
|
6月前
|
缓存 安全 Java
深入解析HTTP请求方法:Spring Boot实战与最佳实践
这篇博客结合了HTTP规范、Spring Boot实现和实际工程经验,通过代码示例、对比表格和架构图等方式,系统性地讲解了不同HTTP方法的应用场景和最佳实践。
556 5

热门文章

最新文章

推荐镜像

更多
  • DNS