携程HTML5性能优化实战

本文转自前端之巅(ID: frontshow),原文标题《 魏晓军:携程HTML5性能优化实战 》,作者是APMCon,原文链接是: 魏晓军:携程HTML5性能优化实战 ,前端之巅是一个坚持原创内容的前端技术社区媒体,推荐关注!

以下为演讲实录:

魏晓军: 接下来的分享内容是由我带来的关于HTML5框架下的优化实战,我今天讲的和上面他们讲的不太一样。我刚才看了一下今天的演讲主题,基本把HTML5所有 东西基本上都涵盖了,有用测试框架去检测HTML5性能问题的,接下来还会有HTML5速度环境的一些优化等。而我今天先讲一下携程在HTML5方面做了 哪些优化。

   一、HTML5概况


首 先讲一下这里HTML5说的就是HTML5,其实HTML5发展下来不仅仅是HTML,它包含一套有CSS和JavaScript在内的一套技术组合,传 统的HTML5里面有新的标签和新的元素的增加,CSS之间有一些动画等其他的方面,种种这些都是广泛的HTML5定义,不仅仅是狭义上理解的 HTML5。

HTML5发展趋势我们可以看到应用在游戏领域例如刚才魏子钧老师介绍的游戏方面的HTML5,还有大家常用的电商,每一家网 站都有自己的HTML5网页,还有OTA上面的携程、去哪儿等,都脱离不了HTML5。当然还有广告,微信里面用的最多推销都是HTML5页面,可见 HTML5是随处可见的。为什么HTML5发展这么好?有几个优点,最简单的优点就是跨平台,再有就是它的开发周期比较短,其实它优点还有很多,这里就不 再多说。


HTML5 还有一些载体,HTML5自身的优化再加上载体的优化才能达到完美的,所以上面我罗列了几个载体,最常见的大家用的最多的就是微信,我们在微信里面经常看 到一些网络推销页面,包括我们自己的一些公众号,以前都是HTML5页面。再有就是APP里面,APP里其实有多种模式,比如Native模式,我们经常 会看到APP里面一些广告页,或者变化比较频繁的页面都是HTML5做的,其中最简单的就是可以看到很多平台上都有扫一扫。再有就是浏览器,所以这些东西 都是它的载体,你光优化HTML5如果载体不变的话怎么优化都是有限的,包括最早接触的AE6,如果AE6不升级大家都去做AE6也是不行的。

   二、携程HTML5框架简介


接 下来说一下携程HTML5的使用框架,我们把它叫做Lizard,Lizard其实是蜥蜴的意思,把名字起名为Lizard就是希望我们的框架跨平 台,HTML5可以走,SEO可以用,Hybrid可以用,我们现在携程的HTML5框架对于开发人员来说只需要做代码,这就是我们名字的由来。

框 架内部其实走的是单页面的模式,我们自己基于业界一些开源的东西去组装成单元的架构,里面其实含有一些定制化的行为,包括性能采集,自定义化的UI,还有 第三方的合作,整体就构成了HTML5的框架。接下来我想讲我们在做这个框架的时候遇到什么问题,逐一的跟大家分享一下,知识点可能比较零乱,但是都是我 们实际的干货。

上 图是我画了一个框架图,其实里面还有很多东西我没画出来。最下面的一栏是我们支持的平台,也就是我刚才说的HTML5平台载体,SEO、还有我们自己的 APP,现在有安卓TV、微信、第三方APP等,比如合作的招商银行APP,里面嵌入我们的页面,都是基于Lizard来做的。

下面是 Lizard的一些载体,上面则是Lizard的一些功能。因为它是一个单页模式,所以它有自身的一套MVC机制,还有我们一些用户行为采集。我们是模块 化的思想,因为现在随着前端的发展,前端已经不是当年只做一些特效,更多的还是把后端的思想吸收过来,我们已经在做工程化的东西,所以说我们不能再像以前 一样都写到一块,一定要有一种思想做这件事情,所以我们都是按模块来划分。

再有就是因为我们这个HTML5框架会应用到我们的Native 上,所以我们采用了外部的一些工具库,里面最常用的是Router、模板引擎、RequireJS等等,还有我们的一套UI,其实每家公司都会有一些定制 化的UI,一般公司都会有自己一套框架,你好多东西都是定制化的。这就是一个简单的Lizard结构图,它只是个平台,它包含的内容、第三方引入,以及它 的一些方式。

三、Lizard使用场景


