扼杀 304,Cache-Control: immutable

随着近些年社交网站的流行,越来越多的人学会了“刷”网页 ── 刷微博,刷朋友圈,刷新闻,刷秒杀页。这里的“刷”,就是刷新的意思,在浏览器里,你可以通过点击刷新按钮,或者用快捷键,或者移动端的下拉操作来进行刷新。

但普通网民不知道的是,通过刷新操作导致的页面加载和通过其他操作(比如点击页面链接,地址栏输入网址并回车,点击收藏夹网址等)导致的页面加载有一点不同,那就是刷新操作会给该页面的请求本身以及页面里所引用的资源们(JS,CSS,图片等)的请求加上 If-Modified-Since 和 If-None-Match 请求头(如果已经有缓存且有 Last-Modified/ETag 响应头的话),服务器会根据这两个请求头判断该资源有没有更新过,如果没有,就返回不带响应体的 304 响应,告诉浏览器:“用缓存吧”,如果更新过了,则把更新后的资源放在响应体里返回 200 响应。

我们把上面说的这种带有 If-Modified-Since 或 If-None-Match 请求头的 HTTP 请求叫做条件请求,除了刷新操作,条件请求还会发生在缓存过期的时候,也就是已缓存时长大于 Cache-Control 响应头中的 max-age 字段指定的秒数的时候。

条件请求是设计用来更新资源的,但实际情况是,在现如今的网站开发中,尤其是大型网站,会依赖适当的过期时长或者让用户手动刷新来更新页面吗?比如把缓存时长设置成一小时,新版页面上线了,用户都看不到效果,老板过来问:“这怎么回事啊,不是上线了吗”,开发回答:“要等一小时缓存过期啊,你也可以刷新一下就看到效果了~”。显然不可能这样,对于那些有更新需求的静态资源,常见的是 JS、CSS,我们都会在它的 URL 里加上点东西,时间戳、版本号、哈希值等,可以放在 URL 的路径里,也可以放在查询参数里,因为只要 URL 变了,浏览器就认为是不同的资源,就会重新下载;还有一些静态资源是完全没有更新需求的,比如你在微博上传的那些图片,同一个 URL 对应的资源是永远不会变的。

上面说的这两种情况,其实是一种,就是它们永远没有更新的需求,它们是不可变的,是 immutable 的,304 用在它们身上完全没有意义,全是浪费。虽然每个 304 请求的往返体积只有 1k 左右,但架不住多啊。而且就算只有一个字节,也会导致页面展现变慢,读本地文件和读网络资源还是有本质区别的。

Facebook 在一年前意识到了这个问题,它的工程师给制定 HTTP 标准的 IETF 工作组发了封邮件,里面说到,Facebook 使用版本号来更新静态资源,还给静态资源设置了几乎不可能过期的缓存时长,但发现仍然有 20% 的请求是无意义的条件请求(必然 304),这给服务器性能带来很大伤害,他们研究发现是因为 Facebook 页面 pv 有 2% 来自用户的刷新操作,他们希望 HTTP 协议能给 Cache-Control 响应头增加一个属性字段表明该资源永不过期,浏览器就没必要再为这些资源发送条件请求了。

今年四月份,Mozilla 的人觉的 Facebook 提的这个建议很好,于是他们在 Firefox 49 里实现了 Cache-Control: immutable。immutable 的推荐用法是和那些超大的 max-age 配合使用,比如 1年:Cache-Control: max-age=31536000, immutable,甚至 10年, 但通常情况下,1 年就够了,因为:1. 对于单个缓存来说,它在某个浏览器里存活的时长不可能超过一年,浏览器的缓存空间都有上限,Firefox 256M,Chrome 320M,旧的缓存会时不时被清掉。2. 一个用户不大可能一年后还来同一个页面,且那个页面还没改版。对缓存时长来说,1 年就代表永远了。

但这只是推荐做法,immutable 并不是真的只能应用在那些永不过期的资源上,也可以配合较小的 max-age 来使用,比如一些个人博客,或者一些不太讲究及时更新的站点,可以设置成 Cache-Control: max-age=3600, immutable,表明该资源能存活一小时,在一小时之内,即便用户刷新也不要发送条件请求,在过期之后,浏览器会发送不带一个不带 If-Modified-Since 和 If-None-Match 的请求来更新资源,这里需要注意,一旦被标志成 immutable,则这个资源不可能返回 304 响应了,只有 200。

