Weex在大前端的应用,以及预加载缓存提高页面渲染速度
前言
现在市面上比较流行的混合框架,主要是Facebook的React Native、阿里的Weex(目前已转移到Apache维护)以及Google的flutter;我司在2016年的时候在调研一款混合框架,当时比较了React Native和Weex两款,Weex的Vue语法学习起来几乎没有成本,而React Native的JSX语法上手起来还有一定的学习成本,并且Weex是支持三端通用的,性能上官方介绍是比React Native要好的,于是选定了Weex作为公司的混合项目应用。
正文
Weex的安装
Weex 的安装,首先需要安装NodeJs。在Mac下通过brew install nodejs
然后通过npm install -g weex命令安装weex 。整个环境就安装好了
详细介绍可参考weex官方文档https://weex.apache.org/zh/guide/introduction.html
Weex的使用
Weex是Vue的一个子集,除了一些方法和属性不支持,以及没有js的Dom操作,其他与Vue的语法几乎一致,详情参考平台差异
以及在Weex中使用Vue.js
会有详细介绍
https://weex.apache.org/zh/guide/use-vue-in-weex.html
有一点需要注意,在使用的时候需要严格按照Weex的文档来,比如属性支持什么单位,以及方法等等,否则会有一些意想不到的坑出现。
Weex的预加载方案
通常在编写完Weex后,编译后会生成js文件,然后把生成的js文件放在服务器通过HTTP的方式加载渲染,或者打包在APP包内,通过本地文件加载的方式渲染
通过打包本地加载的方式渲染不存在性能上的问题,因为没有网络上的消耗,但不能通过热更新的方式更新打包在APP内的js文件
通过HTTP远端加载的方式,因为每次加载js,都会有网络上的消耗,因此今天就说说这个问题我们是怎么解决的。
为什么需要做缓存
- 减少数据请求,减少设备端网络流量
- 弱网络状态下,能够快速展示页面
- 提升我们的综合能力,以及技术水平
APP端缓存的几种形式
- 设备端初次打开APP时,拉取缓存配置
- APP端运行时定时拉取缓存配置
- 当有更新缓存时,发送静默推送,拉取缓存
- 懒加载形式,按需缓存,在加载页面时通过页面参数进行缓存处理
缓存框架需要满足以下特点
- 简单,轻量级(对于后端服务器来说不需要太多开发成本)
- 高可用(缓存加载失败或路径错误,不能报错)
- 安全性(需考虑一下缓存文件是否存在被别人破坏或替换)
- 日志记录(需记录缓存读写异常日志,并上传至服务器,便于后期排查问题和追踪命中率)
- 业务一致性(不能破坏现有代码处理逻辑,如现有url的业务参数)
- 缓存淘汰(LRU:least recently used最近最少使用),当缓存容量到达一定级别时的处理方案
缓存设计
首先说下第四种懒加载形式按需缓存
因weex sdk加载器通过url(支持远端http url和本地file url)加载,而url又可扩展多个参数,因此适合在url后面追加缓存参数来支持缓存。并且sdk又提供了onJSDownloadedFinish方法,因此实现起来就非常简单了
URL设计
http://172.17.83.27:8081/dist/index.js?cityid=111&_cache=1&_v=2018081123
说明:
- cityid=111 业务参数,与缓存无关,远端下发
- _cache=1 有此参数,且值为1,表明启用缓存
- _v=xxx 版本号(string类型),与本地缓存文件比对若不一致则视为缓存过期,建议采用日期格式,如2018081123
缓存文件设计 当客户端在加载远端地址时http://172.17.83.27:8081/dist/index.js?cityid=111&_cache=1&_v=211,首先判断_cache是否=1,若为1并且有_v版本号就走缓存处理模块,否则就直接加载url进行渲染,然后取http://172.17.83.27:8081/dist/index.js的md5值,判断本地存储中是否包含key,若包含,然后取value中的_v与远端url的_v参数比较,若一致则把value中的文件物理路径参数取出加载, 若不一致,则直接加载远端url渲染,渲染完成后,在weex提供的onjsdownload方法中,进行保存文件操作
设备端初次打开APP时,拉取缓存配置
这种缓存设计,在打开APP时,通过接口拉取缓存配置表
[
{
"url":"http://172.17.83.27:8081/dist/index.js?cityid=111&_cache=1&_v=2018081123"
},
{
"url":"http://172.17.83.27:8081/dist/index.js?cityid=111&_cache=1&_v=2018081123"
}
]
然后循环去比对本地缓存配置是否与url的缓存配置一样,若不一样则在APP后台下载js文件并缓存本地,缓存设计与上面所说到的一致。
也可以通过增量更新js的方式,在拉取配置时,传入本地缓存版本,服务端返回新的缓存版本,客户端在处理完缓存时,把API返回的配置版本cacheVersion覆盖,则下次请求时再传入cacheVersion,然后API判断配置版本一致,则不下发cacheList即可。但这种对缓存的控制要严格,好处是当有n多个cacheList时,不需要下发全部的,只需要下发当前版本变动的cacheList即可
{
"cacheList":[
{
"url":"http://172.17.83.27:8081/dist/index.js?cityid=111&_cache=1&_v=2018081123"
},
{
"url":"http://172.17.83.27:8081/dist/index.js?cityid=111&_cache=1&_v=2018081123"
}
],
"cacheVersion":1.098
}
APP端运行时定时拉取缓存配置
通常是在运行过程中,通过后台计时器,定时拉取配置列表,若有更新,则随机处理。好处是缓存的及时性比较高。
当有更新缓存时,发送静默推送,拉取缓存
在有缓存更新时,通过发送静默推送的形式,去执行更新逻辑,但需要注意静默推送只有APP在后台时才生效,通常是作为一种辅助手段来处理。
本文首次发布于 孙忠良 Blog, 作者 [@sunzhongliang] , 转载请保留原文链接.