首页 >要闻 > > 正文

H5开屏从龟速到闪电,企微是如何做到的

2022-12-19 22:33:02


(资料图片)

导读|H5开屏龟速常是令开发者头疼的问题。腾讯企业微信团队对该现象进行分析优化,最终H5开屏耗时130ms,达到秒开效果!企微前端开发工程师陈智仁将分享可用可扩展的Hybird H5秒开方案。该团队使用离线包解决了资源请求耗时的问题,在这个基础上通过耗时分析找到瓶颈环节,进一步采用“预热”进行优化提速以解决了WebView初始化、数据预拉取、js执行(app初始化)耗时的问题。希望这些通用方法对你有帮助。

背景

服务端渲染(SSR)是Web主流的性能优化手段。SSR直出相比传统的SPA应用加载渲染规避了首屏拉取数据和资源请求的网络往返耗时。团队针对Web开发也已经支持了SSR能力。近期出于动态化运营的考虑,我们选择了Web开发,同时我们也接到了提升体验的诉求。以企业微信要开发的页面为例:采用SSR方案,从用户点击到首屏渲染的耗时均值约600ms,白屏时间的存在是可以感知到的。为了尽可能消除白屏达到秒开效果,我们尝试做更多探索。方案思路1) 方案选型如何实现页面秒开呢?从最直观的渲染链路来入手分析。下图列出了从用户点击到看到首屏渲染可交互,一个SPA应用主要环节的加载流程。我们调研了业内相关方案,从渲染链路的视角来看下常见方案的优化思路。传统离线包在加载渲染过程中,网络IO是很明显的一个耗时瓶颈。传统的离线包方案思路很直接,如果网络耗时那就将资源离线,很好地解决了资源请求的耗时。用Service Worker也能达到离线包的效果,同时也是Web标准。首次渲染优化一般需要结合客户端配置预启动脚本来达到缓存资源的效果。SSRSSR则从另外的角度出发,在请求页面的时候就进行服务端数据拉取和页面直出,首屏得以在一个网络往返就可以展示,有效地规避了后续需要等待css/js资源加载、数据拉取的时间。性能体验有比较大的提升,在BFF普及的情况下开发模式简单,很受欢迎。公司内相关工作考虑到WebView的初始化(冷启动/ 二次启动)、页面网络请求、首屏数据接口的耗时,白屏时间还是可感知地存在的。以我们要开发的页面为例采用SSR首屏耗时均值~600ms,可交互时间均值~1100ms。如何进一步消除白屏?这里为各位介绍公司内外针对h5首屏性能优化的优秀方案。手Q团队的VasSonic是集大成者,主要思路是采用WebView和数据预拉取并行的方式。这套方案需要客户端和服务端采用指定协议改造接入,开发时也有一定的改造工作。微信游戏团队主要思路是利用jsCore做客户端预渲染,用户点击后直接上屏。这个方法也达到了很好的效果,首屏FCP时间从1664ms降低到了411ms。我们做了一个简要的方案对比,可以看到每个方案都针对渲染链路的某个或多个环节做了优化,其中VasSonic的效果比较显著。不过结合企业微信业务实际情况,我们列出了如下几点考虑:首先,接入对客户端和服务端有一定的改造成本,业务开发也有一定的改造工作。其次,我们已经有一套的统一发布平台,希望能复用这套发布能力。最后,性能上有没有进一步优化的空间呢?业务需求对体验上的要求是希望达到更好的性能效果或者说尽可能完全地消除白屏。基于以上考虑,我们在上述方案的基础上做了进一步的实践探索,以期望达到更好的性能效果。
离线包SSRVasSonicCSR
资源加载
数据拉取
JS执行
WebView启动优化
首屏FCP
可交互(取决于JS执行)
2)方案架构为了达到尽可能完全消除白屏,我们还是从初始问题出发,结合渲染链路进行分析,思路上针对每个环节采取对应的优化方法。每个环节的优化在具体落地时会存在着方案的利弊取舍。比如预拉取数据一般的思路是交给客户端来做,但是存在着客户端请求和h5请求两套机制(鉴权、请求通道等方面)如何协调的问题。在渲染链路分析时,如果业务的js执行也贡献了不少耗时,有没有可能从通用基础方案的角度来解决这个问题,同时也能减少业务对性能优化的关注?这是个值得各位思考探索的问题。具体的内容会在后面展开来说。如图展示了方案的优化思路和主流程。方案使用离线包解决了资源请求耗时的问题,在这个基础上通过耗时分析找到瓶颈环节,进一步采用预热的思路进行优化提速,解决了WebView初始化、数据预拉取、js执行(app初始化)耗时的问题,最终达到了理想的性能体验。图1 上屏流程图2 方案架构下面我们具体介绍下方案,包括:离线包技术、预热提速和进一步的优化工作。离线包加速为了规避资源请求耗时,我们使用了离线包技术。离线包技术是比较成熟的方案,相关打包、发布拉取的方案这里不多说了,主要说下方案中一些设计上的考量。1)加载流程我们通过offid作为离线包应用的标识,fallback机制保证离线资源不可达时用户也可以正常访问页面,通过离线包预拉取和异步检测更新机制提高了离线包命中率,尽可能消除了网络资源加载的耗时。2)fallback机制因为用户网络状况的不确定性,离线包加载可能存在失败的情况。为了保证可用性,我们确定了离线包加载不阻塞渲染的思路。当用户点击入口url,对应offid离线包在本地不存在时,会fallback请求现网页面,同时异步加载离线包。所以我们针对离线包的打包结构,按照现网URL path来组织资源路径。这样客户端请求拦截处理也会比较方便,不需要理解映射规则。当发现离线包不匹配资源时,放过请求透到现网即可。如图展示了我们的离线包结构示例。3. 离线包生命周期为了提高离线包命中率,我们会配置一些时机(e.g.入口曝光)来预拉取离线包。离线包的更新机制:客户端加载时根据offid检测到本地离线包的存在,则直接使用拉起,同时启动异步版本检测和更新。如果新包版本号大于本地版本号则更新缓存,同时发布平台也支持区分测试环境、正式环境以及按条件灰度。上了离线包后,可以看到页面的首屏耗时均值从基准无优化的1340ms降到了963ms,离线包的预拉取和更新策略则使离线包命中率达到了95%。首屏耗时得到了一定的降低,但也还有比较大的优化空间,需要更一步的分析优化。预热提速通过离线包的加速,我们解决了资源请求耗时的问题,不过从整个渲染链路来看还有很大的优化空间,我们做了具体的耗时分析,找出耗时瓶颈,针对耗时环节做了进一步的优化提速。1)耗时分析离线包技术规避了资源请求耗时,但是从整个渲染链路来看还有很大的优化空间,我们做了耗时分析如下。Hybird应用中,WebView初始化是比较耗时的环节,这里我们针对iOS WebView做了测试。
首次冷启动/ms二次打开/ms
iOS(WKWebView)480ms90ms
数据拉取方面,不同入口页面的耗时不一,某些入口页面比较重的接口耗时超过了1s。此外,我们发现js执行也贡献了不少耗时。以某入口页面为例,框架初始化时间~10ms,app初始化时间~440ms。2)渲染链路预热提速预热流程我们的目标是消除白屏,这里理想的方案是找到一种和业务无关的通用解法。方案的主要思路是预热,把能提前做的都做了。预热是不是就是把WebView提前创建出来就好了呢?不是的,这里的预热涉及到多个渲染环节的优化组合。如图展示了预热的整体流程,下面一个个来解。2)WebView预创建为了消除WebView的耗时,我们采取了全局的预创建WebView,时机为配置入口曝光。不过全局复用预热WebView不可避免地会引入可能的业务内存泄露问题,下文会介绍对应的规避方案。数据预拉取数据拉取是页面渲染的一个耗时环节。为了消除数据预拉取耗时,在预创建WebView阶段我们同时进行了数据预拉取。数据预拉取常见的思路是交给客户端来做,但是存在着客户端请求和h5请求两套机制如何协调的问题,以请求鉴权为例,存在以下的问题:第一,Web团队自身有一层node BFF,实现了相应的数据拉取业务逻辑,而客户端则走的私有协议通道请求C++后台,二者是不同的鉴权机制。第二,如果交给客户端来做,可以接入HTTP请求这套机制,改造成本比较大,如果复用原有通道,则一份数据业务逻辑需要两套实现。如何设计一套通用可扩展的方案?我们希望做到客户端只关注容器的能力(预热、资源拦截等),屏蔽掉更深入的对Web的感知,这样的解耦可以有效控制方案的复杂度。因此,这里我们针对离线包配置项增加了preUrl字段,使客户端维护更通用的能力,数据预拉取交给业务团队来做,具体如下:第一,客户端:拉取某个离线包配置项时会读取该字段,同时针对当前曝光的入口url可能存在多个有着不同的数据需求,这里会进行收集,将曝光url中的业务key参数拼接到preUrl来初始化WebView,这些作为通用能力。第二,业务:preUrl页面在加载时会拉取相应的业务数据存到localStorage,实际的数据预拉取请求放到业务方发起,也可以很好地兼容已有的技术栈。JS预执行很接近目标了,最后js执行的耗时能不能消除呢?首先来看下440ms的耗时具体在哪里,通过分析看到,框架初始化仅需要不到10ms的时间,而真正的大头在业务代码的执行,其中代码编译耗时~80ms,其余的都是业务app初始化执行时间,这个是业务本身复杂度造成的。我们首先考虑了创建两个WebView的方案,一个负责加载preUrl预拉取数据,另一个负责loadUrl上屏,这样设计上比较简洁健壮,不过实践下来发现效果不理想,如图展示了该方案的效果,渲染不稳定可以感知到白屏的存在。在已经有了预拉取数据和离线资源的情况下,理论上用户点击后需要等待的就只有渲染这块的耗时,实际我们发现在复杂应用初始化时存在js执行耗时较大的问题。最终我们做了一个预执行的解法。结合SPA的特点,将preUrl作为SPA的一个子页面,不需要UI展示,只负责预拉取数据,这样子页面加载完成的同时也完成了app提前初始化。而相应的不同入口切换页面时,不同于复用预热WebView重新reload页面,为了保留app初始化的效果,我们采取了一套Native通知Web SDK,页面切换交给WebView控制的方案。其中,Native通知则以调用SDK全局方法的方式。通过这种方式,入口页面间切换其实只是hashchange触发的子页面渲染,达到了不错的效果。流程图即预热方案的上屏部分。该方案执行后我们达到了预期目标效果,最大限度地消除了白屏接近Native体验。需求上线后通过监控数据可以看到在命中预热和离线包逻辑的情况下,从用户点击到页面上屏可交互耗时均值约130ms。进一步优化1)离线包安全在离线包安全方面,为了防止包篡改,每我们次打包发布时都会生成包签名和文件md5。客户端在使用解析离线包时会校验完整性,在返回离线资源时会校验文件完整性。2)稳定性整体方案在性能上已经达到目标了,保证稳定性对产品体验也很重要。我们为了消除js执行的耗时,采取了Native通知Web SDK控制页面切换的方式。虽然比较灵活但是也带来了稳定性的问题。具体来说,如果SDK在做页面切换时异常,之后用户打开每个入口url都会看到相同的页面。入口页面的业务在用户使用过程中如果跳转了非SPA的链接同时没有注入SDK,之后的页面切换也会失效。如何保证预热容器的可用性呢?我们设计了一套通知机制确保客户端感知到预热容器的可用状态,并在不可用时得以恢复,如图。预热容器会维护isInit和isInvokedSuc两个状态。只有当preUrl成功加载和SDK执行成功上屏时,两个状态才会置true,此时的预热WebView才是可用的,否则会回退到普通容器模式进行load url来加载页面。此外,在每次入口url曝光时,已有的预热容器也会销毁重建,也有效保证了容器的稳定性。3)内存泄露使用全局的预创建WebView,不可避免的会引入可能的业务内存泄露问题。在测试过程中,我们也发现了这种例子。可以看到当点开使用了预热容器的页面后放置一段时间,整个内存在不断上涨,最终会导致PC端页面的白屏或者移动端的Crash,这个状况最终归因是业务逻辑的实现存在缺陷。不过在基础技术的角度而言,开发者也需要采取措施来尽可能规避内存泄露的情况。主要思路是减少同一个预热容器的常驻,也就是对存活的容器设置有效期,在适当的时机检查并清理过期容器,我们选择的时机是App前后台切换时。4)解决副作用出于性能考虑,我们选择了通过Web SDK控制页面的方案,同时使用了全局的预创建WebView。这带来了副作用——当页面对容器做了全局的设置,可能会影响到下一个页面的表现。比如:设置document.title、通过私有JSAPI设置了WebView导航栏的表......当执行这些操作时,在下一个页面也复用预热容器的情况下,全局设置没有得到清理重置或者覆盖,用户会看到上个页面的表现。为了解决上述问题,业务可以在每个页面主动声明需要的表现来覆盖上个页面的设置,理想的方法还是基础技术来规避这个问题来保证业务开发的一致性。我们在SDK控制切换页面时,进行了一系列的重置操作。此外,在Windows和Mac端,我们也设计了双预热WebView的方案来完全解决这个问题。每次使用时同时创建新容器,得以保证每次打开入口页面都是使用新创建的容器。当然,方案的另一面则是会带来App内存的上涨。总结我们从渲染链路入手,针对每个环节进行分析优化,最终沉淀了一套可用可扩展的Hybird H5秒开方案。从渲染链路的角度来看,方案通过离线包和预热一系列优化,将用户从点击到可交互的时间缩短到了一个SPA路由切换上屏步骤的耗时。上线后我们监控发现,命中了预热离线逻辑的页面首屏耗时~130ms,相比于离线包、SSR都有优势,同时预热离线容器命中率也达到了97%,达到了理想的体验效果。希望本篇对你有帮助。‍‍