目前 Firefox 的实现里,只对 HTTPS 资源开放 immutable 属性的支持,我通过 Fiddler 在本地篡改了淘宝搜索页面 https://s.taobao.com/search?q=连衣裙 里所有资源的 Cache-Control 响应头,在原值尾部加上 “, immutable”。篡改之前,假如我刷新一下此页面,会导致数十个 304 响应:

篡改之后的刷新效果:

注意那些带有 cached 字样的 200 请求,那些请求实际上根本不是真正的请求,只是一次本地读取文件的操作。

目前 Facebook 还没有反馈 immutable 的测试数据,毕竟 Firefox 49 还不是正式版,以后应该会有的。不过考虑到现在 Firefox 的市场占有率,也许 Chrome 实现之后才会得到更多人的关注, Chrome 也表示了有意愿去实现。不过我在 GitHub 搜了一下,倒是发现 W3C 的网站和 Firefox 附加组件网站准备实现。

immutable 只有在你的网站被频繁刷新的情况下才有较大的意义。还有虽然它是向后兼容的,但可能一些 CDN 服务器在识别 Cache-Control 时因不认识这个属性,导致最终返回给浏览器的响应丢失了 immutable,推特上有反应 Akamai 就这么干了。

少数人知道的强制刷新功能(Ctrl+F5/Shift+Command+R)以及开发者工具的跳过缓存功能优先级应比 immutable 更高。

转载于:https://www.cnblogs.com/defined/p/6286035.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/284850.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Eolink是国产API接口管理的无冕之王

一、传统API接口管理的缺陷 1、前言 项目开发我们都知道在一个项目团队中是由很多角色组成,最常见团队的就是前端开发工程师、客户端开发工程师、服务端开发工程师组成一个团队,团队之间进行合作,一般我们都离不开API接口管理和测试&#x…

linux下永久添加静态路由

在linux下永久添加静态路由有两种方法: 添加路由的命令: 1,route add route add -net 192.56.76.0 netmask 255.255.255.0 dev eth0#添加一条静态路由 route add default gw 192.168.0.1#添加默认路由 route del -net 192.168.1.0/24 gw 192.…

【ArcGIS微课1000例】0020:关于ArcCatalog,你知道多少?

文章目录 一、ArcCatalog简介1. ArcCatalog启动和关闭2. ArcCatalog界面3. 菜单栏4. 目录树5. 搜索窗口6. 主窗口7. 工具栏二、ArcCatalog主要功能1. 文件夹连接2. 添加空间数据库连接3. 文件类型的添加和移除4. 文件特性的显示设置5. 导出数据6. 查看数据7. ArcCatalog中图层的…

【数据结构】二叉排序树

二叉排序树(Binary Sort Tree)又称二叉查找树(Binary Search Tree),亦称二叉搜索树。 特点 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: 1、若左子树不空,则左子树上所有…

记一次 .NET 某电厂Web系统 内存泄漏分析

一:背景 1. 讲故事前段时间有位朋友找到我,说他的程序内存占用比较大,寻求如何解决,截图就不发了,分析下来我感觉除了程序本身的问题之外,.NET5 在内存管理方面做的也不够好,所以有必要给大家分…

Bomb(hdu 3555)

题意&#xff1a;给定一个闭区间&#xff0c;求区间内有多少数中含“49” /*dp[i][j]表示i位数以j为最高位位中的所有不符合数的个数。然后把数字拆分&#xff0c;乱搞即可。 */ #include<cstdio> #include<iostream> #define lon long long using namespace std; …

《深入实践Spring Boot》下载

本书以丰富的实例&#xff0c;介绍了如何使用SpringBoot开发框架进行基础应用和分布式应用等方面的开发&#xff0c;以及如何使用SpringBoot开发的应用构建高性能的服务平台&#xff0c;同时还对SpringBoot的一些核心代码进行了深入剖析。本书从基本的入门&#xff0c;到数据库…

【ArcGIS微课1000例】0021:ArcToolBox工具箱功能与环境概述

文章目录 一、ArcToolBox功能简介1. 3D分析工具2. 分析工具3. 制图工具4. 转换工具5. 数据管理工具6. 地理编码工具7. 地统计分析工具8. 线性参考工具9. 空间分析工具10. 空间统计工具二、ArcToolBox环境设置一、ArcToolBox功能简介 ArcToolbox的空间处理工具条目众多、功能丰…

