localStorage的黑科技-js和css缓存机制
发布时间 - 2026-01-10 22:53:16 点击率:次一、发现黑科技的起因

今天在微信公众号看到一篇技术博文,想用印象笔记收藏,所以发送了文章链接到pc上。然后习惯性地打开控制台,看看源码,想了解下最近微信用了什么新技术。
呵呵,以下勾起了我侦探的欲望。页面加载后的异常点就是只加载了一个js,如下图所示:
我很诧异,为什么已经开启了Disable cache,js只加载了一个,而且体积这么小。接着,我按住Ctrl+O进行资源文件查找,发现我被“忽悠”了。其实根本就不止一个js文件。
脑袋里灵光一闪,不会是用localStorage做了缓存吧?!赶紧看了下localStronge,还真是。。。。
心里一阵澎湃,这不是我之前就想实现的加载性能优化的想法吗!乖乖,我孤陋寡闻了,已经有前端团队实现了代码。
二、谈谈文件加载方面的优化思路
通常,前端的资源文件加载优化,就是在文件不修改迭代的情况下,尽可能多地利用缓存,避免多次下载同样的文件。
一般的做法就是尽量延长资源的有效期,也就是设置 Cache-Control里的max-age,使页面资源请求的返回码为304,让浏览器直接使用本地缓存。
虽然pc端的协商缓存(304)很快,但手机端因为网络原因,协商缓存的效果就没pc端那么好了。而且,手机会经常清除本地缓存,所以文件缓存的时间也不会很长。
这个时候,localStorage就派上用场了。
localStorage相比cookie,可以缓存大体积的数据,而且是永久有效。所以,如果把js资源和css资源存储在localStorage中,则可以省去发送http请求所消耗的时间,大大提高用户的浏览体验。
三、用localStorage做资源缓存需要解决的问题
3.1 版本更新机制
只要一个项目还在迭代开发,就难以避免需要更新资源文件。
普通的资源请求,可以根据
文件名+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?v=201612051739
做标识来判断是否需要更新资源。
如果用localStorage做,则需要一套新的缓存更新机制。
3.2 搭建更新代码的脚手架
使用localStorage缓存,则需要一个新的脚手架来管理资源文件的读取和写入。
3.3 后台输出一份资源配置信息
因为需要前端做资源更新,所以后台要输出一份依据给前端做判断用,也就是需要一份资源配置信息。前端根据配置信息,进行匹配和比较,最终决定 使用localStorage缓存,还是重新发起请求,下载最新的资源文件。
3.4 存在XSS安全隐患
localStorage中的信息,客户端是可以任意修改的。如果哪个黑客想练手一下,可以任意注入js代码。那么,在页面刷新的时候,注入的代码也将会被执行。
四、微信的做法解析
4.1 版本标识
以__MOON__a/a_report.js为例,版本信息用key __MOON__a/a_report.js_ver存储,存储的value为//res.wx.qq.com/mmbizwap/zh_CN/htmledition/js/a/a_report32e586.js。
如果按普通加载方式,直接将该value取出来,设置到script节点的src属性,即可完成加载。
微信判断该版本是否最新,就是用该value值与后台输出的配置信息进行比较,最后得出是否更新的结果。
如果value值与配置信息一致,则使用缓存。否则,重新发起请求加载。
4.2 脚手架
可以看出,微信使用的是自己开发的脚手架moon.js,在这个网页中的实际文件名是moon32ebc4.js。
因为是混淆过变量名的文件,所以要看出具体代码的走向,有点费劲,这里就不做分析了。
4.3 资源配置信息
因为脚手架moon.js需要资源配置信息才能正常工作,所以配置信息一定会在moon.js之前输出。
依次查看moon.js之前的script标签,发现了window.moon_map这个json对象。
利用控制台输出该变量查看信息如下:
看到这里,可以明确一个点:这就是更新机制所必备的资源配置信息表了。
而且,可以看出,该配置信息json对象的key,就对应localStorage中的key。同理,value值也是一一对应。
4.4 XSS攻击
此处是为了验证微信的缓存机制是否存在XSS攻击,看到这里的童鞋可千万不要去做坏事。
我在一个js缓存代码中,插入alert("hehe");,看页面刷新的时候,是否会出现该弹窗,来验证是否存在攻击漏洞。
刷新页面后,结果如下图:
可以看出,微信也没有解决这类问题。所以,这种缓存机制,还是有先天不足的。
4.5 测试微信的更新机制
修改localStorage中 key __MOON__a/a_report.js_ver对应的value值,让微信的脚手架moon.js更新__MOON__a/a_report.js,刷掉我刚才主动插入的代码。
这里,我修改文件名为***587.js(原来的文件名为***586.js)。接着F5刷新页面。
结果为:report.js代码更新了,版本号也恢复回 ***586.js。
五、结论
localStorage缓存有其用武之地,但不是万能的。需要注意以上提及的坑。
可以应用的场景我归纳为以下几点:
1. 非首屏渲染需要的css文件,可以做LS缓存。
首屏渲染需要的css,需要按常规方式输出,因为SEO需要,不然爬虫爬取页面的时候,页面效果会很不好。而非首屏的css,则可以用LS缓存,减少资源下载时间。
2. 展示类、动画类等非业务主要逻辑的代码,可以做LS缓存。
这样,可以一定程度上避免业务层的安全漏洞。当然,前端再怎么做防护都是一层薄纸。重要的,还是后台接口要做好安全保护。
3. 移动端可以做LS缓存。PC端做LS缓存,起到的优化作用不大。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
# localstorage缓存
# localstorage
# 使用jquery读取html5 localstorage的值的方法
# JavaScript使用localStorage存储数据
# JS 中LocalStorage和SessionStorage的使用
# JS中LocalStorage与SessionStorage五种循序渐进的使用方法
# JS中利用localStorage防止页面动态添加数据刷新后数据丢失
# JS实现本地存储信息的方法(基于localStorage与userData)
# JavaScript中localStorage对象存储方式实例分析
# 移动端使用localStorage缓存Js和css文的方法(web开发)
# 详解JavaScript中localStorage使用要点
# Javascript 计算字符串在localStorage中所占字节数
# JS localStorage实现本地缓存的方法
# JS+HTML5本地存储Localstorage实现注册登录及验证功能示例
# 加载
# 资源配置
# 可以看出
# 则可
# 可以任意
# 如下图
# 是否存在
# 则需
# 的是
# 都是
# 迭代
# 我在
# 好了
# 看了
# 在这个
# 是有
# 还在
# 将会
# 这就是
# 孤陋寡闻
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
佛山网站制作系统,佛山企业变更地址网上办理步骤?
音乐网站服务器如何优化API响应速度?
教你用AI将一段旋律扩展成一首完整的曲子
EditPlus中的正则表达式 实战(4)
LinuxShell函数封装方法_脚本复用设计思路【教程】
如何获取上海专业网站定制建站电话?
北京网站制作的公司有哪些,北京白云观官方网站?
Laravel如何实现用户密码重置功能?(完整流程代码)
Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】
制作公司内部网站有哪些,内网如何建网站?
Laravel如何与Docker(Sail)协同开发?(环境搭建教程)
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
Laravel任务队列怎么用_Laravel Queues异步处理任务提升应用性能
HTML 中如何正确使用模板变量为元素的 name 属性赋值
js实现获取鼠标当前的位置
Linux系统命令中tree命令详解
Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧
Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤
详解CentOS6.5 安装 MySQL5.1.71的方法
打造顶配客厅影院,这份100寸电视推荐名单请查收
宙斯浏览器文件分类查看教程 快速筛选视频文档与图片方法
大连网站制作公司哪家好一点,大连买房网站哪个好?
韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南
成都网站制作公司哪家好,四川省职工服务网是做什么用?
Linux系统运维自动化项目教程_Ansible批量管理实战
Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】
香港服务器WordPress建站指南:SEO优化与高效部署策略
jimdo怎样用html5做选项卡_jimdo选项卡html5实现与切换效果【指南】
Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】
如何在Ubuntu系统下快速搭建WordPress个人网站?
Laravel如何使用模型观察者?(Observer代码示例)
大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?
Android Socket接口实现即时通讯实例代码
动图在线制作网站有哪些,滑动动图图集怎么做?
Android利用动画实现背景逐渐变暗
Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】
百度浏览器ai对话怎么关 百度浏览器ai聊天窗口隐藏
千库网官网入口推荐 千库网设计创意平台入口
高性能网站服务器配置指南:安全稳定与高效建站核心方案
佐糖AI抠图怎样调整抠图精度_佐糖AI精度调整与放大细化操作【攻略】
php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】
Laravel怎么创建自己的包(Package)_Laravel扩展包开发入门到发布
C++时间戳转换成日期时间的步骤和示例代码
油猴 教程,油猴搜脚本为什么会网页无法显示?
香港服务器租用费用高吗?如何避免常见误区?
Laravel怎么自定义错误页面_Laravel修改404和500页面模板
jQuery中的100个技巧汇总
Swift中循环语句中的转移语句 break 和 continue
JavaScript实现Fly Bird小游戏
Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法

