随着前端开发的兴起,QQ也逐渐演变为Web与原生终端混合的开发模式。得到Web动态运营能力的同时,QQ也在交互响应速度、后台服务压力、海量用户集的带宽冲击等方面,受到了更多的挑战。在快速的Web运营节奏下,必须保证嵌入QQ的第三方业务也始终处于一个高质量的服务状态。针对这些问题,QQ团队除了采用动态CDN、后台渲染等全栈手段优化体验,也构建了围绕速度、成功率、页面异常等维度的监控体系来保障服务质量。 写在前面 首先自我介绍,我叫涂强。我于2005年加入腾讯,那个时候还不流行移动端、hybrid等开发。我当时主要开发PC版本的QQ,后来负责PC版QQ UI引擎的时候做过一些尝试,即在PC客户端上集成浏览器内核,那个时候做了一些H5和native混合开发的框架性工作。之后我加入了腾讯QQ会员团队,负责QQ会员在移动终端上的技术,同时也有很艰巨的任务:维护手机QQ中的所有H5 hybrid开发的框架,即WebView组件的技术工作。 言归正传,现在主流的hybrid还是H5 + native,H5开发对现在移动终端的重要性不必多提,但H5在native中很明显的问题大家都看得到,比如打开应用的时候要等很久的页面loading,loading时用户看到转菊花的界面很可能就流失掉,这也是产品经理不想看到的状况。还有一点是每次打开H5都涉及到网络交互、文件下载,这些操作会消耗用户的流量,如果流量消耗大用户也会不高兴。 今天给大家分享的内容主要是介绍QQ会员团队如何在页面打开时间以及用户流量方面所做的优化,分别对应sonic和reshape的两个自主技术框架。 传统页面的动静分离 所有的技术选型与框架都是要结合业务形态来选择,大家对QQ会员的业务形态可能有简单的了解。手机QQ中可以说有大概70%以上的业务由H5开发,像会员的主要商城:游戏分发中心、会员特权中心和我现在负责的个性化业务的商城等等。这些商城特点很明显,它们不是UGC生成的页面,是产品经理在后台配置的内容,比如在页面上可以看到的表情和主题等等。 这些页面相对传统,在最初的时候,一个传统的H5页面为了提升速度和体验会做一些动静分离的优化,比如页面顶部的banner以及下面我们称作为item的物品区域,这些区域的数据可以由产品经理自由编辑随时更换,我们会通过页面loading之后发起CGI请求,从dataServer获取数据,然后再拼接起来。 这里的流程大概如下,用户从click开始,到launch WebView,WebView去加载CDN上的HTML文件,页面loading起来后才会去获取JSON,为了加速这个过程可能会用到localStroage做缓存,这整个过程是非常传统的静态页面加载过程,相对比较简单。 但上述方案有一些问题,比如我们在launch WebView的时候网络处于空等状态,这会浪费时间。我们团队内部统计了Android机器launch WebView大概需要1秒以内(因为手机QQ是多进程的架构,WebView生存在另一个进程内部,launch一次WebView除了进程loading还有浏览器内核的加载)。 其次,发布在CDN上的静态页面内部不包含item数据,所以用户第一眼看到从CDN下载的页面,里面的banner区域和item区域处于一片空白,atv直播,这对用户体验也是很大的伤害。 还有一个问题,页面loading起来要refresh当前的DOM,即拉取JSON之后拼接DOM结构再refresh,我们发现在一些QQ用户所使用的低端Android机器里,这个执行也会非常消耗时间。 静态直出+离线预推 面对这些问题我们大胆采取了一些技术手段,我们称之为静态直出+离线预推的模式。首先我们把WebView的加载和网络请求做了并行,我们所有的网络请求并不是从WebView内核发起request,而是loading WebView的过程中,我们通过native的渠道建立自己的HTTP链接,然后从CDN和我们称作offlineServer的地方获取页面,这个offlineServer也就是大家听说过的离线包缓存策略。 我们在native会有offlineCache,发起HTTP请求的时候首先检查offlineCache里有没有当前HTML缓存,这个缓存和WebView的缓存是隔离的,不会受到WebView的缓存策略影响,完全由我们自控。 如果offlineCache没有缓存才会去offlineServer去同步文件,同时也会去从CDN去下载更新。我们在CDN上存储的HTML已经把banner和item等所有的数据打在静态页面里,这个时候WebView只要拿到HTML就不需要再做refresh和执行任何JS,整个页面可以直接展示出来,用户也可以进行交互。 (责任编辑:本港台直播) |