本文来自飞猪前端工程师@太吾同学,今年飞猪双十一会场前端性能的优化负责PM,来一起看看从 Weex 到 Web 我们的性能优化实践。
一、前言
没有最快,只有更快!在前端开发领域,性能是一个永恒的话题。它不仅仅代表着给予用户的体验,甚至直接会影响到业务的效果,业界共识的说法:页面加载时长每增加 1 秒,用户流失 10%。反过来说性能每快一点,就会带来更多的用户,使业务 GMV 提升,想一想今年双十一 4982 亿的销售额背后有我一份功劳时,心里还有点小激动呢,嘿嘿 但是飞猪今年双十一和去年双十一,会场部分最大的区别就是从 Rax0.6 on Weex 到 Rax1.0 on Web。今年上半年启动导购域“端渲染”升级,前端渲染引擎回归到 WebView,初步的结论是在强网和离线的情况下加载体感方面相差无几,但从数据上看 Web 首屏性能数据略差一点。但大家都知道,在 Web 上,已经很久没有页面实践,需要重新探索优化方向
今年双 11,前端在性能方面的目标就是体感上要超过 Weex,数据上也要争取超过 Weex
面临的挑战
为 Follow 集团主推方案,使用 Rax1.0 统一 DSL,一码多端支持 H5、小程序和未来的 Flutter,飞猪从 618 大促开始,就将会场渲染侧全量切换到 Rax 1.0 Web 渲染,当时对于性能方面的优先级不是那么高。 之后,性能优化专项重启,开始着手进行 Web 方面的优化研究,力争提升双 11 的用户体验。双 11 总项目组对性能方面提出一个近乎苛刻的目标:比日常会场性能提高 25% 面对这个目标,传统意义的前端方面优化已经不足以支撑,于是我们联合客户端、服务端以及其他 BU 同学,进行了一场协同战役
二、优化手段
既然要达到这个目标,传统的优化手段已经不足以支撑带来如此巨大的提升,并且一些基本该优化的地方已经被层层框架给做完了,于是需要另辟蹊径。整体梳理页面加载流程,在现有优化手段下,落地更多增进手段。
与客户端合作(预渲染、离线包、Data-Prefetch...)、重启 SSR 方案。同时在兼顾数据的同时,也需要同时兼顾用户的体感,做了两种 Snapshot 的方案(Mtop 缓存、Html 缓存),最后保障页面间跳转顺滑完成 SPA 方案。
下图展示了所有会场所使用的优化手段
图 3.1 所有会场所使用的优化手段
- **主会场:**为了保证主会场的最佳体验,使用客户端提供的终极大招 - 预渲染;
- 榜单会场、超级宝贝、酒店会场、机票会场、万券齐发:对于首屏没有异步模块的场景,使用 SSR 配合 Data-Prefetch,极致提升用户可见页面时间;
- 全部会场:因为模块基本没有变化,全部会场使用 HTML 缓存类型的 Snapshot 方案,用户可以更快浏览该页面;
- 超级宝贝、榜单会场、我的双 11:针对底部重要会场,采用 Mtop 接口缓存类型的 Snapshot 方案,提升用户浏览体验;
- 所有会场均通过统一渲染页推送离线包和 Data-Prefetch;
- 为同时保证分会场分别运营和页面之间切换的流畅性,底部 Tab 五页面之间使用类SPA 方案,使页面切换起来无缝衔接。
可以说为了追求用户的体验,从速度到体感都做了全方位的考虑,性能优化从来就不是技术的狂欢,是可以真正给业务带来价值的事情
** 下面简单介绍一下本次双十一会场主要使用的优化手段。
一)端侧预渲染
如果不考虑可能带来的 Crash 风险,这应该是提升最大的方案了
在双十一这种大促的场景下,通过端控制开关,将下发的配置 URL 以“离屏”的方式初始化好容器并 loadUrl,在上屏之前完成页面的 Rasterization(栅格化)。当用户点击页面入口时,客户端会直接将准备好的 Webview 推到前台直接展示,形成几乎无感的打开效果
效果对比
开启预渲染 | 未开启预渲染 |
---|---|
方案流程图
在客户端通过配置下发的方式初始化 WebView,并通过内存管控保证 APP 的稳定性,同时在展示逻辑上和前端配合,保证数据的一致性,最终通过释放后续的一系列处理管理多次访问的情况。
二)SSR(Server-side render or Serverless-side render )
披荆斩棘的战士,带着荣光归来
中文名:服务端渲染,顾名思义也就是将渲染的工作放在服务端进行,这种方式很早就存在,早在 Ajax 出现之前全部都是这种方式,由服务端返回给浏览器完整的 Html 内容,但传统 BFF 架构的到来,使得这种方式逐渐慢慢消失,但借着 Serverless 大潮的到来,当 Faas 遇上 SSR,迸发出的火花却让人着迷 今年 3 月份,狼叔的一篇分享《前端新思路:组件即函数和 Serverless SSR 实践》中重新将 SSR 做了概念上的升级,从传统意义上的Server-side render 升级为 Serverless side render,基于 FaaS 环境,提供端侧页面渲染能力 但这条路也充满了挑战,从 8 月底开始了解淘系要搭建业务的 SSR 之后,飞猪侧 9 月开始跟进方案,原本计划国庆会场投入试点,因为种种原因,仅上线不到一天就被下线。但项目组最终还是顶住压力,在双十一的五个重点会场(榜单会场、超级宝贝、万券齐发、酒店会场、机票会场)使用 SSR,并有着非常优异的效果
效果对比
SSR 代表首屏即可视,相比 CSR 减少模块加载以及页面渲染,将可视时间大幅提前。
开启 SSR | 未开启 SSR |
---|---|
方案流程图
整体方案保证性能优势以及改造成本小的前提,采取异步 SSR 方案,即将 HTML 放在接口中返回,在规避高低端机容器影响的同时,又可同时复用客户端的离线以及数据预加载能力,还保证 CSR 到 SSR 的平滑切换。
对 SSR 方案刚兴趣的小伙伴可以看看《飞猪营销域 SSR 总结 - 双十一会场再加速》
三)SnapShot(页面快照)
将用户体感页面可见时间继续提前
原本设计 SnapShot 是在非千人千面的场景下,多次访问可以更快的可见页面,将上一次访问的 HTML 直接缓存在本地,下一次进入页面时,首先展示缓存的页面,但后来发现在会场这种每天基本都会变阵的场景下,模块的删减以及顺序的调整,都会使得在缓存页面到真实页面展示的过程中发生不可避免的闪动,而这种闪动是有点无法接受的,于是项目组重新设计出 Mtop 接口缓存的方式,配合模块缓存,基本上可以实现与之前同样的效果并且避免了页面闪动的问题 同时项目组发现 HTML 缓存的方式也并非毫无用武之地,双十一会场上线前,针对所有会场进行 Review 优化手段,发现在全部会场这个场景下,会场基本无变化,使用 HTML 缓存的方式简直再合适不过,于是我们将使用 Snapshot 的页面分为两类,适合的才是最好的,达到所有页面都可以尽可能快且没有展示问题地呈现给用户
效果对比
开启 Snapshot 后,整体页面无 Loading,基本达到页面的直出效果。
开启 Snapshot | 未开启 Snapshot |
---|---|
四)SPA
完成用户体感的“最后一公里”,多页面间跳转实现无感知
各分会场需要进行分别运营,目前的搭建体系又不支持单页面拆分运营,通过底部 Tab 包框将多页面假装聚合成一个页面,但页面之间的跳转造成的切换割裂体感是一直被人所诟病的,本次改造升级完成了类 SPA 的方案,将 Tab 中的页面数据请求后,直接渲染成真实的 Dom,切换通过 Display 的方式,基本在高端机上实现了将多页面聚合成单页面,多页面间跳转无感知,给予用户最好的体验
效果对比
从多页面之前的 replace 操作,页面跳转中出现白屏,到目前页面中 DOM 的替换,用户体感大幅提升,也取消了用户点击 Tab 却跳页面割裂的感觉。
开启 SPA | 未开启 SPA |
---|---|
方案流程图
搭建页面框架共用一套渲染引擎,且每个页面的所有模块通过 Fetch 获取,每个模块独立发布,且支持模块拆 combo 后单独缓存,非常适合 SPA 方案。同时项目组针对高低端机做了不同处理,在高端机上请求单 Tab 数据完成后,预加载其他几个 Tab 数据,切换时直接取用,提供更好的体验。
五)资源&数据预缓存
最快的请求是不发请求
利用飞猪端侧的 Fcache/DataPrefetch 机制,结合飞猪端总控配置下发通道,将页面内使用的静态资源主动下发到客户端进行缓存,使用户访问页面时无需请求静态资源,此外在页面发起跳转时在端侧提前触发页面的 MTOP 数据请求,减少接口请求等待时间。
Fcache 方案 (资源缓存)
会场的离线方案采用 url+package 的方式,在配置后台录入 url 后,后台通过 puppeteer 去跑这个 URL,把请求的资源缓存下来,其中还包括一些滚屏操作,把懒加载的资源也抓下来,最后通过通过读配置去匹配资源缓存。
DataPrefetch 方案 (数据预加载)
数据预加载拥有三个状态:Memory、Ongoing、Miss。我们认为将请求放在客户端发出一定会减少真实的请求时间,所以即使真实请求发出时,客户端还未完成请求,只要 key 匹配,会等待客户端数据,而不是重新进行一次请求发送。
三、监控&诊断
优化手段之余,也需要对会场页面的性能趋势进行持续的监控,对于异常 Case 进行排查,为此,项目组开发了实时的性能稳定性实时大盘(图 3.4.1)、双 11 会场小时级性能大盘平台(图 3.4.2)、耗时异常长的慢会话跟踪小工具(图 3.4.3)。
图 3.4.1
图 3.4.2
图 3.4.3
四、成果
飞猪端内双 11 所有会场首屏可见时间达成既定目标,较日常会场首屏耗时环比降低 25%,较 618 以及国庆会场首屏耗时环比降低 20%。
图 5.1 双十一分组整体性能耗时趋势图
命中 SSR 的情况下首屏可见时间更是被拉入 1s 内,开启 SSR 的会场在使用 Web 后也可以重提秒开率,在业务频繁变阵影响首屏模块的基础上,达到周整体秒开率 60%以上,机票会场秒开率 75% 以上。
五、技术规划
本次技术上有着很多新尝试和迭代升级,在经过双 11 的磨练之后,需要朝着更加易用和通用的方向发展,主要分为以下几个部分:
1、SSR 方案优化
SSR 在端内提供了巨大提升,首先需要完善同步方案,实现端外场景的提升。其次,在现有基础上增加 AbTest,来支持更有说服力的业务效果对比;最后优化 SSR 在服务端的执行速度以及弹性扩容能力。
2、客户端优化
接下来会尝试多 Webview 的 Tab 切换,接入 PHA 方案。并将更多的唤端情况列入优化方向,如冷启动场景的专项优化。
3、配套设施
优化的背后离不开配套设施的支持,在现有基础上支持卡口、巡检、监控等功能,实现性能问题及时治理。
六、总结
作为一位前端开发工程师,担任双 11 会场性能 PM,特别是对于今年从 Weex 到 Web,性能水位重新被拉高,是挑战也是机会。 在保障业务不受影响的情况下,确保用户打开会场可以得到极致体验。从页面各阶段的耗时分析,到借助兄弟团队能力,整个过程步步为营,最终支撑双 11 会场圆满结束。在整个过程中,通过应用大量的优化手段和创新方案,提高用户的秒开率来侧面帮助业务转化提升;将预渲染、SSR 逐渐落入更多场景,为之后的全面性能提升做铺垫;联合客户端、服务端,打破前端能力和边界,进而探索性能深水区;提升性能数据提升的同时,兼顾性能数据监控,实时把控异常情况。 最后,为明年双 11 立个 Flag:明年不再需要性能保障,而是在页面生产出来的时候,就是满足性能标准的!