如何开发亿级DAUH5页面

以云看科技 2024-08-23 01:29:19

2022手Q春节活动主会场页面日PV过亿,活动期间覆盖用户总数更是达到数亿,多项数据刷新历史记录。

为了支持这个亿级DAU项目,项目前端团队从项目架构到页面性能,实施了各种常规和非常规的创新实践及优化,确保了用户体验的平稳顺滑。

下面就从整体技术方案、稳定性考虑及监控、性能调优、资源带宽优化、日志效率几个方面来说说前端团队所做的创新和优化。

1 整体技术方案1) 主会场的截屏效果

主会场是一个游戏化的单页应用。

上方星空是主要用户交互区,点击星星可以抽奖。

右侧按钮区是背包、碎片列表、小游戏、好友互动等二级页和子功能入口。

下方是小窝、小世界、王者荣耀、公益等分会场入口。

在项目初期,首先面临的问题是技术方案选型。

2) 前端页面的技术选型

主会场是整个活动的入口,是核心页面,主会场的技术选型是重中之重。

因为主会场是一个“游戏化”的页面,一开始我们考虑引入egret、cocos游戏引擎,把主会场当做一个H5小游戏来做。

我们使用egret游戏引擎做了较深入的技术调研,甚至架设好了项目Demo,但很快就意识到这个方案可能存在各种问题:

主会场内容无法一屏容纳,需要滚动,游戏引擎会很吃性能且较难优化即使用了游戏引擎,也还是要结合dom页面来配合完成所有功能游戏引擎代码复杂,代码量大在分发、加载等多个方面都更加耗损效率游戏引擎都使用webgl渲染,低端机特别容易出现黑屏花屏等需要更多时间精力来定位解决的问题主会场游戏化的交互比较轻,使用游戏引擎带来的“效益”并不明显

于是我们再次梳理了主会场的技术方案,并对使用游戏引擎方案和Dom方案做一更加细致的对比考虑。

从这个对比看,每一个维度都不支持我们引入厚重的游戏引擎,最终我们放弃了游戏引擎,决定使用Dom方案,动画引擎使用非常轻量的anime。

最终的实践确实证明,我们的选择是正确的。anime非常轻量,代码量仅17kb,性能也很好,hold住了所有的动画场景,完全满足产品设计对动画的需要。在满足产品需求的基础上,使项目尽可能简单化,本身也是简洁高效的体现!

关于anime,有需要了解的可以前往其官网:https://animejs.com/

主会场的技术方案确定后,其它页面的动画、复杂程度都比主会场轻的情况下,就可以统一参考主会场的方案来做了。

3) 前后端接入方案

日常业务,一般是走nodejs直出,异步数据走https请求。nodejs直出对于效率的优化意义,很大程度上得益于接口数据的请求是在node端实现的,但代价是需要部署额外的node服务器。

春节红包这样基于手Q客户端的大规模的活动,为了增强安全性和稳定性,数据请求我们考虑走客户端的sso加密通道。

这种情况下,node直出的优势得不到发挥,并且还要额外部署大量的node服务器。所以我们没有考虑使用node直出方案,而是直接从CDN加载静态代码文件和资源,然后接口通过客户端sso通道异步获取。

但是这样一来,首次加载页面的用户,在没有缓存的情况下,页面白屏时间可能会比较长,为了解决这个问题,我们与客户端紧密配合,使用了内置包 + 离线包方案。具体来说,就是把代码、资源等文件随客户端一起打包发布,当用户进入页面发起资源请求时,客户端会拦截用户请求并判断是否存在本地资源,如果存在就直接使用,不存在时才通过网络加载。

内置包 + 离线包的方案,极大提供了用户进入各个页面的速度,让页面达到了秒开的效果。

4) 整体动画方案

整体项目有大量的转场、轨迹、场景动画,我们的动画方案是animejs + apng + css。animejs本质也是css动画。

这个方案避开了canvas、webgl渲染等可能引起黑屏、花屏问题的前端特性,并且完全满足产品、设计的需要,即是稳定、高效的方案。

对于普通的位移、渐变、循环旋转等动画,简单写点css即可解决。

比如按钮扫光、窗口上浮,还有主会场的环型星空的自转、抽奖星星的自转等。用好css动画,本身就可以解决非常多的动画场景了。

