
为什么要有动态化?
- 应“变”:随着互联网红利的消失,整个移动市场的关注从“流量”转成了“留量”,大部分的移动产品也都告别了初期的抢占市场,对某个业务领域的精细化打磨、避免 App 发布漫长的周期,在出现问题时还能即时对线上进行中止血,成为了所有业务的基本诉求。
- 提“效”:动态化往往和跨端化一桌而谈,如何在“变”的基础上还能提升 iOS/Android 两端,甚至 H5 M Site 三端的研发效能,做到“一次开发、多端运行”,让技术更快满足业务的迭代助力业务发展。
动态化几个阶段(类型)
- Native 组件 + 局部配置化下发:最原始阶段,可变化范围小,大变还是需要依赖各端 Native 开发发版。
- DSL Native+:通过一个特定语法的 XML/JSON 文件描述布局,端侧植入 SDK 进行渲染;可做到纯 UI 变化完全不依赖发版,但可能缺少富逻辑和交互处理能力。
- JS Runtime + Native View 转译:RN/Weex 方案,通过 JS 运行时解析 DOM 转换为 Native View 渲染,逻辑层通过 JS 执行,依赖 Native 特有能力需要 Native-JS 桥接,性能不可观。
- WebView:完整的浏览器渲染引擎,和标准前端开发接轨,灵活性高,生态成熟,性能低。
为什么是 DSL Native+?
从「支持动态化的程度」、「与原生体验的差异」、「方案集成与功能开发成本的高低」三个维度出发,将市面上的移动端动态化方案分成三个方向:

动态化方案需要满足「跨平台」、「热更新」两个基本诉求,因此没有考虑 Android 插件化这个大类下的方案。
- 「Web 增强(Web+)」方向主要基于 WebView 实现,能够进行快速的迭代,在洋葱已经有了对应的解决方案;
- GPL 和 DSL 可以看作「Native 增强(Native+)」方向的子方向,Native+ 方向基于 App 内自带的语言解析器,独立于 WebView 实现动态化逻辑的解析、布局和渲染。
- 「基于 GPL 的 Native 增强(GPL)」这个方向是移动端动态化的热门方向,React Native、Flutter、NativeScript 等等,实现原理各不相同,共同的特点是利用了通用编程语言器,可以是系统提供的(如 Javascript),或者是集成到 App 的(如 Dart),再辅以某个布局系统和渲染方案,由于语言是图灵完备的,可以提供完美的动态化解决方案;
- 「基于 DSL 的 Native 增强(DSL)」GPL 方案虽然美好但始终需要在动态化能力、渲染性能、Framework 体积、学习和开发成本等方面取舍,难以达到完美。于是产生了基于领域专用语言的解决方案,此类方案通过采用适合专业场景的的 DSL 解析云端下发的逻辑结构,舍弃一部分动态化灵活性,换取其他方面的优势。
动态化方案选择要考量的因素很多,如渲染效率、动态化灵活程度与用户体验的取舍、方案实现成本等等。其中重点强调一下「方案实现成本」,这个因素应该基于开发团队的现状进行考量,可以包括开发成本、学习成本和人才培养成本,开发成本很好理解,即该方案从调研到落地的工作成本;学习成本和人才培养成本往往是我们容易忽略的,基于团队已经掌握的技术栈,不同的方案需要的需要掌握的知识有所不同,学习成本也不同。而人才培养成本强调的是市场上是否有对应的专业人才,不是很熟悉或者没有亲身实践过这个技术方案的人多久能够熟练掌握这项技能?比如 RN 为代表的基于 Javascript 的 GPL 方案通常需要前端开发技能和移动端开发技能的配合使用,对人力培养成本比 Native+ 和 Web + 的成本要高。
讨论了这么多,我们应该选哪个方向呢?针对公司现有的业务场景、工程现状,我们梳理出需要优先考量的原则:
- 「接近 Native 的高性能」落地页及二级页面的动态化的核心要求。相比于 Web 的灵活性,接近 Native 性能需求更强烈。滑动流畅是信息流列表的基础需求,而对于落地页,打开速度和使用体验也是重中之重;
- 「项目能够快速启动」高速发展的业务诉求。项目需要能够快速启动,快速上线;
- 「低人力成本」在业务快速迭代的过程中,支撑业务开发的同时,技术方案上的投入资源有限,前后端都很难有充足的人力投入,新方案应该占用尽可能少的人力,并且对现有工程的改造降至最低;
- 「App 包体积影响小」洋葱 App 重视用户体验,新技术对 App 性能、包体积不能产生负面影响。包体积是影响应用增长的重要因素,App Store 应用如果超过 150M,则无法在 4G 环境下下载,将会极大的影响 App 的增长,所以新的方案需要尽可能少的影响包体积;
- 「平滑迁移」基于技术架构现状。落地页及二级页面是基于现有业务的,不能因为动态化而要求整个业务侧重构,所以需要保证新的方案能够和现有业务方案完全兼容;
- 「持续演进」快速启动后的发展方案。整体框架需要支持高扩展性,可以在上线后进行持续的需求迭代。
性能 | 动态化能力 | 学习成本 | 迁移成本 | 人力成本 | 扩展性 | 包体积 | |
---|---|---|---|---|---|---|---|
GPL Native+ | 高 | 高 | 高 | 高 | 高 | 中 | 高 |
Web+ | 低 | 高 | 低 | 中 | 低 | 高 | 低 |
DSL Native+ | 高 | 中 | 低 | 低 | 低 | 高 | 低 |
「Web+」方向在性能和稳定性上略差,而且使用场景有限,不适合在落地页信息流这种流畅性要求高的场景中使用;「GPL」方向提供一套完全不同于 Native 的开发模式,可以在其基础上实现动态化功能,且能够保证较好的性能,但是目前的解决方案接入成本和学习成本都比较高,并且与复杂业务场景结合时均有难以解决的问题,不适合在已有业务中接入。
综上考虑,最终我们决定采用基于 Flexbox 的 DSL Native+ 动态化方案即 OMCD(Onion Mobile Client DSL)。OMCD 方案在业务上具有如下优势:
- 和现有技术栈完美融合。洋葱 iOS App 绝大部分业务组件基于 Yoga 实现的,几乎几乎不会产生额外的学习成本;
- 快速上线,后期维护成本较低:整体方案的上手难度低,不需要学习新的技术,能够快速进行功能迭代开发;
- 对包体积影响小:整个方案只是增加了 Google-FlexboxLayout、Yoga 两个轻量级开源布局框架,对体积影响可以忽略不计;
- 支持现有A/B测实验组,很好的满足样式实验、数据采集的需求。
为什么是 Flexbox?
动态布局方案基于 Flexbox,带来的好处是:
- Flexbox 为盒状模型提供最大的灵活性,是目前布局系统的首选;
- 跨平台方案,双端统一;
- 和洋葱 App 现有技术栈匹配度高,开源环境中有优秀开源库的本地化。
- iOS 端 Facebook 开源的 Yoga 已经经过 10+ release 迭代,有 1.1w+ 的 Star,在生产环境经过长时间验证;
- Android 端的 Yoga 库有一些难以解决的问题,选择 Google 的 FlexboxLayout 框架来解析,该框架也非常成熟,在和 iOS Yoga 配合中仅需要很少的双端适配。
为什么是 JSON?
布局描述语言上,由于各种描述语言的描述能力差异不大,在这种情况下,开发成本成为我们选型描述语言的重点。
传输体积 | 描述能力 | 基于现状的开发成本 | |
---|---|---|---|
XML | 大 | 大 | 高 |
JSON | 中 | 中 | 低 |
Proto Buffer | 小 | 小 | 高 |
YAML | 中 | 中 | 高 |
TOML | 中 | 中 | 高 |
开发成本考虑的是基于洋葱 App 现有客户端和后端的交互结构,目前前后端数据传输采用的是 JSON 格式,如果要换成其他格式的数据,客户端和后端都需要进行额外的工作处理,应采取 JSON 格式来描述布局样式。
如何设计DSL Native+ 动态化方案架构
我们将一个使用 DSL 系统,以 JSON 格式组织的描述一个视图树结构的配置称为样式。实现动态化的核心业务流程是实现布局文件云端下发和解析:编写样式文件 -> 上传到服务端 -> 云端下发样式到 App 端 -> App 端收到数据后解析样式文件进行展示。
样式管理平台
样式管理平台由业务端、引擎端和接口层三部分共同组成。其中业务端提供面向需求方的模板投放管理平台(可视化操作、样式关系的JSON数据转换等);引擎端负责存储和处理相关数据(储存样式模板、下发样式模板、实验分流等);和 App 端直接交互的是接口层,负责响应对应业务请求接口,和样式下发接口,根据 App 端的请求,选取符合规则的样式下发给 App 端,同时对处在实验内的样式进行流量分流。(理论上业务接口与样式接口应当在引擎端聚合,鉴于公司现有技术体系,前期不做强要求,满足样式下发接口即可)