腾讯工程师技术干货直达:

1、算法工程师深度解构ChatGPT技术

2、10分钟!从架构视角读懂K8s

3、探秘微信业务优化:DDD从入门到实践

4、耗时减半?腾讯云OCR只做了3件事

上一篇: 下一篇:
x
推荐阅读

H5开屏从龟速到闪电,企微是如何做到的

2022-12-19

做多中国 2022年12月19日盘后技术测市。 世界实时

2022-12-19

东星医疗董秘回复:公司目前尚未涉及机器人业务 环球通讯

2022-12-19

全球资讯:浦江上山,又逢一年稻熟时 | 汤朔梅

2022-12-19

大帝34+13!76人送勇士3连败 哈登27+5+9普尔29分

2022-12-18

每日观察!五粮液曾从钦:白酒横跨一二三产业 推动产业融合发展

2022-12-17

绑架就的判多少年 世界热推荐

2022-12-17

焦点速读:《缉魂》口碑获赞,你猜不到它的结局

2022-12-16

俄媒:今年前9个月俄主要商品对欧出口增加50%|头条

2022-12-16

ST国华: 2022年第一次临时股东大会决议公告

2022-12-15

万润科技(002654)12月15日主力资金净卖出20.91万元

2022-12-15

全球热门:威孚高科董秘回复:公司电子油泵产品已获取国内外多个定点项目

