欢迎光临散文网 会员登陆 & 注册

拉勾算法突击特训营3期-明月何皎皎

2022-11-20 15:51 作者:山观那恭喜囧昂贵的  | 我要投稿


Que App跨端技术架构实践
1.麻雀的整体介绍

拉勾算法突击特训营3期

拉勾算法突击特训营3期https://www.zxit666.com/4981/
1.1.简介
首先,我们来介绍一下语言Que的整体情况。Language Que是蚂蚁集团推出的笔记和文档知识库管理与协作工具。目前,全集团约有10万员工也在日常使用这一工具,并对外提供服务。
下图是基于电子的语言Que推出的Mac和Windows桌面,以及处理移动端工作场景的小程序。此外,从去年开始,我们开始开发移动应用程序,并于今年2月成功推出。右图为Android/iOS应用截图。

1.2.语言雀的整体技术选择
接下来我就介绍一下麻雀的整体技术选型。Que的内部名称是Skylark,它的整个项目位于一个大型的代码库中。这个代码库中包含了server、desktop和mobile的所有代码,如下图所示:


其中服务器使用Node.js,Egg.js,也有部分服务是基于Java/Kotlin开发的,但这部分目前比较少。PC端主要使用React技术栈,桌面端使用React和电子,小程序使用React和H5离线包。正如你所看到的,整个技术是基于JavaScript或TypeScript的。
语言Que整个技术团队没有前端和后端或者客户端之分,大家都是全栈式的做产品研发。一个团队成员可能必须完成需求的服务器端部分和前端代码开发。在此基础上,我们设计开发了手机App,接下来会详细介绍。
2.语言鸟App架构的演绎与设计
2.1.阿里云mPaaS
Que App的架构是如何设计的?首先,整个集团已经有了一个相对稳定的移动终端框架——MPAAS,这是移动终端开发的基础框架,提供了丰富的移动终端基础能力,如配置切换服务、推送服务、基于长连接的同步服务、H5容器&离线包、移动分析、移动网关等。现在它也在阿里云上对外提供服务,很多三方公司都基于这个框架开发了自己的app:

2.2.移动建筑理念
在此技术品牌的基础上,我们设计了移动终端的架构。首先选择阿里云上的mPaaS作为底层框架基础,然后客户端的原生框架层尽量做到轻量级,与业务解耦:

接下来对于渲染层,我们考虑动态或者混合方案,比如根据文档阅读页面或者编辑器的业务特点选择特定的框架。最后要考虑同构开发,因为已经有很多多端的业务模块在运行。如果可以实现同构开发,那么这些代码或者经验就可以重用。
2.3.移动解决方案比较
下图是各种开发框架在移动端的对比。相信你在很多场合都见过。其中,基于H5混合(H5或离线包)的方案性能稍差。纯Native虽然性能很高,但是开发成本也相应增加,上手难度大。现在一些公司也有自己的内部混合开发方案。


2.4.语言雀的选择
那么如何选择麻雀呢?首先,我们希望麻雀的体验流畅,能够接近原生App的各种体验;其次,希望能写一次,两边跑,兼顾开发效率;然后,可以有Web R&D的经验,让团队的Web技术栈学生快速参与开发;最后,希望可以同构复用,让之前的经验和模块可以直接复用。
综合考虑各种因素和实际业务需求,我们最终选择ReactNative作为业务层开发框架。
2.5.语言鸟App架构图
接下来我给大家介绍一下语鸟App的整体架构,如下图所示。底层是mPaaS的基础设施,如前所述,它包含一些常见的基本组件。中间层是原生基础能力层,提供基础账户管理、统一资源管理、动态能力、各种桥梁等服务。

接下来,我们可以看到两个向上的箭头。RCTBridge负责通过React Native桥接口将基本服务暴露给React NativeJSBridge通过H5 JSBridge向H5同步公开这些服务。然后,ReactNative和H5之间的双向通信通过RCTEvent进行。
反应层主要实现页面生命周期、业务跳转、页面展现等。H5主要用于承载需要高更新速度的业务。上层是CI/CD、DevTools、环境切换、单元测试等。,全面支持语鸟上层的具体业务。
2.6.三层架构