对于一些较复杂的路径动画,比如摘星时星星的曲线运动轨迹,则通过anime控制。

比如下面这段代码就是实现星星的抛物线运动动画的代码:

而对于一些较复杂的场景动画,难以通过纯前端实现的,则通过优化后的apng来渲染。

背景中的繁星点点闪光、流星飞过、极光效果等属于此类动画。此类动画根据性能分级,部分机型不展示。

如有兴趣了解这些动画的最终效果,可以观看本文前面的录屏。

这些都是前端稳定实践了很多年的方案,使用起来没什么顾虑,最终的实践也证明了这样的实现是很稳定高效的。

5) 小游戏接入方案

项目设计包括了多个小游戏。所有小游戏都是是基于cocos creator制作的,游戏的开发、迭代都由各自的开发商负责。

我们采取的方案是让合作方提供的小游戏的单机版本,接入我们统一提供的SDK。开发商发版本时通过邮件把编译结果输出,我们把编译结果代码合入项目版本中发布。

统一游戏SDK提供了获取分数、开始游戏、关卡完成、提交分数、振动等接口,实现了结果页、排行榜等界面,并提供了标准化的文档。

统一SDK及相关文档的设计,确保了游戏接入的高效和标准化,为后续高效改造和添置各种功能、数据上报等提供了前提。

另外,所有的游戏都是基于cocos creator制作的,游戏引擎文件达到2M左右,我们要求各开发商使用一致的版本构建,游戏逻辑和引擎逻辑分享,这样就可以共用一个游戏引擎、物理引擎等,节省了引擎库版本,并把引擎相关的资源早早地合入了离线包、内嵌包,确保了引擎库加载的稳定高效。

2 稳定性及监控

项目整体的稳定是整体技术方案选型以及接口优化的效果,而接口优化需要完善的监控数据来提供指引。

常规的https请求方案链路长,从性能和安全性方面都难以承载这样大规模的请求量。所以页面的数据请求走的是客户端sso通道,而一些关键操作则由客户端提供了接口,前端只需要直接调用,比如抽奖、数据上报等。客户端直接执行的效率比页面处理要更好,这一点毫无疑问的。

对于端到端的接口监控,我们使用TAM提供的前端监控解决方案。关于日志上报后文还会有提及。

整体技术方案之前已有介绍,这里说说接口优化。

1) 接口监控

每一次演练结束后,我们都会从TAM捞取相关的质量数据来分析对比,来洞察性能优化的效果及存在的问题,为下一波优化提供数据支撑。

第二次演练后的质量数据分析(部分)

需要注意,我们页面所有的数据请求走的是手Q客户端的SSO通道,而TAM默认的API性能逻辑是不会侦察到这类接口请求的,需要自己实现API性能数据的上报:

2) 接口优化

经过前端、客户端、后台、测试紧密合作联调,我们排查或优化了如下这些场景:

① 降低数据请求频率

比如常规星星数的扣减由前端直接执行,取消不必要的数据更新策略而是通过更周密的逻辑保障数据一致。

② 聚合数据请求

接口在设计的时候就考虑少用,比如核心主会场,进入首页只会请求一个后台接口,把所有必要的数据都聚合到这个接口。另外,数据上报量较大,不是每次请求都即时上报,客户端有聚合上报的策略。

③ 精简单接口数据量

理论上,数据量越大越影响传输性能。每轮演练后都会梳理所有的数据项,检查可精减、可合并的数据,确保没有一项数据是多余的,以确保数据简洁高效。

④ 解决页面切后台时数据请求失败率高的问题

通过分析收集到的数据发现,页面在切后台时,sso数据请求的失败率较高。联合客户端定位后发现,这是sso的机制本身如此。

于是前端这里做了一个优化:页面切后台时不执行数据请求,而是监听页面切前台事件,等页面切回前台时再执行。因为页面切后台时对用户不可见,所以这个优化并不影响用户体验。

⑤ 推动客户端基础侧优化或解决其它sso链路问题

整个开发期间,遇到的sso链路问题,比如某段时间超时率较高,某些场景回包数据为空等,都能从收集到的反馈及上报的日志分析发现,并推动优化解决。

而这些问题能高效地发现、定位,得益于我们完善的日志上报体系及埋点。

最终,经过多轮调整优化,所有接口的端到端的耗时都小于500毫秒,除逻辑和数据量较重的首页接口外,耗时均小于300毫秒,接口端到端的成功率均在99.5%以上。