2022-12-15

各地打出政策“组合拳” 撬动市场百亿让利优惠-环球快看

2022-12-14

阿莫西林胶囊哪里可以买_焦点热文

2022-12-14

环球微速讯:厦门象屿:12月13日融券卖出金额183.30万元,占当日流出金额的2.07%

2022-12-14

12月13日贵州百灵(002424)龙虎榜数据:北向资金净买入1864.61万元 全球简讯

2022-12-13

安彩高科董秘回复:公司没有茅台酒相关的业务

2022-12-13

万润新能: 关于签订《湖北万润新能源电池正极材料项目投资协议书及相关回购协议》的公告_独家

2022-12-12

从数字水产看一条鱼的“前世今生”_环球速讯

2022-12-12

杰华特: 杰华特首次公开发行股票并在科创板上市网上路演公告 今日热讯

2022-12-11

每日视点!新股开板提醒:光华股份打开一字涨停

2022-12-09

尔康制药董秘回复:公司目前未生产、销售医疗器械

2022-12-08

龙佰集团: 第七届监事会第四十六次会议决议公告 观天下

2022-12-06

2022年服贸会在京落幕 天津市交易团的首发创新类成果达16个

2022-09-07

国美与阿里云达成战略合作

2022-08-15

上周ABS行情走跌受关注 业内预测ABS价格短期内或窄幅有跌