如图,可以看出整体是三层架构。在原生层,我们使用Kotlin/Swift来实现。反应层通过TypeScript/同构Web实现。该层主要用于实现对流畅度和体验要求较高的列表或页面。H5层主要结合Sparrow的具体业务特点使用:比如你想用ReactNative实现一个富文本编辑器或者阅读器,那么它的成本是很高的,这种情况用H5实现;对于需要高页面加载速度的H5页面,我们使用离线包来加速页面资源。
2.7.常规JSBridge设计
接下来,我们来介绍一下一般的JS桥设计如下:

在本地层,RN和H5共享一个JS桥实现。一些底层的通用服务功能通过两个桥公开,H5和ReactNative可以直接调用这两个桥。上图右侧显示了H5和反应呼叫桥的代码。其实除了第一行不一样,后面的桥调用和结果处理都是一致的。
2.8.反应本地H5双向消息流
在业务开发中,不可避免地会遇到反应性页面和开放的H5页面之间的交互和通信。我们开发了双向消息流机制,可以在两边使用postMessage/onMessage来发送和接收消息。
比如进入富文本编辑页面后,底部有一个ReactNative视图,在这个视图上嵌入了WebView/WKWebView来显示编辑页面。这涉及到H5和ReactNative之间的双向消息流:

如上图所示,蓝色箭头是H5呼叫反应式,红色箭头是反应式呼叫H5。双方通过postMessage/onMessage相互通信,支持回调处理。
3.跨端同构实践
如前所述,在选择Yuque App的技术时考虑到了同构开发。那么,语言雀App中涉及到哪些场景的同构呢?在具体的业务研发中,我们遇到了几种典型的同构场景。接下来简单介绍一下同构的实践经验。
3.1.基于视图模型的同构列表页面
如下图所示,我们看到一个包含一些列表的网页,每个列表项包含一个操作选项条目。用户点击操作菜单后,可以对列表进行排序、过滤或删除。小程序和移动应用也是如此。这三个页面的共同点是都是一个列表页面,需要同时请求网络加载数据。此外,它们还可能包括分页操作等。当然这里没有特别复杂的交互。点击操作菜单进行删除等操作。知道了这些共性,我们就很容易发展出同构。

具体的列表页面如何基于ViewModel进行同构开发?如下图所示,我们拿出通用的ViewModel,做加载管理,数据请求,用户操作管理等。在里面。网络请求管理可以通过recentListAll进行请求,并分别通过状态和处理程序公开数据和特定操作。这最终会返回状态集和一个动作列表:


在使用上层的时候,比如我们使用这个ViewModel渲染最终页面的时候,只需要在每个平台上重写UI渲染部分,返回到对应平台的View/div。常见的逻辑密集型和请求密集型代码都是在相同的结构中开发的。
3.2.请求请求同构
互联网服务研发中的网络请求在接口层面是同构的,可以保证三端代码和开发模式的一致性。具体同构模式如下:

同构定义一个通用接口文件,其中fetch/get/post/...并使用其他方法发送请求;
在每个平台上实现特定的fetch接口。比如Web端使用浏览器的fetch接口,applet端可能调用AlipayJSBridge,ReactNative端调用LarkRCTBridge;
在构建阶段,request.js通过alias在各种平台上重写。


3.3.该消息在三个端点是同构的。
接下来我们介绍另一个同构场景:消息通知三端同构。例如,我们在Web端有这样一个消息列表。只要别人关注我或者评论我的文档,就会产生一条消息。小程序和app端的UI都差不多。另一个场景是App消息推送。当其他人操作我的文档时,它应该显示在移动设备系统的通知栏中:

那么这种情况下我们怎么做同构开发呢?现在有70多种信息。如果您想为所有三个终端编写一个实现,您可能需要编写230多次。这显然是不现实的。在这一点上,可以基于同构方案来完成。同构部分包括各种消息的同构生成器生成器,通过模板通知上下文构建三端渲染结果:服务器获取消息字符串进行显示,在H5或Web端渲染native div、span等元素,在ReactNative端渲染View、text等视图。

比如下图所示的上下文上有buildActor、buildSubject、buildLink来渲染用户头像或链接等。接下来,服务器、applet和ReactNative可以提供三种上下文实现:

上面介绍的一些典型的同构场景,很好的验证了App开发中架构设计阶段提出的同构思想。在实际的R&D中,模块和代码的重用将大大提高R&D的效率。
4.子应用程序设计
在实际的业务R&D中,一些业务模块对更新的及时性有很强的要求。此外,技术方也希望一些业务模块可以独立维护和交付,可以按需加载,减轻主应用负荷。在此基础上,我们设计了一个子应用方案来满足这个场景。
基于反应式的动态加载特性,设计了一个子应用架构。使App中更新率高的场景动态加载子应用。如下图所示,RN侧的主应用代码和子应用代码可以分开维护,子应用可以用app打包预置,也可以通过CDN动态分发加载,更符合金丝雀的业务场景。

5.性能、稳定性和交付
5.1.性能调整
在实际开发中,我们遇到了一些性能问题。首先是App启动速度的优化。App启动时,一般需要显示闪屏页面、隐私协议授权页面、权限授予等。我们将闪屏页面和主活动合二为一,同时利用管道方案自定义启动细节,最终优化了启动速度。
二是笔记本编辑器启动速度的优化。如前所述,编辑器是由H5制作的,但如果用户受到启发,想做一些记录,如果编辑器启动缓慢,那么用户就很恼火。为此我们为小吉做了一个单独的编辑器,可以通过离线打包预置到客户端,也可以通过动态分发更新,第一时间快速拉起。
此外,我们还优化了WebView的加载,并针对一些通用的JS和CSS预加速了一些资源包。结合WebView预创建+回收方案,大大提高了App中H5页面的打开速度。

5.2.WebView预创建+回收
在Que App中,文档阅读页面、编辑页面等复杂页面均由H5实现。用户一直反馈终端中的打开速度非常慢。经过我们的实测,在一个很差的安卓机型上打开一个文档大概需要5s!结合业务特点,我们采用了WebView预创建+回收的方案,大大提升了H5的开放性能。
如下图所示,App启动后,启动WebView预创建池,预创建离屏H5骨架屏——这个骨架屏是一个单页应用,包括最后经常使用的页面,比如阅读页面、新页面、个人页面等。当用户打开相应页面时,直接将其从池中取出,识别出打开场景后,切换替换路线。由于页面所需的资源已经预加载,在打开阶段,只需要拉取相应的业务数据进行渲染,大大提高了页面的打开速度。

在方案推出之前,我们将主要场景的FCP耗时嵌入点作为优化基准。上线后安卓平均耗时下降67%左右,iOS平均耗时下降70%左右,整体效果还可以。但是也有一些场景是骨架屏用不上的。例如,用户在进入后立即访问H5页面。如果此时骨架屏还没准备好,体验会降级到优化前。我们以后会继续想办法优化这一块。
5.3.稳定性监控
通过mPaaS埋点SDK统计埋点信息,通过mPaaS监控后台可以看到一些基础数据,同时这些埋点数据流会每日广播到内部监控市场和钉钉集团,也可以通过麻雀的实时报告通道进行ErroeBoundary/JSException实时广播,如下图:

5.4.R&D和交付效率
在三层架构的实践下,Que App可以保证R&D效率和交付效率。我们每周都会发布一个测试版,有可以快速滚动测试版的小功能,测试版用户可以给出积极的反馈。同时,我们会每两周发布一个小版本,每个月发布一个大版本。
目前整个架构的原生端比UI更注重服务:Android和iOS原生实现的模块基本都是面向服务的代码,通过JSBridge暴露给上层。反应方强调UI胜于服务:它只是一个简单的渲染层。原生服务层的接口和能力稳定后,变化不大,随着业务的快速滚动,上层可以通过反应式开发和交付。

5.5.交付质量
作为CI/CD的一部分,我们的QA同学提供了非常全面的自动化测试。他们会每天进行自动化测试巡视,用最新的包进行滚动测试验证,同时出具报告。如果有问题,他们会第一时间通知开发同学修复。以下是自动化测试报告的截图:

6.总结和跟进计划
在日常开发中,可能需要一些原生组件。常见的情况是,社区没有它们,或者社区组件的功能与业务需求不匹配。比如语言Que App的底层基础服务和UI组件都是Native提供的,语言Que现在提供99 Native JSBridge。还有一些UI组件需要Native提供双端实现,比如NebulaWebView、ImagePreviewer、PullToRefreshView等。:

拉勾算法突击特训营3期-明月何皎皎的评论 (共 条)

分享到微博请遵守国家法律