接下来看一下Lizard的场景,我只罗列了三个:中文站点、广告页、英文站点。除此之外我们还可以在APP里面看到的,只要跟HTML5有关的都可以看到Lizard的链接。

今天重点是讲优化,我罗列了一下优化点,比较多也比较简单。

单页面模式:我们大概是2013年的时候已经走了这个机制,单页模式有很多优势,但是它也有一些适用的场景,如果你只有一个页面去做单页模式是没必要的,但是对我们来说页面比较多,里面最少要做成五层,所以说用单页面模式是蛮合适的。

组件样式拆分: 一开始页面比较少的时候,我们会把所有框架都放在一个页面里面,样式都放进去了有个好处就是只用请求一次。这个样式表随着业务发展越来越多,组件也越来越 多,随着业务的发展它越来越大,最后达到40多K,我们只能去拆,拆的时候是将里面的组件用的样式都拆到自己的组件里面,实现按需加载,提高页面性能。

图片压缩上传: 我不知道大家用HTML5对图片有没有要求?因为携程是做旅游的,尤其是我们的攻略频道好多人都会去上传一些图片,有时候他用的相机比较好,拍出来的照片 很大,所以我们这块做了一些处理,我们用Canvas对图片进行压缩完以后再丢到服务器上面。后来我们发现随着图片增大我们的压缩率越好,大于2m的时候 压缩率低于90%,如果你们图片用的比较多的话,这一块也是一个很好的优化点。

模块解耦: 这个东西一开始起步都是一样的,大家都在一块做CSS,JS,各个频道聚集在一起写这个东西,然后写着写着出现好多集成,或者其它一些依赖就逐步增强了, 最后导致依赖关系变得很复杂,很少能把某一个单独拎出来。当这个问题出现时,只用了一个模块但是最终找出来十个模块,所以后续就进行了解耦,保证一个独立 的功能就只是一块。

静态资源拆分:一开始各个频道都在一台主机上,而且我们应该是.NET用的最多的公司,所以后续我们就把它分开了,大家如果前期做的话应该也会遇到这样的问题,我们现在所有的静态资源都放在静态服务器上,动态资源放在动态服务器上,所以说这其实也是一个小的优化点。

首屏显示: 这个应该是大家最关心的,最直接的东西就是首屏的内容。首屏出不来用户流失率也是蛮高的,所以大家都绞尽脑汁想这方面的东西。我们也有自己的想法,首先慢 其实也有两个方面的原因,一个是资源太大,一个是网络请求太慢。下图我标蓝色的就是现在我们事先会把一些DOM结构放在那儿,真正下载以后就把数据填进 去,这样用户看上去也是很好的,所以说我们就做了一个FakeData,第二块做ErrorData,当数据超时以后可以先用默认的数据填进去,即使这次 不行下次还可以点。其它大家也都可能用到,比如Core、UI拆分,再一个就是延迟加载功能,还有模板预编译,ShowView功能。这是我们首页上的一 些优化,当然看到也有负的。

性能数据采集: 这个可以结合刚才达峰老师他们的框架做一些新方向的测试,去支持你觉得需要做测试的哪一块,这个主要涉及到数据方面,也是模板方面,再一个就是一些文档流 方面的一些新数据。还有就是版本,比如说每个公司的框架不可能是一成不变的,你会去对比上一个版本和这一个版本同一个页面里面哪些性能有问题,不是说新版 本就是最好的,所以这方面我们要做集成的对比,只有对比才能发现问题。


页面数量处理机制: 由于我们是单页面的模式,只有一个页面是真实的,这会有一个问题,每个DOM节点越来越多,当达到两千多个以后还是蛮卡的。随便一个DOM颜色的修改,光 是修改颜色还好,如果修改别的会很卡。所以这一块要进行处理,页面节点不超过5个,让他指定哪些页面是需要保存的,再一个我们对清掉的页面也不是完全清 掉,可以放到文档切片里去,下次进来的时候只需要绑事件就好了。

数据缓存: 其实现在HTML5上面有一些新的特性我们要很好的利用。我们用的最多的还是localstorage,虽然它有一定的限制,但是可以浏览。现在几大公 司,阿里、百度,也会用localstorage做一些缓存,所有的东西都可以缓存下来,但是是有限的,当达到一定限度的时候有些就缓存不进去,所以还是 有选择性的缓存一些我们用的比较频繁的数据。数据类型是非实时的,比如城市信息和常用联系人,可以放到localstorage里面去,还会有一些限制 的,我们现在就是30-60秒会自动清一次。

