[原文地址】:https://github.com/amfe/article/issues/21css
2015年是全面『无线化』的一年,在BAT(财报)几家公司都已经超过50%的流量来自移动端,此次 双11
更是占到了68.67%无线交易 (天猫微博)。html
手淘中大量的业务采用H5的方式开发,H5体验好坏全面影响着手淘的使用体验。前端
今年手机淘宝在技术上重点解决“顿”,“卡”,“慢”的问题,并提出了“521法则” ,具体指:java
其中1S加载完成是H5页面须要解决的重点问题,也是难点。android
下面给你们介绍咱们1年多来解决了些什么样的问题,以及带来多少性能的提高。如下每一条都是手淘在无线领域得到的宝贵经验。ios
首先给你们介绍一下目前手淘的环境状况(供你们在设备兼容方面参考)。git
操做系统方面iOS占比42.23%,Android 占比52.38%,阿里云OS 占比5.29%,Windows Phone 占比 0.1%。github
iOS 系统版本占比状况:web
Android 系统版本对比iOS 碎片化较为严重,所幸4.0如下版本占比小于10%。chrome
占好比下:
网络状况方面,得力于近年的3G/4G推广已经占35%,2G网络占比15%左右。
运营商方面 中国移动占据70%的用户,中国联通18.12%,中国电信11.69%。其中须要注意的是移动3G技术(TD-SCDMA)性能差设备支持少,移动4G容易在信号不理想的地段降级成2G。
淘系H5页面主要在手淘客户端中展示,为了了解H5页面在客户端中的性能表现,咱们在WebView容器中作了大量性能数据的采集,以页面,数据接口,单个静态资源为维度采集。
H5页面:咱们以WebView的DidFinishLoad事件触发做为完成加载(Fully Loaded)的时间。
同时对支持performance.timing的设备收集Timing数据,用于详细分析网络请求各阶段的性能消耗状况。
WebViewDidFinishLoad 官方解释:Sent after a web view finishes loading a frame. Android iOS
针对几个主要的业务,咱们将收集到的用户性能数据整理后获得如下的结果(部分业务按传统的网页性能优化方法优化过)。
性能状况很是不理想,不达标严重。2G下大于10s的占比在50%, 3G:6s内的低于70%近一半。
看到上面的性能状况,咱们最早想到的优化方法就是PC时代YAHOO 23条web性能优化军规。
首先看看咱们平常业务的请求瀑布图是怎么样的,根据这些状况看那些能够用规则去优化。
iconfont对于前端来讲有不少优势:自由变化大小 矢量不失真、自由修改颜色、能够添加一些视觉效果如 阴影、旋转、透明度、兼容IE6。
目前你们都基本上从平台上生成,生成后的文件以下:
@font-face {
font-family: "iconfont";
src: url('iconfont.eot'); /* IE9*/
src: url('iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('iconfont.woff') format('woff'), /* chrome、firefox */
url('iconfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
url('iconfont.svg#iconfont') format('svg'); /* iOS 4.1- */
}`
这样直接引用在项目中,真实在手机上的网络请求以下(在桌面版Chrome浏览器网络中没法看到这些请求):
这样形成了极大的网络带宽的消耗,这些icon资源每每在界面渲染中占据重要位置。
目前咱们移动端只加载ttf一个字体文件,对于较小的文件也能够考虑base64在css文件中。
平常的业务中,一个页面每每拆分出多个异步数据接口(后端开发说:解耦),甚至首屏也须要3-5个接口(如动态banner区块,推荐内容,商品列表等),有些还有嵌套关系。
可是这些对页面性能形成不小的影响。
手淘中某个接口在各网络下的请求性能,2G,3G下平均的消耗时间在2-6s完成下载。其中几个请求性能稍差点对整个页面影响也深远。
在咱们CaseByCase的分析中发现,页面&静态资源的重定向会形成巨大的性能损耗。
特别使用前端JS脚原本实现页面跳转的。
手淘的特色就是图片多,图片的性能好坏可不只仅影响用户体验哦,还直接影响着交易,钱 钱 钱…
咱们在图片方面作了大量的优化。
手淘2年前已经开始使用WebP格式了(主要native使用),1年前H5全面使用,其中iOS 的webview中由手淘以插件的方式支持。咱们以手淘线上真实案例来看使用webp格式的先后效果。
案例为:线上的一个活动页面,打开一看其中的banner 就320多KB,整个页面加载457KB,若是就单单banner图片换成webp格式,整个页面的大小就只有181KB。
使用WebP前
使用WebP后
Banner部分对比
这种业务类型的案例,咱们改进一下就能够为用户,为公司省70%
的流量费用。
商品图片在手淘的各个产品中都是必不可少的,为了适应不一样业务需求的须要,咱们在CDN服务上生成各个尺寸和质量的图片(近100个规格)。
计算方式以下:
根据设备DPI值和图片质量Q值作优化,达到最优视觉体验和加载性能(DPI高,宽高增长后可适当下降质量)。
Sprite图片(又称:雪碧图)被运用在众多使用了不少小图标的网站上。相对于把每张小图标以单个文件的形式引用到页面上,Sprite图片会只要请求一张图片就够了,减小了请求数提高了加载性能,还有就是方便图标管理。但在移动互联网时代在使用Sprite图片须要合理利用,否则反对性能形成影响。
Decoded in memory的计算公式: w x h x 4(宽 x 高 x 每一个像素4个字节)
若是设备DPI大于1,还须要 X DPI系数。如Retina设备X 4,RetinaHD设备X 9.
因为图片在浏览器中的解码方式,合理的生成紧凑的Sprite图片,便可以带来更少的请求数,又高性能低消耗。
通过几轮的常规前端性能优化后,页面性能有进步,可是离目标还远远不够。咱们也不断的问本身到到底那里慢,那里瓶颈最大。咱们开始试着CaseByCase的分析页以及梳理H5在手淘中的全链路性能消耗。
最终作了一些和native结合的优化思路。
DNS解析想必你们都知道,在传统PC时代DNS Lookup基本在几十ms内。而咱们经过大量的数据采集和真实网络抓包分析(存在DNS解析的请求),DNS的消耗至关可观,2G网络大量5-10s,3G网络平均也要3-5s。
案例:iPhone5s 联通3G
针对这种状况,手淘开发了一套httpdns,httpdns是面向无线端的域名解析服务,与传统走UDP协议的DNS不一样,httpdns基于HTTP协议。 基于HTTP的域名解析,减小域名解析部分的时间并解决DNS劫持的问题。
手淘httpdns服务在启动的时候就会对白名单的域名进行域名解析,返回对应服务的最近ip(各运营商),端口号,协议类型,心跳 等信息。
传统DNS由Local DNS解析域名,不一样运营商的Local DNS有不一样的策略,某些Local DNS可能会劫持特定的域名。采用httpdns可以绕过Local DNS,避免被劫持;另外,httpdns的解析结果包含HMAC校验,也可以防止解析结果被中间网络设备窜改。
对域名解析而言,尤为是CDN域名,解析获得的IP应该更靠近客户端的地区和运营商,这样才能有更快的网络访问速度。然而,因为运营商策略的多样性,其推送的Local DNS可能和客户端不在同一个地区,这时获得的解析结果可能不是最优的。httpdns可以获得客户端的出口网关IP,从而可以更准确地判断客户端的地区和运营商,获得更精准的解析结果。
在2G/3G这种移动网络下,DNS解析的延迟和波动都比较大。就单次解析请求而言,httpdns不会比传统的DNS更快,但经过httpdns客户端SDK的配合,整体而言,可以显著下降解析延迟和波动。httpdns客户端SDK有几个特性:预解析、多域名解析、TTL缓存和异步请求。
传统DNS的解析结果只有ip,httpdns的解析结果采用JSON格式,除了ip外,还支持其它域名相关的信息,好比端口、spdy协议等。利用这些额外的信息,APP能够启用或中止某个功能,甚至利用httpdns来作灰度发布,经过httpdns控制灰度的比例。
在通过以上的优化方案后,H5页面的性能始终离目标还远。在移动端建连的消耗很是大,在业界也只有SPDY 这个玩意儿比较新颖。
理论上SPDY协议能够完成多路复用的加密全双工通道,显著提高非wifi环境下的网络体验。
看着很牛逼的技术,可是等咱们第一期上线后发现,从数据上几乎察觉不了变化。
域名收敛是指尽可能控制一个页面中使用的域名数量。为何要这么作呢?咱们前面提到DNS解析,减小域名数量能够下降DNS解析的成本。上文还提到SPDY协议,其中一个特性就是复用请求,使用同一个域名能够更多的复用请求。这个PC时代正好相反,咱们原先用多个域名提高并发请求量已提高性能。
PC时代的域名数量相似这样的
最终结合SSL+SPDY+域名收敛 才发挥出真正的做用。下图是各网络下SSL 和 非SSL 的性能状况。
动态数据部分,相信各个公司都差很少,动态数据会有专门的API提供出来。手淘(mtop平台)也同样,接口总会有各类状态,登陆失效,令牌过时,签名失效等。手淘使用了重发请求的方式来获取新的签名令牌等。致使以下的状况(始料未及):
在手淘真实环境中发现一次令牌过时,能够形成10多秒的延迟。
手淘在启动的时候Native已经作了不少的数据请求,这些也是mtop请求,只是由native程序发出。 咱们判断到页面是在手淘客户端中就会使用native发出mtop数据请求,这样就规避了令牌失效,签名失效的问题。
直本次优化后,咱们第一次看到了很是激动人心的数据:第一次里程碑式的提高
优化前
优化后
手淘中加载H5页面的首屏白屏时间较长,基于此,集团各BU都内部产生了离线包的方案(手淘,航旅,钱包),将静态资源经过Hybrid的方式提早加载到本地。大量了资源预加载给H5页面带来了极大的提高,资源加载时间降到30ms内。
今年双11前,针对预加载方案,在技术上解决了3个痛点
关于 预加载&离线化方案详细技术细节不少,这里先简单阐述这个功能带来的性能提高价值。
下图案例:
这是第二次里程碑式的提高,3G,4G,WIFI网络性能全面提高。
截至到这个时间点为止,咱们个别业务的性能有了显著的提高。如下是其中一个业务的3个性能优化节点的性能优化对比。其中10s以上加载完成的占比大大的缩小,1s之内的占比上升较高。
业务数据统计在平常工做中是必不可少的部分,因统计部份量级不大,每每会忽视掉。其中咱们对一个业务CaseByCase的分析后发现。一个中国移动 2G/3G.Edge的用户在请求H5页面的时候 log.mmstat.com 的日志埋点花了近6s
才加载完成。
后面咱们对数据统计部分作了Native的异步上传。效果是这样滴:
iOS:
Android:
第三次里程碑式的提高,2G网络性能全面提高
前面说了这么多性能优化,确定会有问,花了这么多力气,前端到客户端到后端搞了这么多,价值在那里呢。业界google,amazon,microsoft都给过速度性能对业务对GMV的影响。
下面是两个手淘中的业务在持续几个月的性能优化后UV,跳失率,停留时间的变化。
好了,说了这么多此次双11搞的怎么样呢?
在无线时代,H5页面中的任意一个微小的点都会应网络问题被放大N倍。持续分析用户真实数据和CaseByCase的分析不一样业务场景,才能真正找到性能瓶颈。
H5要达到极致的体验,须要你们跳出前端的圈子,从客户端,后端 一块儿的角度来共同协助发挥各自的优点才能真正作到极致的体验。后面有更多精彩等这你们。