2022-07-05

苏银理财打造“518理财月” 开展“减费让利”活动

2022-05-20

商业保险也能定制 南京探索家庭医生服务新模式

2022-05-20

首付比例不变 天津多家银行陆续执行首套房利率优惠政策

2022-05-20

“天津惠民保”将上线 助力天津多层次医疗保障体系建设

2022-05-20

银行狂卖理财型保险 理财型保险站上C位

2022-05-20

江苏银行业一季度成绩耀眼 掀起2022年开门红

2022-05-20

唐山加快验收时间 为建筑工地开复工保驾护航

2022-03-19

消费者“身材焦虑” 减肥市场疯狂吸金

2022-03-19

2月份秦皇岛新建商品住宅销售价格环比下降0.2% 同比下降4%

2022-03-19

深圳技术进出口全年合同数量共1347项 同比增长2.51%

2022-03-19

邢台柏乡:打造羊肚菌产业示范带 引领村级集体经济发展

2022-03-19

胡金秋32分17板 浙江广厦男篮“双杀”稠州金租

2022-03-19

黑龙江新增本土核酸检测初筛阳性人员5例 均在讷河市

2021-12-13

“恋爱盲盒”抽的不是爱情,是急功近利的心

2021-12-13

北京12月12日新增2例境外输入确诊病例

