摘要:文件路径,上线后,丝丝润滑无痛无痒,完美第四个版本,可以做更多注意哦,重点来咯尽早加载是减少首屏时间的关键引申阅读,直接把到里是个不错的方案。
第一个版本,简单粗暴有点痛所谓 File Prefetching 就是在一个页面加载成功后,默默去预加载后续可能会被访问到的页面的资源。
前端资源预加载其实没啥新鲜的,我们倒腾这个事情的过程却是很有有意思也很有启发性。
1、建一个独立的页面,里面索引了各种需要预加载的css、js,代码类似下面这样。
...其他需要预加载的css ...其他需要预加载的js
2、 在每个页面加入一个iframe(一般通过base模板统一加),这样每个页面打开的时候都会加载上面这个页面。假设上面的页面的url是 https://xxx.com/common/prefetching.html 那么我们每个页面底部都有这么一行代码:
如何验证要验证某个file prefetching的方案是否真的有效,无非就是以下几步:
(假设A页面使用了showcase_d0fbaaef124a8691398704216ccd469a.css,而B页面不会)
让chrome终端打开的时候cache功能依旧有效
清空所有本地cache
打开B页面,在控制台Networking里看prefetching.html以及附属的资源文件是否被下载了
打开A页面,注意:是在地址栏里输入A的网址然后回车,不要打开A页面后习惯性地按Command/Ctrl+R来刷新,不出意外,我们会看到如下图这样的结果:
这说明,这2个css文件是从cache里读的。如果Command/Ctrl+R来刷新页面,我们会看到这样的结果:
两者的差别是,Command/Ctrl+R的时候,浏览器会从cache里找该静态文件,如果找到了,会根据上次请求这个文件时得到的cache-control信息判断该静态文件是否已经过期了,如果没有,会以 if-modified-since、Etag 等信息作为 request headers 向服务器请求这个文件,服务器如果认为文件没有变过,会返回Http code为304,浏览器于是直接读cache。具体不展开啦,可以看 [《HTTP caching
》](https://developers.google.com/web/fundam... 和 《Understanding HTTP/304 Responses》。
让chrome终端打开的时候cache功能依旧有效:Chrome终端的配置里把Disable cache (while DevTools is open)的勾选去掉
清空所有cache:地址栏里输入 chrome://settings/clearBrowserData 打开后勾上 Cached images and files 点 Clear browsing data
查看浏览器当前cache的资源列表:chrome://cache/
目前看来,上面这个 File Prefeching 的方案是有效的。不过这种是最简陋的试验版,存在几个问题:
prefetching.html 里的js会被执行,然后不可避免地会有一堆js错误 —— 看着难受~
通过iframe 加载 prefetching.html 会影响到当前页面相关资源的加载速度
每次打开页面都会加载一次 prefetching.html,虽然里面的静态文件都已经在第一次打开的时候被cache住了不会重复下载,但无谓多一个请求终究是没必要。
于是,我们上线使用的版本是这样的:
1、有一段每个页面都会被执行到的js:
// 打开一个iframe,下载之后页面可能需要的js/css setTimeout(function() { var lastOpenTime = 0; var nowTime = (new Date()).getTime(); try { lastOpenTime = window.localStorage.getItem("staticIframeOpenTime"); } catch (e) {} if (lastOpenTime > 0 && (nowTime - lastOpenTime < 24 * 3600 * 1000)) { // 24小时打开一次iframe return; } var iframe = $("
2、prefetching.html 里的资源想办法让他下载但不执行,基本上都是把这些css/js文件当做其他类型的文件来加载,最后参照了《Preload CSS/JavaScript without execution》这篇文章,prefetching.html 中加载js文件的代码大概是这样的:
通过对预加载的js文件只下载不执行、延时加载prefetching.html、借助localstorage的记录一天只加载一次prefetching.html,基本上解决了版本一的3个问题。
效果和问题移动页面全站上线后,平均loaded时间减少了0.15s,首屏时间没有数据,不过收益应该是可观的
不过,这个版本上线后,我们发现页面在prefetching的时候会假死,最后定位到是因为object加载js导致的(具体为什么会这样还没细究),考虑到我们主要的页面都是在手机端访问的,基本上都是webkit内核(Image的方式在firefox中不兼容也不甚关系),所以我们决定改用Image来加载所有JS。
第三个版本,完美这个版本除了解决第二个版本的假死问题,还加入了dns-prefetch,关于这部分的背景和思路可以参考我另外一篇文章:《预加载系列一:DNS Prefetching 的正确使用姿势》。
... ...
上线后,丝丝润滑无痛无痒,完美
第四个版本,可以做更多注意哦,重点来咯!
尽早加载css是减少首屏时间的关键(引申阅读),直接把css inline到html里是个不错的方案。但是,这种方案的缺点是无法充分利用浏览器缓存。所以,我们尝试在现有的File Prefetching 的基础上,再进一步,让首次访问足够快(用css line),后续访问又能利用起浏览器缓存。
我们对一部分重点页面的css文件改用类似加载js的方式去加载,并在加载成功的回调里加一条cookie记录标示该css文件已经被下载。这样在后端输出html的时候,可以根据cookie的信息知道这几个css文件是不是已经在浏览器里cache住了。如果是则正常输出一个标签。如果不是,说明用户是第一次访问这个页面,则直接把css文件的内容inline到html里以求最快出首屏。当然,也会出现从cookie上看客户端已经cache了某个css文件,但实际上没有的情况,由于这种情况下html里输出的还是一个link标签,并不会影响正常的流程。
相关代码大概是这样的,需要的朋友可以参考下:
var loadCss = function(key, url) { var image = new Image(); var date = new Date(); date.setTime(+date + 1 * 86400000); // 因为下载的不是图片,实际触发的是onerror事件 image.onload = image.onerror = function () { document.cookie = key + "=" + url.slice(url.indexOf("build_css")) + ";path=/;domain=.youzan.com;expires=" + date.toGMTString(); }; image.src = url; } preloadCss = { key1: "文件路径", key2: "文件路径2" ... } for (var key in preloadCss) { loadCss(key, preloadCss[key]); }总结
在做 File Prefetching 的过程当中,每一个版本的优化都是不同的人在做的:
A起了个头 ->
B改进到能上线的标准 ->
发现有问题,C改进了它 ->
D又在这个基础上做出了最后一个版本。
这种感觉非常好:)
TODO其实还有一类资源可以加到这个prefetching.html里,那就是常用的图片,不过我们还没这么做。
现在我们有赞全部移动web页只使用一个prefetching.html,并还没有针对不同的条件进行针对性的的prefetching。
本文首发于我的
SegmentFault专栏:https://segmentfault.com/a/1190000004189...
个人技术博客:http://delai.me/code/file-frefetching/
转载请注明出处
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/61759.html
摘要:前端日报精选和实现直接当前页预览手淘互动动效的探索白话原型和原型链源码解析浏览器前端优化中文第期深入理解中的动画演示,提高你的网页开发技能知乎专栏实战一概览工作机制第部分迷津欲有问把卖了众成翻译代理程序实现复制集搭建及抓包 2017-08-24 前端日报 精选 iframe和HTML5 blob实现JS,CSS,HTML直接当前页预览手淘互动动效的探索白话原型和原型链React 源码解...
摘要:错过一周的优质内容,不要再错过周一的快速回顾寒潮来得出乎意料,手脚,一遍听着史诗巨著张士超你到底把我家钥匙放哪里了,一边将优质内容进行整理一周咨询当技术成为一种武器翻译组一周简讯跟着轮子哥造轮子基本概念二排版前端名一前端远程调试德来预加载 错过一周的优质内容,不要再错过周一的快速回顾 寒潮来得出乎意料,dong手dong脚,一遍听着史诗巨著《张士超你到底把我家钥匙放哪里了》,一边将优质...
摘要:错过一周的优质内容,不要再错过周一的快速回顾寒潮来得出乎意料,手脚,一遍听着史诗巨著张士超你到底把我家钥匙放哪里了,一边将优质内容进行整理一周咨询当技术成为一种武器翻译组一周简讯跟着轮子哥造轮子基本概念二排版前端名一前端远程调试德来预加载 错过一周的优质内容,不要再错过周一的快速回顾 寒潮来得出乎意料,dong手dong脚,一遍听着史诗巨著《张士超你到底把我家钥匙放哪里了》,一边将优质...
阅读 702·2021-11-11 16:54
阅读 3030·2021-09-26 09:55
阅读 1947·2021-09-07 10:20
阅读 1170·2019-08-30 10:58
阅读 1010·2019-08-28 18:04
阅读 678·2019-08-26 13:57
阅读 3541·2019-08-26 13:45
阅读 1121·2019-08-26 11:42