智能手机的发展

 

伴随着智能手机在国内的普及及其换代速度,HTML5技术在移动领域的发展终究比PC端来的更迅速些。

 

根据移动互联网第三方数据挖掘和整合营销机构艾媒咨询(iiMedia Research)发布的《2012中国智能手机市场年度研究报告》数据显示,截止2012Q4季度,中国智能手机用户数达到了3.8亿,同比增长72.7%

(2012中国智能手机用户规模发展状况)

 

报告指出,在操作系统占有率方面,Android份额到达68.6%,iOS有所下滑,占12.8%,Symbian则难抑下滑趋势,占12.4%,Windows Phone作为后起之秀,份额只占3.8%,但后续占有率会持续扩大;

 

(2012年中国智能手机市场操作系统分布状况)

 

在系统平台分布方面,Android上V2.x是主流版本,iOS上V5是主流版本

 

2012年中国智能手机市场Android、iOS平台版本分布

2012年中国智能手机市场Android、iOS平台版本分布(以上数据来自iiMedia Research《2012中国智能手机市场年度研究报告》)

 

Application Cache的问题


回到正题,HTML5伴随着智能手机的发展,在手机应用开发方面的优势越发凸显,尤其是其跨平台、版本更新等优势;在一些对性能要求稍低及项目人员紧张的产品中,使用WebApp的形式(大多为Native App+WebApp的混搭方式)不失为一种好的解决方案。

 

排除WIFI,对于国内那昂贵的流量费用,而且是极不稳定的GPRS来说,WebApp的开发不得不考虑一个问题:缓存。

 

开始我很兴奋,知道HTML5给我们提供了Application Cache离线储存接口,通过manifest文件,我终于可以翱翔在离线数据的大海中。

 

理想很丰满,现实却总是很骨感;Application Cache这货可真不好管理,如果你还不清楚它的实际情况,可以参考下这篇文章《Application Cache is a Douchebag》,内容我就不翻译了,但标题我得翻译下:《Application Cache就是个人渣》。

 

关于Application Cache,有一个致命的缺点,那就是你不能选择更新哪些资源。你的manifest文件更新了,所有指定的资源都会给下载,对于流量是金的移动互联网来说,这不就是坑爹嘛。

 

localStorage


但上帝总在关了一扇门之后,给我们开启另一扇门,而这一扇门就是:localStorage。

 

localStorage的存储空间是按域名来计算的,不同平台容量不同,即使相同平台相同版本但由于手机厂商调教不一,造成实际使用中的大小也是不一样的。就拿笔者的MX2(Android 4.1)自带的浏览器来说,测试出来的结果是64M。虽然不同平台及版本存在差异,但对于大部分WebApp来说,这样的存储空间已经可以派上大用场了。

                    (以上数据来自Browserscope,测试地址点这里)

 

在使用localStorage前,我们还需要清楚webview对localStorage的影响,特别是对于那些嵌套在不同客户端的WebApp来说,webview对localStorage的支持与否也是不可忽视的一点。同时,对于业务较多的根域来说,不同WebApp之间可能会出现空间上的使用管理混乱问题,这需要在前期规划时对存储做好队列管理工作。

 

解决方案:WebAppCache


考虑到Application Cache的维护麻烦问题,在我最近的项目中就基本放弃了manifest的方式,转而使用类MVC的方式(估且这么叫吧)。

 

WebAppCache方案由app.json配置应用的每个资源信息,app.html进行整个应用的调度,包括版本对比、更新以及缓存队列管理。由于使用了Ajax来拉取文件,所以受同源访问限制,对跨域请求有要求的同学,可以使用withCredentials,这里就不仔细展开了,只是提供其中一种简单的实现方式。

 

假设我们的目录结构如下:

 

WebAppCache约定app.html与app.json处于相同的目录层级,其他的资源不作要求。

 

则实际请求地址如下:


index.html -> /app/app.html 或 /app/app.html?v=index
inner/demo.html -> /app/app.html?v=inner.demo

 

app.json应用配置文件

 

 

app.html缓存调度

 

 

app.html我使用了Application Cache,这在不使用SPA方式对页面进行documwnt.write输出时,可以加快页面载入速度。当所有的资源处理完毕之后,会将内容渲染到当前页面输出。

 

WebAppCache.js之队列管理

 

为了兼容同一根域下多WebApp的场景,WebAppCache.js以应用为单位进行缓存管理,每次进行写操作时,都会缓存当前的key到队列里;同时资源队列以”资源缓存时间先后 + css核心资源(按依赖权重由低到高排列)+ js核心资源(按依赖权重由低到高排列)“进行排列;


在溢出时,按App使用时间先后进行队列淘汰;当所有非当前App淘汰完毕后,再对当前App资源进行资源队列淘汰;在淘汰当前App资源队列后仍无法存储时,最后尝试清空当前App缓存再试。

 


 

对于同一根域下多WebApp的场景,当用户同时开启多个应用造成空间不足时,当前的解决方案在localStorage支持的情况下可能会出现数据缓存不久就被淘汰的情况,这种情况可以通过转换为sessionStorage来进行优化。

 

有一点需要注意,在使用document.write输出文档流时,要在window.onload触发后方可进行页面渲染,否则原文档流不会被覆盖。