3 性能调优

春节红包这样大规模的活动,性能优化带来的效益是贯穿于整个链路的,从项目的维护成本降低、分发效率提升、用户体验提升、带宽流量降低等。

常规的性能优化措施,我们从项目的设计和开发阶段开始贯彻执行,比如:

常规图片使用之前尽可能压缩、合并、复用资源跨项目复用,比如字体、公用图片、项目公用库、vue、小游戏引擎等尽可能降低请求数量,特别是首屏请求数量逻辑、组件跨项目复用,比如抽奖浮层、上报SDK、游戏SDK等,都是独立且高度复用的模块

后期还针对性地做了多项专门的性能优化,比如:

1) 首屏优化

具体措施有,对于不必要首屏加载的资源,先隔离出去,后续按需加载;进一步梳理压缩资源,加快请求速度;全部资源确保走离线包加载;接口请求数据量经过多轮压缩合并,同时优化请求速度。经过一系列优化,最终使用首屏渲染性能达到1秒左右。

经过n轮演练、优化,最终,大部分页面的首屏性能都实现了秒开的目标。

下图是第5轮演练总结时的页面性能数据,此时离线包资源还未全面铺开。后面离线包资源铺开后,页面性能进一步提升。

2) 资源预加载

针对某些场景,打开后会出现资源加载慢、图片切换瞬间视觉跳变等问题,进行必要的预加载处理。

3) 小游戏专项优化

小游戏合作模式是外包提供的单机版本,接入我们统一提供的SDK。

所有小游戏都是基于cocos creator制作的,除了SDK、引擎复用,还指导开发商进行了资源的压缩、合并、复用等。

从包大小看,单个游戏包大小最终都控制在3M以内,包大小优化到只占首次提供版本的30%左右,优化效果还是相当明显的。

另外在加载速度、体验顺滑性等方面,也针对不同游戏进行了区别调整,比如优先显示背景图减少白屏机率、定制更加精确的加载进度条、减少游戏开始前的资源加载量、把声音加载放在游戏开始后等,进一步提升了用户体验,提高了用户留存率。

经过多轮优化,所有游戏的5秒进入率达到50%以上

4) 主会场分级特效体验

在所有可能的优化措施都做了之后,还是会有部分低端机会出现卡顿的情况,而在春节红包这种数亿级用户参与量的活动中,低端机的绝对数量不可忽视。为了确保核心体验,对低端机型做一些特效减配是非常有必要的。

经过分析定位,卡顿的原因指向了场景特效过多,于是我们打算对所有机型分为全开性能、中等性能、较低性能三个级别,按照性能级别从高往低减配特效展示。

首先面临的问题是机型的配置及分布,借助天璇巨量的页面访问,我们在天璇页面中下发了上报机型配置到TAM系统的逻辑,很快就收集到了近10万条机型配置的数据。通过对这10万条数据进行分析,并结合测试同事提供的少量机型实测数据,我们按平台给出了如下分级策略:

iOS的跑分数据来源:https://www.antutu.com/ranking/ios.htm

Android机型的分级与最初设想的不太一样。最初是想根据CPU核数和内存大小进行分级,但最终发现CPU核数和机器的实际性能没有相关性,一个8核的CPU性能可能比4核的还是差,这和CPU的品牌、架构有关、单核性能等有关,所以最终我们分级时忽略了CPU数量这个参数。

对于iOS的分级比较比较明确。虽然不可能实际跑分,但只要知道机型,根据整理出的机型跑分数据表对照一下,就知道了其跑分数据,进而就能确定其性能分级。最终逻辑,就是根据机型来确定其级别了,如下图:

确定机型分级后,就可以根据机型等级来减配特效了:

这个特效分级是经过开发、测试们反复调整、验证的结果

按照这个特效分级,50%的用户能获得最高的特效体验,30%的中等特效用户只是减配了一些渲染区域较大的流光背景、极光等大块且不太明显的特效区域,而最低配的20%的用户,也不是完全没有特效,一些关键的环节比如摘星、抽奖过程等还是保留了动画的。

这样一来,整体体验有了较大的提升,从测试团队的实践及外部演练用户的反馈看,关于卡顿的反馈数量趋于消失,说明特效分级优化的效果还是很明显的。

4 资源带宽优化

