动态化 - 罗码 (京东科技一码多端解决方案) 介绍
作者;京东科技 胡大海
前言
动态化-罗码(后文统称动态化)是一个全自主研发的一站式跨平台解决方案,一份代码,可以在 iOS、Android、H5 及华为 HarmonyOS 运行。在研发团队使用后可大幅降低研发人力成本;为业务提供实时触达、A/B 触达等能力以提升业务投放效率;同时保障了 C 端用户优秀的用户体验。
一、背景
市面上的 APP,一般使用两种技术方式承载业务:
1、原生开发方式:优势是可以充分使用系统能力,带来极致的用户体验;劣势是动态性差、发布周期长、无法跨平台。
2、H5 开发方式:优势是动态性好、可随时发布、支持多平台;劣势是体验相对较差、系统能力使用受限(需要通过桥接使用系统原生能力)。

我们从业务效率、用户体验、研发成本三个维度总结以上两种技术存在的问题:
1、业务效率
公司端内业务需求一般需要集中在某一个固定时间发版,且各个应用市场对于 APP 的发版都有审核的周期,这样原生开发的业务就无法及时触达用户,甚至对于未升级的旧版用户无法触达。
2、用户体验
研究表明,如果一个移动端页面加载时长超过 3 秒,用户就会放弃等待;网页加载时长每增加 1 秒,用户就会流失 10%,但是由于 WebView 本身的历史包袱,渲染性能差、JS 执行效率低、用户体验差的问题一直无法彻底解决。
3、研发成本
同一个业务如果四端(H5、Android、iOS、Harmony)同时开发,需要投入四端人员,开发成本高。

二、方案实践
1、方案简介
针对上述背景中两种技术存在的问题,业界相继出现了 FaceBook 公司的 ReactNative、阿里巴巴公司的 Weex、腾讯公司的微信小程序、京东的 Taro(RN 原生部分)、Google 公司的的 Flutter、华为的 ArkUI-X 等各种跨端解决方案。

几乎每个跨端解决方案追求的就是在保证 C 端用户良好的用户体验的同时,让业务以最小的人力成本和最快的速度触达用户;下面我们从开发效率、性能、动态性、渲染方式、上手难度等维度对业界跨端方案及我们自研的动态化跨端方案做对一个对比:
通过上述表格对比发现,每一个框架都有很多优劣和部分劣势,那么为什么要自己再做一个动态化方案而不直接使用现有方案呢?
1、React Native 和 Weex 是两个比较相似的技术方案,Weex 在核心开发语言和包大小(React Native 可以通过业务拆包减小包大小)相比 React Native 具有一定的优势,但是都存在两个共性的问题,第一对于常用的长列表渲染、瀑布流渲染都存在渲染瓶颈,第二在框架每次升级后都需要所有存量业务测试验证,造成测试成本突增、业务稳定性被破坏。
2、H5 通过离线化技术能够一定程度缓解渲染速度,但在复杂场景交互仍然存在较多交互问题,甚至在运营商被劫持、Cookie 丢失等场景会导致页面直接白屏。
3、小程序可以看做是一个特殊的 H5 技术,它使用了双线程模型将 UI 渲染和业务逻辑分散到两个线程执行。
4、Flutter 的 Dart 开发语言相比其他框架学习门槛较高,并且因为没有动态更新能力,无法满足业务热更新的诉求,虽然可以通过一定的技术手段达到动态发布的目的,但整个链路就会变得复杂,导致业务维护、排查问题成本直线上升。
每一个框架都有很多先进理念值得我们学习,站在巨人的肩膀上,我们吸取了各个框架的优势,加上自主创新,发明了卡片级动态化渲染技术、高性能列表技术、底层框架升级业务无感技术、业务天然分包技术、多端分布式实时预览等一系创新,打造了自主可控的动态化跨端解决方案。
2、实现方案
2.1、源代码
分为 JSEngine 和业务代码(Hello.jue)两个部分,JSEngine 即为我们自主研发的业务代码运行时环境,在产物运行阶段会第一时间被加载,负责业务代码实例管理、任务管理、虚拟 Dom 树管理、虚拟 Dom 树 Differ、业务页面渲染管理、生命周期管理、事件分发、业务逻辑处理等一系列功能;业务代码即具体的业务代码,其结构和 Vue 一致,包含了描述业务 UI 的 template、业务逻辑表达的 script 以及业务 UI 样式的 style 三个部分,语法和 Vue 几乎一致,但是具备了标签扩展能力,比如在长列表和瀑布流场景我们可以通过结合原生列表及瀑布流控件快速打造出一个高性能的列表标签。
2.2、脚手架
脚手架方便开发者进行项目工程化管理,通过我们自研的 complier loader 完成业务代码及 JSEngine 的编译工作,借助 Babel 插件支持了 ES6 语法,支持图片 Base64 转换、产物 Zip 压缩、热重载等一系列能力;为保障业务构建产物安全,目前脚手架构建能力已经以云端构建方式运行,提供了统一的构建环境。
2.3、产物管理
云端构建的产物,可以直接发布到动态化资源管理后台,后台提供了资源加密、灰度发布、长连接推送等强大的管理能力,满足了业务人群灰度、AB 发布等诉求,为业务快速试错提供了有力保障。
2.4、产物运行
这里分为两种类型产物的运行,首先是 JSEngine,在 iOS 系统使用系统提供的 JSCore、在安卓系统使用 V8 引擎、在 Web 使用浏览器的 WebKit,由一个专门的 JS 线程在一个最早的时机(比如 APP 启动)进行 JSEngine 的加载,加载完毕后,就形成了了业务产物运行的环境;然后客户端通过下载后台对应的产物,经过解密及解压缩后就得到了业务原始 JS 文件,业务资源的运行过程,是一个创建业务实例的过程,由 JSEngine 统一管理。
2.5、统一接口声明
JSEngine 统一创建业务实例的过程是统一的,而真正渲染的客户端是多个(iOS、Android、H5、HarmonyOS 等),通过制定统一的接口规范客户端标准化对接及扩展(比如在华为鸿蒙系统适配只需实现统一接口即可),接口包含了实例创建声明周期、元素的增删改查、JS 和原生的双向通讯、热重载交互等各种能力。
2.6、接口实现
这个过程的核心任务是在 iOS、Android 等系统上,实现统一接口声明的方法,创建出业务对应的页面和处理业务交互逻辑。通过完成统一接口的元素增删改操作及其他指令后就构建出了一个组件树,再经过布局引擎布局后,就显示出了业务具体的页面效果;当用户在业务页面发生了交互事件后,通过统一接口的 JS 和原生的双向通讯调用到业务方,当业务方需要改变 UI 布局的时候,同样通过 JS 和原生的双向通讯触发布局引擎重新布局,由于 JS 语言本身是图灵完备的,所以任何业务逻辑都可以在 JS 中实现而不会收到任何限制;这样就完成了业务 UI 渲染和交互逻辑的处理过程。
三、应用场景
1、卡片场景
动态化项目孵化于京东金融 APP 实际业务场景,京东金融 APP 的积木式构建页面的技术,一定程度上能够根据接口数据驱动预埋在客户端的积木卡片自由组合一个页面,但是存量积木卡片修改及新增依然需要发版。当时通过调研发现,市面上的跨端技术多以页面维度进行支持,对于局部卡片模式的跨端没有很好的解决方案,我们决定自研一个能够和原生卡片共存的区域卡片动态化技术,目标如下图所示,被放大的两个卡片使用动态化技术实现,不改变其余楼层的原生实现方式。

