淘宝和天猫首页都用到了哪些技巧或者技术?

2,530 阅读13分钟
原文链接: www.zhihu.com
作为天猫首页的负责人薛定谔,我也只好解剖一把天猫首页,让大家看看它的骨肉血皮到底是怎个模样。人格担保虽然有撸文狂魔小胡子哥珠玉在前,但本文绝对有不一样的地方哟~ 比如……如何快速响应需求,解放生产力。 比如……移动端首页和WeeX首页的优化经验… 显示全部
作为天猫首页的负责人薛定谔,我也只好解剖一把天猫首页,让大家看看它的骨肉血皮到底是怎个模样。人格担保虽然有撸文狂魔小胡子哥珠玉在前,但本文绝对有不一样的地方哟~
比如……如何快速响应需求,解放生产力。
比如……移动端首页和WeeX首页的优化经验。
比如……广告,天猫前端团队正在诚意招资深前端开发工程师(社招),简历请发到yueyuan.cx@alibaba-inc.com


《PC与无线齐飞,Web共Native一色——天猫首页全解密》
从14年实习开始参与PC首页的开发,到15年正式入职同时负责无线端的首页,至今已经两年的时间。期间历经了6次改版、php到Node端的迁移、ReactNative的尝试、无线端性能优化、进入ES6时代、WeeX的尝试等等,不一而足,感触颇多,与大家分享。

也是一篇难得的长文,先放提纲。
一、天猫首页的定位
二、天猫首页的技术架构变迁史
1. 从PHP到Node的蜕变
2. 从静到动,从PC到移动端的飞跃
3. 光影融合,Web与客户端的交汇
三、疾如风——天猫首页的性能优化
四、侵略如火——大胆的Native化尝试
1. ReactNative的初登场
2. WeeX的回归
五、不动如山——天猫首页的稳定性保障
六、小结

一、天猫首页的定位
在了解天猫首页的技术架构之前,先让我们问自己一个问题:首页到底是什么?是用户关于这个网站的第一印象吗?还是所有业务的起始点?
简而言之,天猫首页有着以下三个特点:
  1. 面向最广大消费者的标杆与门面。
  2. 流量的入口与中转站。
  3. 轻耦合,新技术的试验田。

作为天猫的门面,往往决定了消费者对于天猫的第一印象,所以天猫首页一直在性能优化上有着孜孜不倦的追求,优化加载性能、交互体验、减少流量消耗、Native等多种方式给于消费者更好的体验。

作为流量的中转站,首页赋予了运营非常多灵活机动的能力,例如节日氛围的营造、机动区块的变化能力,并且全面铺开个性化,能够基于人群、地区推荐更加适合用户的商品,导流效率遥遥领先于其他页面。

作为新技术试验田,天猫首页一直处于开放的态度,敢打敢冲,率先尝鲜新技术并落地:2014年9月份率先从PHP迁移到Node、天猫内第一个尝试ReactNative、第一个进入ES6时代、第一个落地WeeX的重要业务。在这一过程中,天猫首页往往会克服非常多先行者的困难,并反哺新技术的优化与成熟。

二、天猫首页的技术架构变迁史
天猫首页的技术架构变迁,主要是基于两个部分:内部搭建系统&模板渲染系统的变更、业务重点的变更。

1. 从PHP到Node的蜕变


在PHP时代,主要存在以下问题:
  • 老旧的服务端实时渲染架构。渲染性能差、服务集群庞大使得文件同步生效慢。
  • 旧搭建系统规范使得效率低。需要手动在php文件中挖出供运营填写数据的位置,该数据位难以定义其他校验规范。
  • php文件和css/js文件不属于同一套部署系统,需要手动控制顺序,先发布新版本css/js文件到cdn,再发布php文件更新引用css/js文件的版本,容易出现发布手误。

在Node时代,上述问题都得到了解决,在首页完成迁移Node的尝试后,我们拥有了新的内部搭建系统斑马和模板渲染系统Wormhole:
  • 在使用『Cache集群缓存渲染好的HTML』这一架构后,性能、抗压能力、可扩展性都有了极大的提升(关于这一点详细可以看 @Barret李靖 的回答)。
  • 接入schema规范系统,建立数据位置的代码不再与前端代码杂糅在一起。
  • 隔离职能。HTML模板代码专注于渲染,不再处理其他事情。
  • 部署系统统一。不再出现需要关注文件发布顺序、手动升级版本的情况。