DAU过亿的活动,入口页面峰值访问量10W+每秒,而入口页面的资源量约30+个,算起来资源请求峰值超过300W每秒。

这样量级的资源请求,如果资源带宽优化不好,随时有可能崩溃。

前面有提到,我们的前后端接入方案,资源是走CDN加载的。但是如果全部资源请求都走CDN,显然会给CDN服务器带来极大的压力,不利于保障活动平稳运营,并且可能给其它活动带来阻塞压力。

1) 内置包 + 离线包方案

结合本次活动的特殊性,我们和客户端推出了内置包 + 离线包方案。具体来说,就是把代码、资源等文件随客户端一起打包发布,当用户进入页面发起资源请求时,客户端会拦截用户请求并判断是否存在本地资源,如果存在就直接使用,不存在时才通过网络加载。

内置包 + 离线包方案的大致流程

实践证明,内置包 + 离线包方案在活动期间发挥了巨大的作用,80%以上的资源请求直接被客户端拦截并使用本地资源回包,极大缓解了CDN服务器的压力,同时提高了用户端的加载速度。

本地资源的命中率统计,部分达到100%

内置包 + 离线包的方案,大大降低了活动高峰期资源的请求量,也就是降低了带宽和流量,保障了活动平稳度过高峰期,同时还降低了成本,是“一箭多雕”的方案。

2) 常规页面优化

常规页面优化的详细做法,有两个方面。一是在不降低设计效果和用户体验的情况下,极尽可能地压缩资源,以减小资源大小,二是通过合并资源、提高资源复用率来减少资源数量。

这些措施的具体做法,其实和性能调优是大体一致的,这里不再细述。

5 日志效率1) 日志的价值

日志是定位、解决问题的主要线索,特别是在项目前期,用户反馈往往只知道一个用户ID,如果用户的关键操作、数据都没有,定位问题就很抓瞎。甚至有些问题只限于特定场景出现,开发侧不可复现,此时日志的重要性不言而喻。

所以日志上报在项目初期要尽可能全面、详细,在项目稳定后可以逐步精简,直至最后为了优化性能可以停止上报。日志的收集和上报在前期就要考虑到这些要素,上报接口要收敛,以方便扩展、维护、精简等。

另外,日志上报需要注意保护用户隐私,不要上报cookie、用户个人信息等隐私数据。

2) 日志上报工具

日志收集我们是使用TAM来实现的。TAM提供了包括页面性能、异常分析、静态资源、API监控、自定义事件等维度的质量监控,并且可以实现异常告警,完善且高效。

TAM的外部公有云版本:https://console.cloud.tencent.com/rum。

除了常规的页面质量监控,TAM还支持了强大的自定义数据上报,比如日志上报、自定义事件、自定义测速等。

3) 接口回包全量上报

前期,我们把用户的关键操作日志及有利于复现问题场景的关键数据进行了上报,TAM支持实时查询,这对于我们定位问题非常有利,基本上只需要知道用户的QQ号就能查询到当时用户的大致状态,进而找到问题的根源。如果有必要,再配合客户端的日志进一步分析,基本都能得出结论,大大降低了甩锅情况的出现,提高了问题定位的效率和精准性。

4) 自定义事件上报

另一个数据收集的例子,是利用TAM的自定义事件上报,来评估游戏页面加载的阶段进入率。自定义事件支持ext扩展参数,通过在页面加载的不同阶段上报一个pv事件,指定不同的ext参数,即可实现。上报代码及效果如下:

TAM的质量监控及日志上报能力在演练期间为项目优化迭代提供了强大的支持,但在版本稳定后,TAM监控及上报已经没有太大必要了,为了进一步降低请求量,提高性能,我们最终在封版前移除了TAM的上报功能。

从技术角度看,亿级DAU H5页面的秘密在于,除了恰当的技术方案选型及设计外,还需要前端极致的性能调优;在资源加载方面,还需要和客户端内嵌包及离线包机制的紧密合作;在接口稳定性方面,还需要和后台充分合作;出现问题需要能够及时发现并高效解决。这是整个团队众志成城、精益求精的结果。

作者:jamesgan

来源-微信公众号:腾讯VATeam

出处:https://mp.weixin.qq.com/s/a7gV1t9BbKiC_RQh8FInjA

0 阅读:0

以云看科技

简介:感谢大家的关注