<强>一,发现黑科技的起因强>
今天在微信公众号看到一篇技术博文,想用印象笔记收藏,所以发送了文章链接到pc上。然后习惯性地打开控制台,看看源码,想了解下最近微信用了什么新技术。
呵呵,以下勾起了我侦探的欲望。页面加载后的异常点就是只加载了一个js,如下图所示:
我很诧异,为什么已经开启了禁用缓存,js只加载了一个,而且体积这么小,接着,我按住Ctrl + O进行资源文件查找,发现我被“忽悠”了。其实根本就不止一个js文件。
脑袋里灵光一闪,不会是用localStorage做了缓存吧? !赶紧看了下localStronge,还真是....
心里一阵澎湃,这不是我之前就想实现的加载性能优化的想法吗!乖,乖我孤陋寡闻了,已经有前端团队实现了代码。
<强>二,谈谈文件加载方面的优化思路强>
通常,前端的资源文件加载优化,就是在文件不修改迭代的情况下,尽可能多地利用缓存,避免多次下载同样的文件。
一般的做法就是尽量延长资源的有效期,也就是设置cache - control里的信息,使页面资源请求的返回码为304,让浏览器直接使用本地缓存。
虽然pc端的协商缓存(304)很快,但手机端因为网络原因,协商缓存的效果就没电脑端那么好了。而且,手机会经常清除本地缓存,所以文件缓存的时间也不会很长。
这个时候,localStorage就派上用场了。
localStorage相比饼干,可以缓存大体积的数据,而且是永久有效,所以,如果把js资源和css资源存储在localStorage中,则可以省去发送http请求所消耗的时间,大大提高用户的浏览体验。
<强>三,用localStorage做资源缓存需要解决的问题强>
只要一个项目还在迭代开发,就难以避免需要更新资源文件。
普通的资源请求,可以根据
文件名+ md5 http://res.wx.qq.com/mmbizwap/zh_CN/htmledition/js/biz_wap/moon32ebc4.js
或者
在资源链接后面加上特定的后缀http://1.ss.faisys.com/js/comm/fai.min.js& # 63; v=201612051739
做标识来判断是否需要更新资源。
如果用localStorage做,则需要一套新的缓存更新机制。
使用localStorage缓存,则需要一个新的脚手架来管理资源文件的读取和写入。
因为需要前端做资源更新,所以后台要输出一份依据给前端做判断用,也就是需要一份资源配置信息。前端根据配置信息,进行匹配和比较,最终决定使用localStorage缓存,还是重新发起请求,下载最新的资源文件。
localStorage中的信息,客户端是可以任意修改的。如果哪个黑客想练手一下,可以任意注入js代码。那么,在页面刷新的时候,注入的代码也将会被执行。
<强>四,微信的做法解析强>
以__MOON__a/a_report。js为例,版本信息用关键__MOON__a/a_report.js_ver存储,存储的值为//res.wx.qq.com/mmbizwap/zh_CN/htmledition/js/a/a_report32e586.js。
如果按普通加载方式,直接将该值取出来,设置到脚本节点的src属性,即可完成加载。
微信判断该版本是否最新,就是用该值值与后台输出的配置信息进行比较,最后得出是否更新的结果。
如果值值与配置信息一致,则使用缓存。否,则重新发起请求加载。
可以看的出,微信使用的是自己开发的脚手架moon.js,在这个网页中的实际文件名是moon32ebc4.js。
因为是混淆过变量名的文件,所以要看出具体代码的走,向有点费劲,这里就不做分析了。
因为脚手架moon.js需要资源配置信息才能正常工作,所以配置信息一定会在moon.js之前输出。
依次查看moon.js之前的脚本标签,发现了window.moon_map这个json对象。
利用控制台输出该变量查看信息如下: