找回密码
 会员注册
查看: 39|回复: 0

转转Hybrid体系建设历程-客户端视角

[复制链接]

6

主题

0

回帖

19

积分

新手上路

积分
19
发表于 2024-9-20 05:41:06 | 显示全部楼层 |阅读模式
前言H5在转转App中有着较高的比重,承载了B2C,C2B,C2C多个业务的巨大流量,转转在前端技术这块,考虑到业务架构和人员结构的情况,没有采用ReactNative,Weex,小程序等技术,一直在Hybrid领域进行深耕。从App诞生之初直到现在,转转的Hybrid体系经历了一些迭代和演进。之前公众号历史文章曾经发布过《转转Hybrid体系建设》,这篇文章是站在前端视角为我们展现了其中一部分内容。今天我尝试客户端的视角来回顾下转转Hybrid体系的建设历程,在这个建设历程中,有着一些我们的困惑、挫败、思考以及喜悦,希望与屏幕前的你,一起分享。几个时期转转的Hybrid体系建设,经历了几个重要的时期,我把总结为下面三个阶段:野蛮生长混乱之治性能优化和开发调试体验提升下面,我来详细阐述下这三个阶段。文章比较长,信息密度不大,一起来吧1.野蛮生长时期在转转App发展的前几年,大概是2015年~2020年上半年这段时间,Hybrid缺少系统的规划,我们刚出茅庐,Hybrid在我们眼中是什么呢?一个WebView,加载一个H5,将前端内容加载展示出来,H5JavaScript与App进行通信交互,仅此而已。我们当时还不能很好的意识到,一个成熟的或者理想中Hybrid体系应该要建设成什么样。这时候App承载的业务形态在不断的尝试中,前端与App的通信接口,也在野蛮不断扩充添加着。A业务今天来了个需求,说我们需要加一个通信接口,OK,前端和App同学约定好,测试了下没发现问题上线🚀。B业务明天来了一个需求,说我们也需要一个,OK,再来,接口不断添加着。从开发过程,到测试过程,最后到上线运行,问题也随之慢慢的暴露出来。1.1开发过程我们没有接口相关的文档或者非常的缺乏,前端同学在开发使用的时候,无法很好的知晓App目前有哪些能力可以使用,以及接口的参数和返回值是什么样的,更多的是靠查看代码和询问客户端同学,非常的不方便,沟通成本还是挺高的。另外就是由于没有合理的规划和接口分类,造成了不少接口的功能是类似的,但实现上有一些差异,会给前端同学在使用上造成困惑,究竟用哪一个才对。1.2测试过程在通信接口开发时,客户端同学自测怎么做的呢?Android和iOS客户端内置了一个html文件,里面有一些通信的接口,每次都往这个文件添加,然后编译到手机上进行测试。非常的不方便,每次要添加接口都要修改本地内置的html测试文件,然后进行编译,但并不是所有人都可以正确的编写这个js测试接口。1.3上线运行线上页面出现问题,客户端同学是比较抓瞎的:页面地址是啥?问题发生时js调用了native什么接口?参数是什么?有没有问题?是离线包引发的问题吗?是否可以通过关闭和打开离线包进行验证和定位问题?···一方面是我们的日志上报还不够全面,另一个是没有方便的小工具可以直接查看,只能通过本地调试app查看断点数据和本地log,排查定位问题的链路比较长,有些低效。另外一个显著的问题就是线上我们的WebView出现了安全问题,有骗子利用转转没有限制页面打开或者限制页面存在漏洞的情况,引导用户在App内打开骗子网页完成支付,用户被骗投诉到平台,给我们的口碑也造成了不小的影响。2.混乱之治上面的问题已经暴露,加之本身WebView也开始面临着不少问题,重新设计一个全新Hybrid架构体系迫在眉睫。建设这样新体系囊括了客户端WebView的重构,以及相关平台的建设,再到JSSDK的优化,涉及到了整个大前端基建层面。我们在2020年中的时候,基本已经完成了新的Hybrid体系设计,截止到目前,整体是这样的:2.1WebView重构历史WebView面临着诸多问题,比如存在大量历史废弃代码代码冗余,业务耦合严重Native接口设计存在不合理的情况代码全部集中在主工程内无法对多App提供能力代码过于集中不便维护Webview本身功能、白名单、Cookie管理等混合在一起,且不具有对外扩展性缺乏Hybrid接口的分组设计以及权限控制,缺乏安全性在Android和iOS两端,我们重写了WebView,并积极的采用了Kotlin和Swift语言。重写之后,将上面面临的问题就全部解决掉了。上线之后,经过一段时间的灰度,对存在的问题进行不断优化和调整,最终进行了全量,且将项目的legacywebview代码全部删除下线。至此,我们在混乱治理中,迈出了最重要的第一步。2.2DSBridge的兼容引入2020年5月6号,转转和找靓机合并,找靓机的整个WebView体系和转转还不太一样。找靓机使用的基于开源方案DSBridge的通信方式。DSBridge这套开源方案其实挺优秀:同时支持同步调用和异步调用支持以类的方式集中统一管理API支持API命名空间支持调试模式支持API存在性检测支持进度回调:一次调用,多次返回支持Javascript关闭页面事件回调支持Javascript模态/非模态对话框优点有很多,但这些优点并不是我们考虑的重点,合并融合后,我们需要考虑的重点是:找靓机侧H5如何运行在转转App上转转侧H5如何运行在找靓机App上核心就是如何统一WebView,更多的是考虑如何让找靓机的WebView平滑过渡到转转的WebView体系中来。转转使用自定义的通讯方案,有200多个API,找靓机采用了DSBridge通讯方案有100多个API。要考虑到H5在多App的运行该怎么做呢?统一的WebView容器这个是必须的,意义重大,意味着后续多App共享核心的WebView架构体系,享受统一的功能升级和Bug修复,享受统一的平台能力统一的基础能力接口,如路由、缓存、多媒体、设备、界面、位置、分享等等,这些能力独立出单独的组件,进行多App复用部分暂时无法统一的接口能力,JSAdapter抽象出H5接口,内部进行多App差异化调用,抹平差异考虑到历史接口兼容问题,存量的历史接口,仍然保持原有的通信方案,新增接口统一按照转转目前推荐的标准形式进行新增在App早期,使用iOS7系统的用户还有一定的占比,为了兼容这些用户,那时候我们并没有使用WKWebView。UIWebView我们采用的是基于iFrameurl拦截解析获取到执行函数名和参数的方式来实现JS调用Native。后面随着iOS7用户的缩小,以及iOS7带来的额外维护性问题,我们逐步放弃了iOS7,应用最低的支持版本从iOS7变成iOS8(现在最低iOS11),此时历史UIWebView的通信接口API作为存量,很多业务在用,也一直保留到了现在。取而代之的是采用WKWebView。毕竟 WKWebView相比UIWebView有着非常大的优势,独立进程和更好的JS引擎带来的性能提升以及WKWebView在稳定性、内存管理、兼容性、安全性、后台加载等方面的表现都更优于UIWebView。所以,在转转App中,由于iOS7的历史原因,存在着两套通信方式:一个是兼容UIWebView的iFrameurl拦截解析通信的方式,另外一个就是WKWebView的WKScriptMessageHandler协议通信方式。融合初期,为了支持找靓机的H5通信,转转iOS这边移植新增了DSBridge的实现,使得找靓机的H5完美运行在转转WebView容器之上,此时,接口调用的Native能力仍然是找靓机侧的。后面随着融合的不断加深,基础能力也在不断的扩大,仅有一些少数存量的接口仍然会调用到找靓机的DSBridge老接口API,大部分都会调用到客户端提供的基础能力API以及找靓机新增的转转式规范接口API。2.3平台的建设在整个Hybrid体系建设中,平台的建设是不可忽视的。我们不断收集一线的反馈,和前端支撑组不断磨合,由前端支撑组打造出统跳、接口管理、离线包、预渲染等平台。这几个平台和客户端关系紧密,还有一些其他平台如前端的性能平台、异常监控平台、报警平台等等,和客户端这边关系不大,这里就不展开说了。统跳平台:在Hybrid中进行路由跳转的信息,由统跳平台统一管理维护接口管理平台:解决Native提供的接口能力的增删改查问题,修改后,一键同步更新到前端文档页面。离线包和预渲染管理平台:解决离线包配置和预渲染配置的平台2.4规范!规范!规范!无规矩不成方圆,没有规范,就容易引发破窗效应与混乱,长期下去,积重难返。2.4.1WebView基本规范WebViewCookie、UA、UrlQuery、通信格式规范,见:转转Hybrid-SDK重构和实践一文中的『转转解决方案』部分。2.4.2安全规范骗子通过聊天向用户发送一些骗子网页,用户中招被骗钱后投诉到平台,这样的情况我们遇到了不止一个。后面我们经过白名单的多次升级,逐步完善了整个白名单体系。从添加域名的审批,到域名的定时清理,以及精细到urlpath级别的授信级别,使得近两年来,骗子通过钻白名单漏洞去行骗的的情况几乎被完全封杀掉。2.5大禹-重点解决多App接口表现不一致我们经常收到前端同学的吐槽:为什么同一个接口在转转iOS、Android上表现不同呢!为什么同一个接口两端回调的数据格式还有这么多差异!为什么同一个接口转转App和找靓机App入参和行为表现这么多不一致呢!为什么???别说啦别说啦💦(逃~)有一段时间,我们会被拉入各种各样的群里,面对群里抛出的类似上面的问题,解决起来非常的心累。不行了,得专门搞一下了。遂立项大禹,治水行动开始。治水基本方针:能统一的基础能力如扫码、分享等等,客户端要统一起来在基础能力层实现,避免转转、找靓机各自实现导致的参数、行为、回调的不一致。虽然前端JSAdapter可以做一层适配,但工作会非常繁杂,在客户端层面统一也有利于多APP基础能力的复用。对于强业务实现的一些能力,比如登录login,仍然交由各自App实现,这种情况,JSAdapter需要抹平差异。经过大禹多期的优化,我们将页面栈管理、分享、相册选图、日历、扫码、通讯录、通用存储、剪贴板、系统权限等多个基础能力,进行了统一。没有数据统计,这个带来了多大的收益,但是明显的感觉,被拉群的次数少了,之前的一些长期被吐槽的接口也很少再收到吐槽了。但大禹治水不能停下来,这是一件需要长期坚持做下去的事情。3.性能优化和开发调试体验提升3.1初期的优化性能优化其实不是最后才开始做的,而是从头到现在,一直在进行,只是阶段性的重点不太一样。早期我们在大前端领域优化手段做的比较有限,包括了公共资源预加载使用了离线包加快资源的访问速度,缩短页面打开的白屏时长离线包图片骨架屏优化白屏问题除了上面几点,前端同学也在积极的尝试各种优化方案,包括但不限于:能让你纵享丝滑的SSR技术,转转这样实践来,一起偷偷优化前端请求性能,然后惊艳所有人SSR同构降级策略离线预渲染OPR:0成本接入媲美SSR效果3.2Kraken的尝试2021年是Flutter高速发展的一年,但是官方的FlutterforWeb并不如人意,此时阿里的Kraken北海(目前的WebF)方案的出现,让我们看到了另外的一种可能。Kraken方案上层采用Web技术栈进行开发,无论是Vue还是React又或者其他如Angular,通通不限制,底层使用Flutter引擎自渲染,保证多端的一致性,使用AOT编译将Kraken编译成机器码,提供接近原生的性能。由于上层基于W3C标准实现,所以拥有非常庞大的前端开发者生态。我们联合前端同学,在Kraken方向做了一些尝试:将转转内的“附近的人”页面,试着用Kraken实现。通过这个页面的改造,我们看到了Kraken还存在了许多不足,还不足以支撑我们在线上大规模使用。存在的问题包括但不限于下面列举的一些:表现不一致问题CSS定位、布局表现与浏览器表现不一致部分API表现与浏览器不一致(getBoundingClientRect等)iOS,Android系统表现不一致重大Bug页面初始化渲染完成,动态修改元素样式,DOM不重新渲染滑动监听计算导致APP崩溃调试成本高不支持vue-router,单项目单路由不支持热更新,npmrunbuild预览不支持sourceMap,无法定位源代码真机调试只支持element和network;dom和element无法互相选中;无法动态修改dom结构,无法直接修改样式.......页面白屏,假死安全性问题无浏览器中的“同源策略”限制兼容性npm包不兼容等由于上面存在的问题带来的高额的开发调试以及维护成本,我们暂停了在Kraken方向的投入。但对后续也就是目前的WebF仍然保持着关注。3.3帝江-一次性能和开发体验的飞跃3.3.1 性能提升除去Kraken等方案的尝试,我们积极的在探索和寻找其他优化方式,最终确定了离线包、预渲染、预加载、预请求、接口请求代理、图片缓存共享等多个优化手段。离线包消除静态资源下载耗时、预渲染消除⻚⾯初始化耗时、预加载提前缓存常用静态资源、预请求提前获取主屏数据解决⻚⾯跳动和⽹络请求链路⻓、图片缓存共享将Native图片缓存共享给H5提供视觉占位等,通过一系列多级优化方案,前端可以灵活的组合上面的优化手段,使得性能体验大大提升。使用预渲染的页面,就是秒开的体验,平均首屏时间从1500ms下降到400ms左右。关于预渲染这块,后面有机会的话,我们会单独再开一篇文章一起深入聊聊。上面提到的这些方案具有正交性,可以随意进行组合接入。正常无优化的H5加载展示流程:离线包:预渲染+预请求:无预渲染+预请求:预渲染+预请求+图片缓存共享:下图点开可以动3.3.2开发调试体验我们很关注前端开发同学的开发、调试体验,以及在线上排查问题的时候,客户端能做什么可以更快的帮助定位问题。基于这个简单的愿景,我们开发了WebView小工具。概览:在概览中,我们可以清晰看到API接口日志,离线包,预渲染等优化手段的命中情况,此外我们也可以直接控制eruda调试工具以及UI走查小工具的开关,以及页面的Url,Cookie,Query,UserAgent等情况。API接口日志: 详细记录了JScallNative的每一个接口,包括request和response。预渲染: 记录了预渲染当前的下发配置,以及预渲染模版的当前状态,可以方便查看模版是不是已就绪还是渲染中或者被加入了黑名单。同时也添加了客户端的预渲染日志,方便排查页面为什么没有命中预渲染。。预请求:记录发出了哪些预请求,以及这些预请求的request和response。离线包:开启和关闭离线包功能,删除离线包缓存,以及展示离线资源的命中记录。接口代理:展示接口代理记录以及接口的request和response。图片缓存共享:记录缓存共享请求,包含目标图片和命中图片地址。后续规划文档建设持续优化前端的接口文档以及平台,在接口的用途、参数和响应描述方面力争清晰和准确,且对接口的升级改动形成变更历史等,方便追溯和兼容。埋点统一和监控统一大前端的埋点,建立更全面的埋点和监控,如页面白屏时长、大前端全链路埋点监控等,实现对H5页面的全方位把控。性能优化还有很多事情需要做,如进一步提升离线包、预渲染的命中率智能预渲染,减少不必要的模版渲染启动时的预渲染,进一步降低对App主线程卡顿的影响保持对WebF等技术的持续关注,探索应用的可能性···鸿蒙HarmonyOSNext的即将出现,意味着要基于纯鸿蒙系统重新构建一套WebView解决方案,整个架构体系和当前可能是一致的,但可能会融合鸿蒙系统的原子化服务以及多设备流转等特性,提升用户在HarmonyOS上的Web使用体验。更多阅读转转Hybrid体系建设转转Hybrid-SDK重构和实践转转Hybrid离线包治理与优化实践能让你纵享丝滑的SSR技术,转转这样实践来,一起偷偷优化前端请求性能,然后惊艳所有人SSR同构降级策略离线预渲染OPR:0成本接入媲美SSR效果https://openwebf.com/想了解更多转转公司的业务实践,点击关注下方的公众号吧!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-26 12:33 , Processed in 1.377058 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表