关于Node应用的更多信息,可以:关注前天猫Node负责人 @死马 的回答Node.js 在双十一中有哪些应用,表现如何? - 死马的回答以及现天猫Node负责人 @ngot 的回答如何看待天猫彻底抛弃PHP? - ngot 的回答

2. 从静到动,从PC到移动的转身
从2014年开始,天猫开始集体转型,迎接移动端时代的来临,直到2015年双十一,移动端成交占比已达到68%。
无线时代有甜也有苦:
  • 不需要纠结坑爹的IE兼容性,但是老版本的安卓兼容起来更加痛苦
  • 因为安卓的碎片化,响应式也是需要考虑的重要问题
  • 高清化的处理方案
  • 部分方案需要优化如iconfont,因为可能会发送多个请求,影响性能
  • 糟糕的网络环境、机器性能、系统特性对于性能有着更加极致的需求

因为移动端和PC端用户的使用习惯差距较大,同时考虑后续维护的方便性,移动端的天猫首页的UI设计上并未使用传统概念上的响应式(PC和移动端一套代码),而是与天猫客户端保持一致。
这一前提使得移动端Web首页可以和客户端共用接口,共享同一份数据来源,避免运营填写多份数据,节省运营成本,又因为移动端大量个性化推荐的需求,千人千面的展现方式,所以移动端Web首页采用了异步渲染的方案——页面进入只载入框架,再调用接口获取数据和模板,在浏览器端进行渲染。
这样做也有诸多好处:客户端中访问可以使用离线包、更少的流量消耗、更细粒度的ABTest、对接其他数据源更方便等等。
同时还实现了一套可以快速满足区块调整需求动态化布局方案,完美地支持了多次需求变更而无需前端代码发布,详细可见发表在天猫前端团队博客的这篇文章,让需求来得再猛烈些——快速响应需求的天猫H5首页新架构 · Issue #35 · tmallfe/tmallfe.github.io · GitHub

3. 光影融合,Web和客户端的交汇
相比起客户端业务迭代的成本、体积和发版劣势,Web的低成本、迭代快、跨平台的特性,使得绝大多数客户端的业务都会选择嵌入Web的方式。而客户端的黏性,使得这个Web页面相当大一部分的流量都来源于客户端。
那么一个新的问题来了:『客户端中的Web页面如何利用客户端的能力?是不是可以将Web和客户端进行融合,获取更好的体验?』
最初尝试了几个方案:
  • Hybrid API。
  • 跳转部分高频页面根据Url规则拦截到Native页(如商品详情页)。
  • 复用客户端建立的网络链路
  • 离线包等等
都取得了一定的效果,但是还需要一套更加完整彻底的方案。所以在2015年7月React Native如火如荼的时候,天猫首页立刻开启了尝试的项目,相关内容后文详述。

三、疾如风——天猫首页性能优化
性能一直是首页所需要关注的要点,希望能给用户更好的体验。

首先明确一点,有很多优化不是单纯的前端团队能够完成的,有CDN团队和服务端团队的支持,让前端同学感觉像生活在极乐天国。《高性能网站建设指南》这本书里提到的方法都比较基础了,在此略过。
除此之外,我们还做了以下对于性能有着显著影响的事情:
  1. css/js文件combo。我们的CDN和前端Loader支持实时url的combo,可以实现按需加载。如果CDN没这个条件,也可以使用webpack等前端工具进行合并打包。
  2. 懒加载。优先渲染首屏内容,其余模块资源延后或者用户有交互的时候加载。
  3. Webp图片格式。对比这两张图,可以发现Webp格式的图小得多,WebP格式的图:https://img.alicdn.com/tps/TB1labeKXXXXXaaapXXXXXXXXXX-1130-500.jpg_.webp;jpg格式的图:https://img.alicdn.com/tps/TB1labeKXXXXXaaapXXXXXXXXXX-1130-500.jpg。感谢(图片存储系统的同学)。
  4. 裁剪合适尺寸的图片。如果某一张图片运营投放的尺寸过大,可以根据实际的尺寸,加上后缀截取,如『https://img.alicdn.com/tps/TB1labeKXXXXXaaapXXXXXXXXXX-1130-500.jpg_100x100.jpg』。
  5. 拍扁所有请求。每个模块渲染所需要的请求不能是两个请求串行。
  6. 数据请求支持自由合并。(感谢服务端同学)
  7. 前端首屏只请求后端一个请求,由后端做对接其他系统的并行请求。
  8. 利用动态化布局保证模块之间的高复用
  9. 图片域名收敛。因为CDN支持SPDY协议,所以收敛域名可以有效节省DNS解析时间。
  10. 天猫前端组件规范整体升级,移动端去KISSY,变得更加轻量,减少流量消耗。
  11. 离线包。如果页面是纯异步渲染,可以考虑在客户端中设置离线包。只有当用户处于wifi且网络空闲时,客户端才会去下载离线包,二次访问效果拔群。