业内竞品调研总结(DSL Native+ 类)
公司 | 产品 | 开源? | 活跃? | 覆盖端型 | DSL | 布局模型 | 布局框架 | 学习/维护成本 |
---|---|---|---|---|---|---|---|---|
阿里内部 | XX | ✗ | iOS/AndroidH5/小程序 | XML | Mesure | 自研 | 高 | |
阿里-天猫 | VirtualView | ✓ | 已放弃 | iOS/Android | XML | Mesure | 自研 | 高 |
知乎 | Morph | ✗ | iOS/Android | JSON | Flexbox | iOS-Yoga Android-FlexboxLayout | 低 | |
美团(大众点评) | Picasso | ✗ | iOS/AndroidH5/小程序 | TypeScript | 自研 | 自研 | 高 | |
陌陌 | MLN | ✓ | 维护力度低 | iOS/Android | Lua | Flexbox | ArgoUI | 高 |
结论
- 有能力的公司内部都已经涉足该技术领域,这不是一个新鲜概念。
- 唯一一个相对比较成熟开源的项目(天猫 VirtualView),还被放弃维护了,开源界里并没有一个可用的方案。陌陌的MLN本质上并不是一个DSL方案,其基于Lua虚拟机的跨端能力将造成极高的后期维护成本且iOS侧对Lua的Bridge支持力度远不及Android。
- 我们期望打造一套「自主可控」、「可塑性强」、「契合现有技术栈」、「低学习成本和低维护成本」的DLS方案。所以知乎的Morph思路最值得借鉴:
- DSL无任何改造成本,Json与现有后端业务也可以无缝对接。
- Flexbox在iOS(Yoga)和Android(FlexboxLayout)双端都拥有非常成熟的布局框架与模型体系。
- 双端仅需要引入一套Flexbox布局框架即可(iOS现有业务包括播放器已大量使用Yoga),无任何额外第三方依赖库。
- 自研对组内所带来的技术提升和后期维护成本的大幅度降低将带来显著收益,形成洋葱移动端侧的实质性技术壁垒。