2021-12-13

满洲里本轮疫情社会面“清零”,迎来拐点!

2021-12-13

北京今日晴冷在线气温低 本周中后期或再遭冷空气侵袭

2021-12-13

近六成受访大学生表示自己不能脱离表情包

2021-12-13

停车费上涨,昆明部分医院停车难缓解了吗?

2021-12-13

救人快递小哥:我不想成为网红 将继续踏实工作

2021-12-13

野猪拟从“三有”野生动物名录中除名

2021-12-13

“三有”名录删除野猪,要把握好捕杀与保护的度

2021-12-13

齐齐哈尔讷河发现5例核酸检测初筛阳性人员

2021-12-13

野猪退出“三有”名录不是一道“滥捕滥杀令”

2021-12-13

网红蹭“遗孤”流量是变相吃“血馒头”

2021-12-13

演员涂们病逝 曾被称为“草原王爷专业户”

2021-12-13

被偷走的那些年:被拐14年后他们成夹在中间的孩子

2021-12-13

文峰道歉:官微官网整改,10个工作日内对接预付卡备案

2021-12-13

山东烟台海域货船沉没已致9人遇难 搜救仍在进行

2021-12-13

浙江绍兴累计报告确诊病例107例 无症状感染者1例

2021-12-13

第三届国际白鹤论坛举办 中外专家聚焦生物多样性保护

