首先,发现黑科技的成因
今天在微信微信官方账号上看到一篇技术博文,想用Evernote收藏,于是发了一篇文章链接到pc。然后习惯性的打开控制台,看看源代码,想知道微信最近用了哪些新技术。
哈哈,下面激起了我侦探的欲望。加载页面后的异常点是只加载了一个js,如下图所示:
我很奇怪为什么Disable cache已经打开了,js只加载了一个,而且体积这么小。然后按Ctrl O搜索资源文件,发现自己被“忽悠”了。事实上,不止一个js文件。
一道光闪过我的脑海,我没有用本地存储缓存它,是吗?快速看一下localStronge,真的是。
我内心澎湃,这不就是我之前想实现的加载性能优化的想法吗?亲爱的,我无知。前端团队已经实现了代码。
第二,谈谈文件加载的优化
一般来说,前端资源文件加载优化就是在不迭代文件修改的情况下,尽可能多的使用缓存,避免多次下载同一个文件。
一般的做法是尽可能延长资源的有效期,即在Cache-Control中设置max-age,使页面资源请求的返回代码为304,浏览器可以直接使用本地缓存。
虽然pc端的协商缓存(304)快,但由于网络原因,手机端的协商缓存效果不如pc端。而且手机经常清空本地缓存,文件缓存时间不会很长。
这时,localStorage就派上了用场。
与cookie相比,localStorage可以缓存大量数据,并且是永久有效的。因此,如果将js资源和css资源存储在localStorage中,可以节省发送http请求所消耗的时间,大大提升用户的浏览体验。
第三,使用本地存储作为资源缓存需要解决的问题
3.1版本更新机制
只要项目还在迭代开发,就很难避免更新资源文件的需要。
普通的资源请求可以基于
文件名是md53358res.wx.qq.com/mmbizwap/zh。
或者
在资源链接v=201612051739后添加一个特定的后缀http://1.ss.faisys.com/js/comm/fai.min.js?
标记以确定资源是否需要更新。
如果使用本地存储,则需要新的缓存更新机制。
3.2为更新代码搭建脚手架
使用本地存储缓存,需要一个新的支架来管理资源文件的读写。
3.3后台输出资源配置信息
因为前端需要更新资源,后台需要输出一个依据供前端判断,也就是需要一个资源配置信息。前端根据配置信息进行匹配比较,最终决定是使用localStorage缓存还是重新发起下载最新资源文件的请求。
3.4存在安全隐患
客户端可以随意修改localStorage中的信息。如果有黑客想练,可以随意注入js代码。然后,当页面刷新时,注入的代码也将被执行。
第四,微信的实践分析
4.1版本识别
以__MOON__a/a_report.js为例,版本信息用key __MOON__a/a_report.js_ver存储,存储值为//RES . wx . QQ.com/mmbizwap/zh _ cn/htmlessent/js/a/a _
如果在正常加载模式下直接取出该值,并设置为脚本节点的src属性,则可以完成加载。
微信判断版本是否最新,即与后台输出的配置信息进行比较,最终得出是否更新的结果。
如果该值与配置信息一致,则使用缓存。否则,重新启动请求的加载。
4.2脚手架
可以看到微信使用了自己的脚手架moon.js,这个网页中的实际文件名是moon32ebc4.js
因为是变量名比较混乱的文件,看具体代码的方向有点难,这里就不分析了。
4.3资源配置信息
因为scaffold moon.js需要资源配置信息才能正常工作,所以配置信息会在moon.js之前输出。
依次查看moon.js前的脚本标签,我们找到了json对象window.moon_map。
使用控制台输出变量,查看如下信息:
看到这里,可以明确一点:这是更新机制所必需的资源分配信息表。
此外,可以看到配置信息的json对象的键对应于localStorage中的键。同样,数值也是一一对应的。
4.4 XSS袭击
这是为了验证微信的缓存机制中是否有XSS攻击,所以在这里看到童鞋不要做坏事。
我在js缓存代码中插入了alert('呵呵');查看页面刷新时是否会出现弹出窗口,以验证是否存在攻击漏洞。
刷新页面后,结果如下:
可见微信并没有解决这样的问题。因此,这种缓存机制仍然存在固有的缺点。
4.5测试微信的更新机制
修改localStorage中key __MOON__a/a_report.js_ver对应的值值,让微信脚手架moon.js更新__MOON__a/a_report.js,刷掉我刚刚主动插入的代码。
这里我把文件名改成了***587.js(原来的文件名是***586.js)。然后F5刷新页面。
结果就是report.js的代码更新了,版本号恢复到* * * 586.js。
五.结论
本地存储缓存有它的用途,但它不是万能药。要注意上面提到的坑。
我可以将适用场景总结如下:
1.第一次屏幕渲染不需要的css文件可以用作LS缓存。
第一次屏幕渲染需要的Css需要用常规的方式输出,因为SEO需要它,否则当爬虫抓取页面时,页面效果会很差。代替第一屏的css,可以使用LS缓存来减少资源的下载时间。
2.展示类、动画类等非业务主逻辑的代码,可以作为LS缓存。
这样可以在一定程度上避免业务层的安全漏洞。当然,不管前端怎么保护,都是一层薄薄的纸。重要的是后台接口应该是安全的。
3.移动终端可以做LS缓存。PC端做LS缓存,优化效果不大。
以上就是本文的全部内容。希望本文的内容能给大家的学习或工作带来一些帮助,也希望多多支持我们!