区域动态化技术是我们自研的一套跨平台、动态化的楼层卡片解决方案,渲染速度几乎可以和原生同步,用户体验好,并无缝对接了公司内部运营系统及埋点曝光等功能。
2、页面场景
页面动态化技术是在区域动态化基础上的进一步扩展,提供了页面常用的列表组件、瀑布流组件、下拉刷新组件等,进一步提供的混合路由模块和以及沉浸式导航能力使动态化形成了区域到页面级别的升级。对于业界跨端方案普遍面临的埋点、曝光难题,我们设计实现了一套无侵入自动化埋点和曝光的协议接口,并在金融 APP 无缝对接了埋点、曝光通道。
3、未来适用的场景
通过进一步扩展 APP 级基础能力,可用于一个完整 APP 的开发。
四、未来规划
在渲染性能方向,探索抽取 Flutter 底层 SKIA 渲染引擎作为动态化的渲染引擎,进一步提升渲染速度和渲染一致性,降低未来多端长期维护成本。
在 DSL 支持方向,基于 Vue3 的虚拟 Dom 接口分离设计,以及 ReactNative 最新的渲染流程架构设计,为虚拟 Dom 技术思想打造的跨端框架对接多个前端 DSL 提供了空间,未来 Vue3 和 React 开发的项目可以结合动态化实现跨端,充分发挥动态化原生渲染优势,使前端业务低成本享受原生丝滑体验。
五、写在最后
动态化是一个涉及 JavaScript、iOS、Android、Java、Harmony、Vue、Node、Webpack 等众多领域的综合解决方案,我们有各个领域优秀的小伙伴共同前行,大家如果想深入了解某个领域的具体实现,千万别忘了点赞+收藏,方便以后随时阅读和提出宝贵意见。
版权声明: 本文为 InfoQ 作者【京东科技开发者】的原创文章。
原文链接:【http://xie.infoq.cn/article/42b2e9601cbd64dbb62cf68cc】。文章转载请联系作者。
评论