2021-12-13

浙江绍兴本轮疫情已累计报告107例确诊病例

2021-12-13

“零容忍” 浙江宁波公安机关将严厉打击涉疫违法犯罪行为

2021-12-13

宁波镇海疫情未发生外溢 44例感染者均在蛟川街道管控区内

2021-12-13

来华留学生游梵净山 感知贵州多彩文化

2021-12-13

货船触礁进水 福建海警成功营救6名船员

2021-12-13

战“疫”时刻:浙江疫情下的“特殊”二三事

2021-12-13

浙江宁波44人已确诊 年龄最小为2岁 最大为70岁

2021-12-13

浙江宁波此轮疫情病毒为德尔塔变异株(AY.4 进化分支)华沙株

2021-12-13

南粤古驿道徒步体验活动(西京古道站)韶关举行

2021-12-13

上海试点驾驶证“学法减分” 一年最多减6分

2021-12-13

河南周口发布公告 明确过节确需返乡应提前3天报备

2021-12-13

浙江越城区新增1例确诊病例 系上虞区病例的密接者

2021-12-13

浙江已报告阳性感染者139例 明确严控跨省出行

2021-12-13

第二届鄱阳湖国际观鸟周在“中国候鸟小镇”江西吴城开幕

2021-12-13

“酥油茶‘遇见’咖啡,好比空气中飘着香水味”

2021-12-13

西安新增1例本土确诊病例 活动轨迹公布

2021-12-13

浙江三地病例感染病毒均属于德尔塔变异株

2021-12-13

山东烟台海域一载有14人货船沉没 9人已无生命体征

2021-12-13

浙江严控跨省出行 中高风险地区人员严格限制出行

2021-12-13

陕西西安一诊所工作人员确诊 8份核酸检测环境样本结果呈阳性

2021-12-13

浙江绍兴越城区在集中隔离点发现1名核酸检测阳性感染者

2021-12-13

截至12日15时 西安已追踪管控密切接触者486人

2021-12-13

陕西西安一诊所工作人员被诊断为确诊病例 活动轨迹公布

2021-12-13

抗疫特写:交通封控后的上虞“24小时”

2021-12-13

居家观察期间擅自离开封控区域 浙江上虞警方处罚3人

2021-12-13

杭州发布致市民公开信:非必要不流动 少聚集

2021-12-13

满洲里新冠肺炎救治感控督导组:“战事”越严峻 越要教会大家如何躲“子弹”

2021-12-13

浙江宁波、绍兴和杭州三地累计新冠肺炎确诊病例138例

2021-12-13

宁波镇海疫情下的“产科故事”:三天迎来28个宝宝

2021-12-13

内蒙古满洲里核酸检测累计检出阳性样本532份

2021-12-13

内蒙古满洲里新增确诊病例3例

2021-12-13

银川一企业为社区防疫人员捐赠“黑心棉”大衣被查处

2021-12-13

重庆15家医疗美容机构被立案调查

2021-12-13

四川泸州市泸县发生3.0级地震 震源深度8千米

2021-12-13

物资如何安全运抵封闭城区?浙江镇海内外联动保供应

2021-12-13

广西宁明县实施分区分级防控 非必要不离县

2021-12-13

江西吉安发现1例境外输入新冠病毒核酸检测阳性

2021-12-13

一货船在烟台海域沉没 3人获救4人遇难7人失联

2021-12-13

【挑战365天正能量速写画】第012期:为了陌生人赴汤蹈火

2021-12-13

守望下一个春天——疫情中的“冰城人”侧记

2021-12-13

山东烟台海域一货船沉没致14人遇险 3人已获救4人遇难

2021-12-13

满洲里已确诊病例年龄最小的3个月、最大的过百岁

2021-12-13

浙江绍兴新增7例确诊病例和8例无症状感染者

2021-12-13