在读本文前你要确保读过我的上篇文章《扼杀 304,Cache-Control: immutable》,因为本文是接着上文写的。上文说到,在现代 Web 上,“条件请求/304 响应”绝大多数都是浪费资源,因为绝大多数静态资源都是永恒不变的,因此 Firefox 实现了 Cache-Control: immutable 来让开发者们控制用户浏览器的刷新行为,即在刷新时不要对这些资源文件进行条件请求(缓存不过期的前提下)。

Chrome 至今迟迟没有实现 Cache-Control: immutable,难道 Chrome 不想让自己的网页在刷新时展现的更快?不是的,其实 Chrome 的开发人员也早已注意到了这个问题。早在 2015 年底,他们就开发出了一种新的刷新行为,称之为 new reload/faster reload/non-validating reload,这种新的刷新和以前传统的刷新有个区别,那就是在刷新页面时,只对页面本身的资源文件进行条件请求(如果缓存了的话),页面里引用的各种子资源文件,只要缓存不过期,就直接读取缓存。也就是说,“你们开发者压根不用去加什么 Cache-Control: immutable 响应头了,我 Chrome 直接改成刷新不发条件请求就得了”。

Chrome 在 2015 年底只针对安卓端的 Chrome for Android 中的下拉刷新开启了这种新的刷新,下面是当时的 commit log

Make pull to refresh not perform regular reload (with cache revalidation)