[转]将图片转换为 latex 公式

一、官网链接及使用方法 官网链接&#xff08;跨平台&#xff09;: Mathpix 公式截图快捷键截图生成 latex 公式--------------------- 作者&#xff1a;man_world 来源&#xff1a;CSDN 原文&#xff1a;https://blog.csdn.net/mzpmzk/article/details/84140617 版权声明&…

在SQL Server2005中使用 .NET程序集

昨天完成了一个最简单的在数据库中创建标量值函数,今天主要完成表值函数,存储过程和用户定义类型在和.NET结合下的使用方法.1,表值函数所谓表值函数就是说这个函数返回的结果是一个Table,而不是单个的值.在.NET 中创建这样的函数,返回的结果是一个IEnumerable接口.这个接口非常…

C# 实例解释面向对象编程中的接口隔离原则

在面向对象编程中&#xff0c;SOLID 是五个设计原则的首字母缩写&#xff0c;旨在使软件设计更易于理解、灵活和可维护。这些原则是由美国软件工程师和讲师罗伯特C马丁(Robert Cecil Martin)提出的许多原则的子集&#xff0c;在他2000年的论文《设计原则与设计模式》中首次提出…

Appium同时运行多个设备

为了提高测试效率&#xff0c;测试需要同时在多个android设备上运行&#xff0c;就需要启动多个appium。 启动appium时&#xff0c;为每个设备设置不同的端口号&#xff0c;并为driver设置该设备的udid。见如下实例&#xff0c;关键是红色部分 DesiredCapabilities capabilitie…

AI作画的业界天花板被我找到了,AIGC模型揭秘 | 昆仑万维

一、前景 1、AI和AIGC的关系 人工智能&#xff08;Artificial Intelligence&#xff09;&#xff0c;英文缩写为AI。它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。 AIGC是继 UGC、PGC 之后新型利用AI技术自动生成内容的生产…

【ArcGIS微课1000例】0022:ArcGIS点(点坐标)自动连成线操作案例教程

ArcGIS中,可以将带三维坐标(X、Y、Z)的点/点集自动连成线,本文演示具体操作流程。 文章目录 实战演练GPS点数据下载实战演练 打开ArcMap软件,添加实验文件夹0022下的GPS轨迹点.shp矢量点数据(文末提供下载地址),该数据是由GPS RTK采集的河道点数据,首先需要将GPS点坐…

微信公众号 文章的爬虫系统

差不多俩个星期了吧&#xff0c;一直在调试关于微信公众号的文章爬虫系统&#xff0c;终于一切都好了&#xff0c;但是在这期间碰到了很多问题&#xff0c;今天就来回顾一下&#xff0c;总结一下&#xff0c;希望有用到的小伙伴可以学习学习。 1、做了俩次爬虫了&#xff0c;第…

[转]关于C#操作WPS和office兼容性的问题

最近一直在做的开发是关于导出word的功能&#xff0c;一开始的做法是在VS中直接添加引用office PIA&#xff0c;Microsoft.Office.Interop.Word&#xff0c;VS08有两个版本&#xff0c;V11和V12&#xff0c;V11对应的是office03&#xff0c;V12对应的office07&#xff0c;试验之…

AI入门到进阶到放弃

前些天&#xff0c;发现了一个比较好的AI学习网站&#xff0c;有很多数学基础&#xff0c;也通俗易懂&#xff0c;我自己先记录起来防止忘记&#xff0c;猛戳这里&#xff08;学习网站&#xff09;

OAuth认证与授权

什么是OAuth授权&#xff1f; 一、什么是OAuth协议OAuth(开放授权)是一个开放标准。允许第三方网站在用户授权的前提下访问在用户在服务商那里存储的各种信息。而这种授权无需将用户提供用户名和密码提供给该第三方网站。OAuth允许用户提供一个令牌给第三方网站&#xff0c;一个…

IO的多路复用

一、概念: 使单线程或者单进程同时监测若干个文件描述符具有执行的能力&#xff1b; 二、作用: 类似于多进程和多线程 三、必要性: 多线程或者多进程对资源需求较高 四、IO模型: 1.阻塞io 不设置的话系统默认 2.非阻塞io 在阻塞io的基础上调整为不在阻塞状态 用到的函数接口…