减少数据返回:这个其实也是现在影响我们页面一个重要的 点,因为文档结构大就会导致DOM的时间长,所以尽可能减少数据返回。这一块主要做了这么几步,比如以前我们取城市的时候会把国际国内都取下来,但其实这 个用户是国内的,所以没必要取国际的。再一个就是返回必需数据,从这个页面到下个页面都要去拉一次,但是其实对于首页页面来说不需要,只需要拉到对应的数 据就可以了。

情感化组件迁移:这个应该大家都会用到,最常见的就是loading,这是从产品来说它是很漂亮的,但是从用户来说它是要费很大流量的,所以说为了解决这个问题我们想用canvas去绘图,可以看到左边是baseuw64,右边是canvas图片。


降低框架体量: 其实这个也是所有框架都会遇到的通病,因为业务线越多,而且你抽成公用化,所以导致框架体系越来越大。如果我自己做一套简单的框架可能十来K就好了,但是 集中酒店、旅游、机票、火车票的话框架就特别大,所以我们这块现在来说影响最大的就是框架体系太大了,现在我们大概80K。在这一块我们也是绞尽脑汁做 HTML5上的优化,所以说一定要拆,可以把解析配置项的拆出来,比如说单线面模式拆出来都可以。再一部分就是你定制化的UI,所以一定要把这些东西拆出 来。

利用浏览器并发:这个是某一次我发现我们在浏览器里面请求的时候,在这一段时间里面只有一个JS请 求,我们知道浏览器是有变化的,只要在带宽允许的情况下和2G网络下不同,所以说4G、wifi情况下只请求一个JS是很浪费的,这时候就把框架一些东西 拆成并发的,下面就是我们拆的一个并发的东西,在性能上得到很大的提高,这其实也是一个小的优化点。

框架功能拆分:看下面这个图,这是我们拆完的一个JS的资源,首先会有一个解析文件,会解析这个页面上配置项的文件,比如说WEB,因为拆掉以后带来的问题是请求太多,这时候我们用webresource.c-ctrip-com,后面就是把技术合在一块的。

异步加载非必要模块: 其实好多API是用不到的,所以这个东西必须埋点去发现,然后把它从里面删掉。再就是我们一些定位模块,我们定位因为既有国际又有国内,还有百度、谷歌之 分,乱七八糟加起来还是蛮大,所以第一次请求失败了再弹一个是无所谓的,但可能用户体验稍微差一点,所以这些东西我们必须要做到异步。

并行加载: 以前的逻辑是在bu首屏的数据取回来,然后dom节点展示完成之后,再去阻塞式的加载bu业务的controller,然后再绑定dom事件等等,这中间 两个异步的请求事件是串行的,导致时间 >= 两者之和; 优化后的逻辑是两个异步的请求同时加载,然后在处理业务时相互等待,在不影响原来业务处理顺序的前提下,总时间为两个异步之中,请求时间最长的一个。

适当使用服务端优势:虽然我们采用的是单页面模式,但是还是有一些缺点的,所以我们采取部分资源服务端输出,或者登录态放在服务端,以及数据聚合放在服务端。你一定要发挥各个多端优势,前端有前端的优势,服务端有服务端的优势,结合才能得到最优。

实现Lite版本: 因为你的框架不是适合所有的场景,比如营销和广告页面,可能就是一个页面,它在构造框架和页面时是挺复杂的,所以我们推出自己的Lite版本,它可以说是 一个工具加插件的方式,比如我们会把一些工具函数,一些定位模块都抽出来,以模块方式让它们加载,你在里面都可以不用模块就能加载模块,这样的话才能保证 这些营销页面的速度。如果单纯运行框架的话对于他们来说是蛮浪费的,所以我们最终拆出来的Lite版本才用了4K,压缩出来也才7K,这个做活动页面还是 蛮有意义的。

第三方库优化:由于我们是模块化思想,所以用到的其实更多的是JS,大家知道其它两个吗?alameda和almond,requirejs其实也蛮好用的,其实其它的东西都可以自己精简的,没必要去完全遵循它。

新技术引入:ReactJS.net、ReactJS、Webpack、Vue.js、AngularJS,我们是推出了ReactJS.net来做自己的东西,有些时候还是很有必要的,所以说我们要关注一些新技术。

加载余下内容▼

相关文章:

;