再让我用一张图说明页面渲染各个阶段可以做的优化。

除了加载性能外,还需要考虑交互性能,例如页面滚动时的帧率。
除了用requestAnimationFrame来将模块渲染切片,避免UI线程阻塞。如果页面的hover和mouseenter效果过多,还可以在用户滚动时,设置全局的pointer-event:none,避免在滚动的时候触发大量hover效果,实测效果拔群。

四、侵略如火——大胆的Native化尝试
相比起Web而言,APP有着更好的体验;但相比APP,Web的开发效率和发版优势毋庸置疑,如何融合两者,一直是前端的重要探索方向之一。

1. ReactNative的初登场
2015年7月,天猫首页立刻进行了ReactNative的尝试。
但在尝试过程中遇到了非常多的问题,满满的坑和血泪:
  • 一方面是ReactNative彼时并不完善,调试体验非常糟糕,莫名其妙红屏不知原因,还有升级0.8.0后会顺手升级iojs为3.x,和2.x的iojs并不兼容。
  • 另一方面是当时考虑并不完备。工程化落地一个技术需要考虑的因素非常多:多版本降级&兼容方案、开发调试工具、环境一致性、埋点、测试、监控、后续维护成本等等,需要考虑一系列的方案。
因为没有拿到数据和结果,并且没有足够的人力维护多一个版本的页面时,RN版的首页选择了停止维护。
但是ReactNative在天猫和双十一还有大范围的应用,详细可以看《天猫双11前端分享系列(三):浅谈 React Native与双11》天猫双11前端分享系列(三):浅谈 React Native与双11 · Issue #27 · tmallfe/tmallfe.github.io · GitHub

2. WeeX的回归
正如灰太狼被打飞时常说的一句话——『我还会回来的』,在手淘团队推出了一套新的Native化方案WeeX以后,天猫首页又死性不改蠢蠢欲动地进行了尝试。
这一次考虑较为全面,上述RN落地时没考虑的方案都有一定的考虑和解决,例如自动构建Web版本以降低维护成本、多Weex版本的降级方案、Cache集群部署Detector自动识别请求是否支持WeeX并返回对应内容。实际体验优于Web,从业务数据上来看也取得了较好的结果。


感兴趣的同学可以使用iOS手机淘宝客户端5.7.0以上版本扫码下述图片体验。
https://img.alicdn.com/tps/TB1GAYMKXXXXXcTaXXXXXXXXXXX-260-260.png

Weex页面非常精简,gzip后首页JSBundle的大小大概是13K,是Web的十五分之一。

WeeX即将开源,敬请期待。

五、不动如山——天猫首页的稳定性与保障
大概是心有灵犀吧,天猫首页和淘宝首页也采用了非常类似的容灾和监控机制,有小胡子哥的详述,我在此就一笔带过。

1.在容灾方面:
  • 如果接口请求失败,会依次加载本地缓存、访问CDN的备份文件等。
  • 对于运营填写的数据内容质量,投放系统配置了详细的校验,如最大字数等等。

2. 在监控方面:
  • 全量监控的埋点方案。能够全网统计到各个模块的运行状况和接口调用的健康情况。
  • 客户端层面的监控方案。能够拿到更多Web运行时无法自己拿到的信息,如当前页面某一链接404。
  • 业务监控的方案。能够保障页面的业务内容一定是符合预期的。因为首页的数据来源相当多,一个页面对应几十个运营,对于数据内容的质量是一定要保障的。

六、小结
接下来天猫首页还会做的事情大概有:
  • 赋能运营。接入个性化合图系统,免去了运营找设计师做图的成本等等;
  • 国际化。为了方便弱网地区用户的访问,对于性能有更高的要求,对于设计、素材也有更高的要求。

提笔匆忙,感觉虎头蛇尾,还请见谅。
如果有不明白的地方欢迎指出,欢迎和我一起来完善这篇文章哈哈。


最后,天猫前端团队正在诚意招资深前端开发工程师,简历请发到yueyuan.cx@alibaba-inc.com

P. S. 再吐个槽,一年多以前我问了你见过哪些前端性能优化方面做得好的网站? - 前端开发、以及移动端和PC端在html,CSS,js等技术实现的细节上,有哪些不一样的地方? - 前端开发,结果今天来答了这个问题,真是一种循环。