Pull-to-refresh action on Android is currently handled as a
regular reload, which causes revalidation of cached contents,
however the action would usually imply that the user wants to
refresh the 'contents' rather than reloading everything (e.g.
to reset the page contents when something's screwed up).

这段话中说到,用户刷新一个页面通常都不是为了重新请求每个资源文件看是不是过期了,而仅仅是为了重置一下页面的状态,所以要做这个优化。下面是当时测试效果的对比演示,左旧右新:

 

可以看到,左侧有明显的加载白屏阶段,而右侧没有。

在 16 年 5 月份,Chrome 把该刷新行为应用到了 PC 端,从 Chrome 54 开始默认启用。我写了一个测试 demo,在 Chrome 54 之前,刷新这个 demo 后效果是这样的:

所有的资源都会被发起条件请求从而返回 304 响应,而在 Chrome 54 里,刷新这个 demo 后效果成了:

只有页面本身被发起了条件请求,所有引用的子资源都直接读取了缓存,也就是说,实际上刷新这个页面只触发了一个 HTTP 请求。

额外小技巧

从 Chrome 56 开始,你可以通过网络面板新增的 is:from-cache 过滤条件来过滤出直接读取缓存的请求(即没有发送真实的 HTTP 请求的请求),还可以利用它的反向过滤找出发送了真实请求的请求,像下面这样(还是上面的 demo):

这个过滤条件是我向 Chrome 提议的。

不知道你们注意过没有,除刷新外,常规加载一个网页的途径有两种,最常见的一种是通过点击其他页面的超链接(包括浏览器书签)进入当前页面,还有一种是在浏览器地址栏上输入网址并回车(高级用户),这两者在发送请求上也是有区别的。前者是不会发起任何条件请求的(除非缓存过期),而后者是会为页面资源本身发起条件请求的(你可以用上面的 demo 做测试),Chrome 新的这个刷新机制其实就是把刷新改得和在地址栏回车一样了。鉴于现如今的大多页面都是动态页面(没有 Cache-Control/Expires/Last-modified 响应头),不会被缓存,所以如今这三者在 Chrome 上的差别已经很小了。

如果你已经升级到了 Chrome 的最新版,没法找到 Chrome 54 之前的版本来做对比测试,可以试试通过停用 chrome://flags/#enable-non-validating-reload-on-normal-reload 选项来切回老版的刷新,不过这个选项在 Chrome 56 里已经被彻底删除了:

读到这里,有同学就想问了,“难道 Chrome 这样做不违反 HTTP 协议吗?”。并没有,HTTP 协议只会规定客户端应该怎么发一个条件请求,服务器应该怎么响应这个条件请求,但不会规定应用程序何时应该发送条件请求。

那 location.reload() 呢,也会改成新版刷新吗?从 Chrome 56 开始 location.reload() 也会使用新版刷新。HTML 规范并没有明确的说明 location.reload() 应该如何对待缓存,只略略提到了一句:

User agents may allow the user to explicitly override any caches when reloading.

这句话应该是给 Firefox 的 location.reload(true) 准备的。

那对用户来说,这个改动向后兼容吗?从我注意到 Chrome 的这个改动后,一直以为这是 Chrome 的 bug,但提 bug后被告知这是有意的。我当时觉的这个改动太激进了,毕竟打破了二十年多年的浏览器传统,一定会有用户反馈不兼容问题的。但直到这个改动进入稳定版后,也没有一个人反馈。。。仿佛全世界只有我一个人注意到了这个改动。

但对开发者来说,其实这个改动的确是有点不向后兼容的。比如某个带有特定版本号的资源在发布到 daily 环境后,是可以不换版本号(URL)反复覆盖式更新的,但你在浏览器里刷新却看不到效果,只能借助于开发者工具的 Disable cache 功能。不过最终用户是没这个问题的,因为线上是无法覆盖式发布的。

所以现在我的看法变了,Firefox 和其他浏览器应该变的像 Chrome 一样,Cache-Control: immutable 已经几乎没有价值了(除非我漏掉了某个点),能让所有的网页变的更快,为什么不呢。

俗话说的好,“前端有三宝,清缓存、清 cookie、换个浏览器”。以后在 Chrome 里单纯的刷新是真的不行了,要教用户怎么“强制刷新/跳过缓存刷新”了。

可以看到自己公司 CDN 日志的同学们,可以看看最近 304 响应的占比有没有大幅减少,不过国内的话也许需要等国产浏览器的内核更新后才行。

关于缓存和 Chrome 的“新版刷新”的更多相关文章

  1. chrome最新版49跨域问题

    chrome最新版49跨域问题   一.最新版49要用新的参数 加--user-data-dirwindows:"C:\Program Files\Google\Chrome\Applica ...

  2. vue的组件缓存(返回页面不刷新)

    每次使用返回是页面总是会刷新 导致了一些体验上的不愉快 现在 发现vue中的一个很方便的方法还可以用来优化性能就是: keep-alive缓存组件 <router-view v-if=" ...

  3. 关于如何刷新清除某个特定网站的缓存---基于Chrome浏览器

    今天工作时又发现了一个小技巧 1.打开一个网站如:百度 2.打开F12开发者模式 3.右键浏览器的刷新按钮,会出现三个选项:正常重新加载,硬性重新加载,清空缓存并硬性重新加载 正常重新加载 Ctrl+ ...

  4. [Web前端] mac chrome 浏览器强制刷新,清除浏览器缓存

    本文链接:https://blog.csdn.net/zeroyulong/article/details/79806156 mac 强制刷新:command+shift+r mac 普通刷新:com ...

  5. 【原创】Chrome最新版(53-55)再次爆出BUG!

    前言 今年十月份,我曾发布一篇文章<Chrome53 最新版惊现无厘头卡死 BUG!>,不过那个BUG在最新的 Chrome 54 中已经修正. 而今天即将发布的Chrome弱智BUG: ...

  6. Sublime3和Chrome配置自动刷新网页【实测可用】

    SublimeText2下的LiveReload在SublimeText3下无法正常使用,本文整理SublimeText3安装LiveReload的方法.win7下实测可用! 安装成功后,就不需要再手 ...

  7. 清除IE中Ajax缓存,Chrome不需要

    做项目的时候,会遇到这种情况,通过ajax从后台获取的数据在chrome上显示的是最新的,而在IE上却是以前的数据,这是为什么呢,在我百般调试下终于发现原来是因为IE的ajax缓存的原因,于是加上这段 ...

  8. 用Meta 取消流量器缓存实现每次访问都刷新页面方便调试

    如果想禁止浏览器从本地缓存中调阅页面,可以设置网页不保存在缓存中,每次访问都刷新页面,下面是Meta在这方便的用法,需要的朋友可以参考下: <!-- 禁止浏览器从本地缓存中调阅页面.--> ...

  9. IE/firefox/chrome 每次都刷新

    IE FIREFOX 1.在firefox的地址栏上输入about:config回车2.找到browser.cache.check_doc_frequency选项,双击将3改成1保存即可. 那么这个选 ...

随机推荐

  1. 【实战代码】PHP实现读取一个1G的文件大小

    本文地址:http://www.cnblogs.com/aiweixiao/p/7535351.html 欢迎关注我的微信公众号哈 “ 程序员的文娱情怀” http://t.cn/RotyZtu [背 ...

  2. ESP8266远程OTA升级

    https://blog.csdn.net/xh870189248/article/details/80095139 https://www.wandianshenme.com/play/arduin ...

  3. MySQL内部执行流程

    本文参照自:https://www.cnblogs.com/xiaotengyi/articles/3641983.html mysql处理java传过来的SQL具体步骤: 1.java通过JDBC获 ...

  4. 异步渲染页面怎么点击checkbox获取value值

    前后端分离时 后端向前端传递json数据  前端根据需要进行页面渲染 因为是异步渲染 想要获取获取渲染数据里面的值时获取不到的 介绍两个方法: 1,设置全局变量 即渲染时在html页面设置全局变量 如 ...

  5. Nero8刻录引导系统光盘镜像图文教程

    刻录可引导的Windows系统光盘一直是电脑使用者较为需要的,今天,倡萌抽空写了这篇图文教程,希望对于菜鸟级的朋友有所帮助,大虾请飘过.本教程以最为强大的刻录软件Nero 8做为工具(其他版本的Ner ...

  6. Linux启动时间优化-内核和用户空间启动优化实践

    关键词:initcall.bootgraph.py.bootchartd.pybootchart等. 启动时间的优化,分为两大部分,分别是内核部分和用户空间两大部分. 从内核timestamp 0.0 ...

  7. Cesium如何通过addImageryProvider方法加载SkylineGlobe Server发布的WMS服务

    某某某单位用SkylineGlobeServer7版本发布了好些服务,然后让我们在Cesium里都加载进来展示. 其实只要符合OGC标准的,加进来还是很容易的. 示例代码如下: function te ...

  8. iOS开发基础-序列帧动画之Tom猫

    新建一个Single View Application,向该工程中导入Tom猫的图片资源,本示例演示Tom猫喝牛奶的动作.图片的名字为 drink_00.jpg.drink_01.jpg.....dr ...

  9. Bootstrap开发框架界面的调整处理

    我在之前介绍了很多关于Boostrap的框架方面的文章,主要是介绍各种插件的使用居多,不过有时候觉得基于Metronic的Boostrap框架的界面效果不够紧凑,希望对它进行一定的调整,那么我们应该如 ...

  10. 技术趋势:React vs Vue vs Angular

    React.Vue 和 Angular 这两年发展状况如何?2019 年哪个技术最值得学习? 前几天 Medium 上有一位作者发表了一篇关于 React.Vue 和 Angular 技术趋势的文章( ...