共计 13622 个字符,预计需要花费 35 分钟才能阅读完成。
从 PC 时代、挪动时代到万物互联的 IoT 时代,随同终端设备的日趋多样化,跨端复用的种子自此落地,开始生根发芽。从业务角度登程,跨端技术演进更多是在不同阶段、不同时间段内业务效率上的抉择,美团民宿业务在大前端交融的浪潮中逐浪前行,一直摸索和迭代抉择,为解决业务痛点而孵化出跨端框架技术,在这个过程中,咱们进行了很多的摸索和实际的思考,心愿能给大家一些启发。本文次要分享美团民宿在跨端复用技术摸索和业务实际过程中的教训。
从 PC 时代、挪动时代到万物互联的 IoT 时代,随同终端设备的日趋多样化,跨端复用的种子自此落地,开始生根发芽。从依附容器能力、各类离线化预装包的 Hybrid 计划,到通过 JSC 连贯 JavaScript 生态与原生控件,联合视图框架(React、Vue 等)寻找效率、动态性和性能更平衡的 Native 容器计划(React Native、Weex 等),接着由微信牵头的以多过程 WebView、容器标准化的小程序计划入世,各平台小程序随之春笋萌生,随后带来了国内 Taro、uni-app、Rax、Remax 等多端框架的百家争鸣。
从业务角度登程,跨端技术演进更多是在不同阶段、不同时间段内业务效率上的抉择,美团民宿业务就是在大前端交融的浪潮中逐浪前行,一直摸索和迭代抉择,为解决业务痛点而孵化出跨端框架技术。本文次要分享美团民宿在跨端复用技术摸索层面以及业务实际过程中积攒的教训,心愿能给大家带来一些帮忙或者启发。
1. 背景
1.1 美团民宿业务介绍
美团民宿专一为消费者提供“住得不一样”的寄居体验,提供的服务包含民宿、酒店、公寓、客栈、短租、宾馆、旅行住宿等,同时包含树屋、房车、INS 风等离奇的网红民宿。美团民宿自上线之后,业务倒退迅猛,在供应侧,房源类型不断丰富,各类分销、直销、直连、境外陆续推出,房源信息维度一直扩大,筛选、举荐、信息出现也一直变得复杂。同时随同着营销形式的丰盛、房东治理、经营、服务的一直裁减,民宿的业务也越来越简单。美团民宿大前端随同业务的倒退一直自我迭代,挪动端整体架构也随之一直调整、降级,以寻求匹配业务多样化、复杂化的倒退诉求。
1.2 美团民宿挪动端现状
业务的倒退和跨端复用技术的一直演变,让美团民宿客户端从业务刚起步的单端 Native App,到跨 App(民宿 App、美团 App、点评 App)的 Native 复用和以 SSR 补救性能差距的 Hybrid 的联合计划,在这场性能和效率的博弈中,客户端最终落脚以 React Native(以下简称 RN)为外围的复用框架。在此同时,民宿小程序端也随着微信小程序的诞生、生态壮大、多平台化的趋势一直成长,逐步造成多平台复用的小程序架构。
上图是美团民宿挪动端原始架构图,左侧是客户端的技术架构,iOS 和 Android 零碎层之上是独立的 Native 基建层,再往上通过了 RN 关上双端的复用之门,接着以 RN 容器标准化屏蔽了宿主利用间差别,保障了容器化的一致性,进而实现了业务层的复用和跨 App 的复用。右侧是民宿小程序以后简化的架构图,咱们在基建层做了多端适配,通过多平台复用构建工具实现了各平台小程序的复用。以后客户端和小程端相干独立,开发保护也互相独立,团队各司其职。
只管美团民宿 App 曾经通过 RN 实现 iOS 和 Android 的跨端复用,然而因为 App 和小程序依然须要投入双倍的人力老本进行业务迭代,所以咱们思考一个问题:是否能够更进一步,应用一套代码解决多端,把 iOS App、Android App、小程序进行大一统。
2. 美团民宿跨端复用框架设计
2.1 行业现状
近几年,在微信小程序产品牵头下,业界也随之诞生出各种小程序利用,各端技术差别使得开发和保护老本都成倍增加。为了抹平原生开发、小程序开发、Web 开发等技术差别,一些优良多端框架也就此诞生了。比方 Taro、uni-app、Rax、Remax 等,这些框架都是以本身定义 DSL(个别是 React DSL、Vue DSL)转换成各端利用(微信小程序、RN、H5 等),从而实现一套代码,多端运行。
在美团民宿业务中,App 的交易占比拟大,从业务角度登程需优先保障 App 的性能体验和需要开发效率,而以后的民宿 App 已迁徙至 RN 技术栈。基于这两点,咱们心愿跨端复用计划的是:RN 转到小程序平台计划,所以上述的多端框架并不能满足咱们的 RN- 小程序跨端复用的诉求,为此美团民宿参考了业界多端设计方案,实现了基于 RN 转小程序复用的计划。
RN 采纳的是 React 语法,因而如何将 RN 转换为小程序,首先要思考如何将 React 代码转换成小程序可运行的代码(简称小程序代码),其次是 RN 根底组件库的适配。随着这几年的倒退,React 代码转换成小程序代码在业界实际也是层出不穷,业界计划分为编译时与运行时两类,以下是这两类计划的简略比照:
框架分类 | 重编译 | 重运行 |
---|---|---|
典型代表 | Taro2.0 / Rax 编译时 | Taro Next / Remax |
原理 | 编译时将 React 代码间接转换成小程序代码 | 运行是通过 React 自定义渲染器实现页面绘制 |
劣势 | 性能损耗低 | 无语法限度 |
劣势 | 语法限度大 | 性能损耗大 |
比照来看,重编译计划有一个重大的问题:语法限度。因为大部分前端开发者们曾经对灵便的语法有肯定的依赖性,比方会应用高阶组件、在条件判断的时候写很多 return 等等,这种写法很难在编译过程被精确命中。因而,编译时计划就会制订一些语法规定来限度开发者的写法。重运行计划则没有语法限度问题,能够随便应用各种 React 个性。它的实现原理是通过 react-reconciler 实现小程序平台对应的 React 渲染器(以下简称 MP-Renderer),从而来渲染虚构 DOM 树。不过小程序没有 DOM API 能够更新界面,所以生成的虚构 DOM 树数据是通过小程序的 setData 触发渲染层的更新,在渲染层里有一个通用模板能够用来渲染这些数据。
因重编译语法限度的问题,咱们决定采纳重运行时计划来实现 RN 转小程序。但重运行计划存在性能问题,难以满足业务的要求,咱们经一直摸索后设计了对应的计划极大晋升了性能,下文会详细描述如何解决这个问题的。
2.2 整体方案设计
2.2.1 RN 与小程序复用的技术计划
整体架构分为两个局部:编译过程、运行过程。它的渲染形式与上文形容重运行时计划相似,都是通过 MP-Renderer 来解决 React 代码。上面咱们来简要剖析这两个过程:
(1) 编译过程:该阶段对 RN 源码进行肯定的转换解决,用于运行过程,编译后次要产生有以下产物:
- 编译后的 RN:通过编译后产生 RN 代码,实质上还是 React 代码。
- 适配组件库:RN 根底组件的适配库,是应用小程序自定义组件实现的。
- 通用模板:因为小程序没有像 Web 有 DOM API 操作节点操作方法,所以这里通过一个通用模板来渲染 React 渲染进去的 TreeData(页面虚构 DOM 树序列化后的 UI 数据)。
- 合并模板:次要用于性能优化的,下文会详细分析这个模板的作用。
- WXSS:将 RN 代码的 Style 转换为 WXSS,这样能够缩小页面的 TreeData 数据量,从而优化性能。
(2) 运行过程:运行过程分为逻辑层和视图层两局部。
- 逻辑层:编译后的 RN 源码蕴含 RN 业务组件和适配组件库,适配组件库是通过小程序自定义组件来进行适配。这样的形式既能够灵便应用小程序原生代码对齐 RN 组件性能,也能够晋升转换后小程序的性能,因为小程序原生代码不会产生 TreeData 数据,从而使性能上失去晋升。逻辑层有一个 MP-Renderer,实现形式和上文讲述的是一样的,RN 代码通过渲染后,便产生对应的虚构 DOM 树,虚构 DOM 树数据再通过序列化便产生对应的 TreeData(形容页面的 UI 数据)。
- 渲染层:当页面须要更新的时候,逻辑层通过 setData 将 TreeData 传输到渲染层里,TreeData 与通用模板、合并模板和对应款式联合在一起,便能够渲染出对应的 UI。
综上所述,上述整体设计与业界多端框架有点相似,然而也有不同点,次要体现在适配组件库和合并模板。适配组件库上文有解释比拟好了解,而合并模板这里可能大家还是比拟有纳闷的。其实这个合并模板内容是由编译过程的“动态编译”转换生成的,这样的解决形式是为晋升转换后的小程序性能,接下来,咱们会着重来讲述这个性能解决方案。
2.2.2 性能解决方案
重运行时计划性能损耗起因是什么?正如上文所说,重运行时计划会将所有 React 代码对应的 TreeData,再通过小程序 setData 传输到渲染层,当页面初始化或者大数据更新的话,setData 就须要传递比拟大的一个数据,因而也就会造成对应的性能问题。所以要解决这种计划的性能问题,外围就是要缩小 TreeData 数据量。
在上述 RN 转小程序计划,有提到适配组件库、款式转换等是能够起到对应性能优化作用的,它的优化原理正是通过缩小 TreeData 数据的形式。只管这些形式能够优化性能,然而在页面比较复杂的时候,TreeData 数据量依然会保留比拟大,因而优化成果并不显著。为此,咱们思考一种新的形式来进一步压缩 TreeData 的数据量,也就是前文所提到的联合动态合并树节点计划,在讲述该计划前咱们先来看下一个 RN 代码转换为 TreeData 的例子:
如上图所示,RN 代码转换后的 TreeData 是一个形容 UI 树的 JSON 数据,等同于右侧的 UI 树,将这颗树的节点进行分类,能够分为静态数据和动态数据,比方 View、Text 节点就是静态数据,而“Hello”、“World”则是动态数据。所谓静态数据,就是编译过程可预知的,因而这些数据是不是能够转换另一种模式来形容 UI 呢,从而缩小 TreeData 的数据量。答案是必定的,动态编译合并树节点正是通过这样的原理来实现的,如下流程所示:
这个计划有两个动作,别离是动态编译和合并树节点,动态编译就将 RN 代码的转换成合并模板,如上图序号 2 代码所示,合并模板的名称为“b1”,内容就是一段与 RN JSX 代码对应的 WXML 构造片段。而合并节点是将曾经动态编译的节点进行合并,如上图序号 2 至序号 3 流程所示,本来五个节点被合并到顶层的 View 节点,这个 View 节点称为合并节点,合并节点须要记录合并模板的名称和相干的动态数据,目标是为了渲染时让合并节点能够找到对应的合并模板进行渲染,通过这样合并节点后,最终生成的 TreeData,如上图序号 4 所示。能够看到 TreeData 相比之前的数据量就缩小了 60% 左右!
看到这里,是不是有同学就有疑难了,上文不是提到动态编译会有语法限度,那这里是否会有语法限度?的确,如果是齐全动态编译,是会有语法限度,而这里所说的联合动态编译是有选择性的编译,即在编译过程,首先会通过 AST 剖析节点是否静态数据,如果是的话,再转换成对应的合并模板。如果遇到不可预测的动静节点,则依照运行时计划去解决。因而,最终生成的 UI 树节点即会蕴含合并节点、也会蕴含本来的组件节点,如下图所示:
通过这样的形式,既能够保障语法无限度,又能通过编译联合的伎俩最大化优化性能。当然了这种计划也是有毛病,因为这种计划其实是用空间换性能的形式,生成的合并模板会影响会影响包大小,不过对于一些须要谋求性能的页面,这点包大小的减少是值得付出的。
为了更好地掂量解决方案对性能的晋升水平,咱们参考 Taro 官网的试验(试验内容),对优化前后以及原生和 Taro 3.0 运行后的性能指标进行采集与比拟。通过试验,统计出各框架在初始化、加载数据、加载大量数据的操作耗时,如下表所示:
操作耗时 \ 框架 | 优化前 | 优化后 | 原生 | Taro 3.0.17 |
---|---|---|---|---|
初始化(首屏渲染工夫) | 897ms | 423ms | 210ms | 675ms |
加载一般数据(20 条) | 1124ms | 198ms | 110ms | 640ms |
加载大量数据(400 条) | 5330ms | 1041ms | 470ms | 3919ms |
从上表中能够看出:性能优化后,得益于更少的渲染数据与更精简的节点树,加载数据的操作耗时比优化前缩小 80%,初始化耗时缩小了 52%。与同类型的框架 Taro 3.0 相比,也有更好的性能体现。
与原生相比,优化后性能差距显著缩小,然而因为运行时计划绝对于原生须要更多的 setData 数据开销和更简单渲染流程,所以从原理上运行时计划和原生性能差距客观存在。尽管如此,业务实际上两者差距并不会那么显著,因为在测评试验中测试数据比拟纯正,setData 数据使用率较高,但在业务实际中原生开发 setData 数据不免冗余且难以优化,而运行时计划会默认优化冗余数据使得两者性能差距更靠近,从咱们历史业务实际数据上看,性能与原生差距在 10% 左右。
3. 美团民宿跨端复用实际
在跨端复用摸索中,咱们用翻新的计划解决了性能和个性限度的难题,设计了 RN- 小程序跨端复用框架。尽管跨端复用属于“利器在手”,然而这是一把“双刃剑”,用得其所则事倍功半,处理不当则隐患丛生。那么,如何在业务实际中驾驭好这把利刃呢?咱们先介绍在业务实际中遇到的问题,而后介绍解决这些问题的计划。
3.1 跨端复用场景下的问题
- 复用场景下的问题:小程序产品状态以轻、快、便为旨,用户可疾速应用,用完即走,客户端产品绝对全、精、稳,能够满足更多的用户需要,以用户留存、用户认知、用户体验为主,两者在产品性能上存在较大的差别,如何失当地解决产品差异化问题是跨端复用的场景下的一个重要挑战。
- 跨端复用品质隐患:实现了复用便要思考两端的各种兼容性问题,这就会产生各种品质上的隐患。如何在复用组件一直迭代中,保障组件接口、输出、输入的兼容性问题?如何保障各个复用组件底层依赖的对立、适配层接口的对立?双端复用场景下,如何更好的做测试和监控?双端同学存在各自技术认知的边界,如何在呈现问题时疾速排查、及时止损?
- 跨端复用流程标准问题:新的技术反动,必然打破旧的秩序,在以后跨端复用场景下,各种包含工程治理、代码标准、分支治理、需要同步的问题也会孕育而生,同需解决。
3.2 跨端复用利用架构
为了解决跨端复用在业务实际中遇到的各种问题,咱们从新设计了跨端复用利用架构,从架构分层治理、复用形式设计、流程标准、品质保障方面动手,重点解决跨端差异化、品质隐患、流程标准各种问题,并寻求复用的最大化和性能上的平衡。
3.2.1 跨端复用利用架构演进
在这里,先贴出动静的架构演进过程,让大家有一个宏观的意识。咱们先简略地形容下演进过程,后续会基于最终的架构图再做具体的介绍。大抵演进过程如下:
- 起初,客户端分 Android App 和 iOS App 独自开发,引入 RN 技术实现了 Android 和 iOS 跨端复用,然而小程序端仍然须要独自保护迭代。
- 为了跟进一步实现 RN- 小程序跨端复用,咱们接入了自研的 RN- 小程序跨端复用框架,并基于框架的适配标准,以 RN 的基建为基准,打造出一个和 RN 基建对立接口的小程序适配层。
- 实现小程序渲染器接入(MP-Render)和小程序适配层后,React-Reconciler 这一层就能够买通到小程序侧,实现了 React 代码复用到小程序的能力。
- 实现 RN 与小程序间的复用后,就能够对存量的 RN 代码进行形象、适配、整顿,进而抽取出一个组件复用层,这个复用层可间接供下层业务层间接应用。
- 最初,为了解决跨端复用场景下各种流程、合作和品质隐患,咱们配套了相应的流程标准和品质保障措施。
3.2.2 跨端复用利用架构整体介绍
整个民宿的 RN- 小程序跨端复用架构图如上,咱们依照从下到上,从左到右的视角进行解读:
- 零碎层:最底层是零碎服务,除了 iOS 零碎和 Android 零碎外,咱们把小程序视为一个独自的零碎模块。
- 根底服务层:零碎服务之上是根底服务层,这一层次要是团体基于 Native 和小程序建设的基建,全公司通用,笼罩了研发工程中方方面面的根底服务。在此基础上,咱们在小程序基建中引入了基于 react-reconciler 实现的小程序运行时渲染器(MP-Render),这个渲染器能在运行时动静更新 vnode 以匹配编译转化的小程序 UI 模板,调用小程序原生 API,最终渲染出小程序组件,有了这个基于 React 的小程序渲染器便使得跨端复用成为可能。
- 基建层:根底服务层之上是基建层,这块次要包含 MRN 基建和小程序适配层,咱们以 MRN 的基建为规范,适配出一个统一标准和对立接口的小程序适配库,通过这一层适配,下层能够无感知、无差别地以同一规范实现复用组件。其中适配层分为 2 块,下半局部次要适配 RN 根底服务,下层是民宿业务独立封装的根底库和第三方库,这块咱们独自引入一个名为 Mapping 的适配库。一个独立的适配库能够让 RN 和小程序在业务迭代和技术改革过程中互相独立,互不烦扰,如此就能保障技术的推动齐全不会影响业务的迭代。基建层的最上方是 react-reconciler,React 框架自身就是把协调过程和渲染过程离开的,react-reconciler 是实现跨端复用的外围,所以咱们把它独自展现进去,它真正买通了客户端和小程序的隔膜,只有有了一个独立的小程序渲染器,就能够全面、无限度的把 React 代码复用到小程序。
- 复用层:基建层再往上是复用层,复用层次要以组件维度做复用,复用组件是基于存量 RN 组件做形象和适配,而后抽取独立进去,复用层的组件以对立的规范和接口供下层业务应用。复用层是很重要的一块,好的复用机制能帮忙咱们解决后面提到的产品差异化问题和复用最大化问题。这块咱们独自放到
3.3 跨端复用形式设计
来具体解说。 - 业务层:复用层之上就是业务层,业务层的各模块次要以页面容器来承接复用组件,基于不同的端和产品差别,能够灵便、动静配置页面的组件来称心业务的差异化需要。
3.3 跨端复用形式设计
差异化问题,始终是跨端复用场景中的一个痛点,双端的产品上、平台上、代码上的差别如何妥善的解决、适配,也是咱们始终思考的问题。而好的差异化解决计划能够晋升代码的可维护性、升高品质隐患、晋升开发效率。咱们从复用设计层面登程,摸索出页面复用模式、组件复用模式、“组件 + 逻辑复用”模式等三种复用设计形式,并且依据不同的场景下采纳不同的复用模式,能够较好地解决跨端差异化问题,同时能兼顾效率晋升、性能体验和可维护性。
3.3.1 差异化下的复用形式
咱们自研的复用框架提供两种复用模式,如下图所示:
页面复用模式 :页面模式基于页面维度的,能够间接把页面的网络层、逻辑层、数据层以及页面内的组件集全副转换复用,这样能够达到复用的最大化,代码复用率能达到 90% 以上,人效晋升显著。
组件复用模式:组件模式是基于组件维度的,复用以页面中的业务组件为指标,把页面的所有组件形象、解耦、规范化之后抽取为复用组件。组件模式只能复用组件内代码,对于页面容器的逻辑交互、网络层都须要小程序本人实现,代码复用率绝对较低,然而组件复用更灵便、可控,可随便插拔、拼接、定制。
以下是两种复用模式的优劣剖析。
页面复用模式
劣势
1) 提效显著:整个页面包含所有组件、页面逻辑层网络层一并打包转换复用,代码复用率极高,开发效率晋升幅度更大。
2) 接入成本低:整个页面间接转化同步复用,无需小程序同学帮助接入,缩小双端帮助、接口沟通带来的出错危险。
劣势
1) 灵活性低:业务差别和小程序个性不易解决,双端差别适配只能在 RN 上做,代码易出错,保护老本高。
2) 性能劣势:整体页面由 RN 转换复用而来,页面一次性渲染,性能上会略差一些,而且做页面级的性能优化艰难。
3) 包大小危险大:整页复用状况下包大小较大,且不能动静调配(比方页面内某一模块需要迭代较少,不想复用,然而页面模式做不到动静移除)。
组件复用模式
劣势
1) 轻便灵便:组件如插件般可随便插拔、拼接、定制,可较好解决 App 和小程序双端的差异性问题,针对差别点双端能够独立实现,进步我的项目的可维护性。
2) 性能较好:页面容器仍然是小程序原生组件,如滚动、滑动组件采纳原生可缩小性能损耗,另外组件分布式 setData 渲染有更好的性能,不会像整页一次性渲染导致 setData 数据量较大影响首屏加载性能。
3) 性能优化空间大:不会影响做页面维度的性能优化(如首屏优先、申请前置)。
4) 包大小可控:组件是否复用能够动静调配,比方把页面中迭代较少的组件不复用以缩小包大小。
劣势
1) 提效无限:组件模式只能复用组件内的代码,代码复用率较低,页面容器、逻辑层、网络层小程序仍然要本人保护一份代码。
2) 复用组件保护老本高:组件的接口要思考组件降级迭代的兼容性、可维护性问题,治理不当,容易产生品质隐患。
3) 接入老本较高:小程序须要实现 RN 的页面逻辑,而后依照组件接口进行接入,有更高的接入老本。
两组复用模式各有利弊,页面模式复用率高,然而灵活性低、性能欠佳;组件模式轻便灵便,性能可控,能较好的解决平台差异化问,然而复用率低、保护老本高。咱们在想有没有一种计划能保留组件模式的灵活性,又能升高组件保护老本、进步复用水平。在业务实际中,咱们摸索出一套“组件 + 逻辑复用”的模式,能够较好地解决下面提到的问题。
3.3.2 差异化下的逻辑复用
“组件 + 逻辑复用”模式仍然保留组件复用的形式,然而在组件复用根底上减少了逻辑层(包含页面逻辑、网络、数据层)的复用,这样保留了组件灵活性,也减少了复用性。具体设计如下图:
整个组件 + 逻辑复用模式设计图如上,咱们依照图片标注的序号进行一一解读:
1) 逻辑复用接口实例 :在小程序的页面容器中,通过注入的形式获取逻辑层复用的接口实例,通过这个实例便能够调用接口实现获取、更改、监听 Redux 的状态,本质上就达到了逻辑复用的成果。
2) 页面复用组件集 :页面能够自在应用复用组件,复用组件可大可小,能够尽管拼装布局,保留了组件模式良好的灵活性。
3) 小程序原生组件 :页面既能够应用复用组件,也能够用小程序原生组件来实现小程序差异化的性能和个性,这样能较好的解决双端差异性。小程序原生组件能够通过 逻辑复用接口实例 来调用逻辑层性能,进而达到逻辑复用的成果。
4) 弹窗复用组件 :弹窗复用组件和页面复用组件同理,这边次要阐明能够依照各类维度把复用组件分类,进而更好的做复用组件治理。
5) 复用组件库 :复用组件库的复用组件可多可少,可大可小,如果页面双端差异性小,一个大组件即可满足。每个复用组件集外层包一层 Reudx-Provider 并设置雷同的 Store,便能够和逻辑层主动绑定上。因为 RN 组件自身就是基于 Redux 的,所以复用过程绝对容易。
6) 业务逻辑层 :最右侧的业务逻辑层能够简略了解成 3 块,一块是基于 Redux Store 的数据层,这里寄存整个页面模块所有的数据和操作、监听数据的接口,一块是蕴含页面内所有网络申请的网络层,另外就是用来流转状态和解决复用的 Reducer、Redux-Saga,以及配套的各种工具类。业务逻辑层能够依据双端的差别把 Reducer 与 Saga 分拆更小的单元实现差异化的逻辑复用,晋升逻辑复用层的代码可维护性。
7) 封装复用接口 :业务逻辑层蕴含整个页面的业务逻辑,只有针对性凋谢接口给小程序,让小程序可能获取、更改、监听 Redux 的状态,那本质上就达到了逻辑复用的成果。凋谢接口给小程序有 2 种形式:逻辑 API 接口 和 Store。
8) 逻辑 API 接口:基于 Store 给小程序提供小程序真正须要的逻辑 API 接口,通过这些 API 小程序能够来获取数据来渲染 UI(如:渲染没有复用的组件),也能够更新数据,也能监听复用组件外部的数据变动。
9) Store:把 Redux Store 裸露进来,小程序便利用 Store 实例能够通过 getState、dispatch、subscribe 来操作、监听状态机了,也就达到逻辑层复用的目标了。
这种计划的劣势很显著,它保留组件模式的灵便个性,能够比拟不便做差异化解决和性能优化。而逻辑复用层把 Redux 蕴含进来了,这样不仅转化容易、不易出错,而且逻辑复用接口基于 Redux 的 Store,接口较好设计,容易保护、不易出错。而对于逻辑层,能够依据业务上一些差别做 Reducer 与 Saga 分拆,把不须要复用的代码逻辑排查在外,逻辑层复用也能够做到像组件一样热插拔,按需引入,这样也比拟好做差异化代码治理,挺高我的项目的可维护性,同时也能优先缩小包大小危险。
3.4 跨端复用流程标准
为在代码跨端复用过程中尽可能晋升开发效率并防止引入品质问题,咱们制订了差异化编码标准、需要同步标准、复用组件标准等开发流程标准,以下将通过 RN 到小程序产品需要同步过程进行简略的介绍。
1. 评估业务需要是否须要同步
针对 PM 提出须要同步的需要,客户端尽量将 RN 业务代码复用至小程序,以晋升开发效率。无需同步的需要将通过差别编码标准进行管制,防止同步至小程序后减少潜在危险与测试老本。通常可应用平台判断(如 iOS、Android、WX_Platform)的形式管制业务代码是否打入复用组件包,也可通过 module.rn.js、module.wx.js 不同后缀文件形式实现雷同接口不同逻辑的实现。
2. 评估是否有关联依赖需要
如明确业务需要须要同步,先判断该需要是否有前置需要依赖,再评估技术计划。如无依赖可间接开始复用适配工作;如有依赖,需判断前置需要是否一起同步或做适当降级,以此递推,防止因前置依赖需要未同步呈现不合乎预期的问题。
3. 制订 RN 组件适配与小程序接入计划
明确需要同步范畴评估工作后,需实现以下技术评估工作:(1)明确需要是否须要新建复用组件还是在原有的复用组件上进行迭代。如需新建复用组件 NPM 包,需依据组件复用标准进行技术选型,确定应用“组件 + 逻辑复用模式”、“页面模式”还是“组件模式”,并制订相应的复用组件接口协议;(2)明确该需要是否须要开发 RN- 小程序映射办法、组件,并评估相应的开发量。实现技术评估后需提前与小程序侧沟通接入排期。
4. RN 组件适配开发
客户端实现 RN 侧需要开发后,便可进行复用组件适配小程序开发。实现适配开发工作后需在 RN 页面与小程序 Demo 页面中对复用组件同时进行测试,防止在适配小程序过程中引入 RN 页面 Bug。复用组件测试结束后将 NPM 包以及相应的接口文档提供给小程序接入,但在打包前需严格审查以后版本与上个版本间的 diff,防止不合乎预期的代码也被同步至小程序。
5. 小程序接入 RN 适配组件
适配实现后将组件打包提供给小程序侧接入,接入后需在美团民宿小程序环境下再次进行自测。原则上客户端同学提供适配好的 RN 组件后,由小程序侧同学接入并测试,但咱们也激励客户端在实现 RN 组件开发与复用适配后,一并实现小程序侧的组件接入工作,这样需要开发残缺度更高,并能无效缩小跨端开发下的沟通老本。后续随着大前端交融推动,RN- 小程序代码复用率将逐渐晋升,客户端(iOS、Android)与 小程序代码将偏向由一名同学实现多端开发。
6. RN 适配代码合入迭代分支
需要在小程序测试结束后,将 RN 组件适配 Feature 分支代码合入 Release 迭代分支,并在客户端(iOS、Android)打包上线。
3.5 跨端复用品质保障
跨端复用场景下存在包含复用组件接口兼容性问题、组件间的依赖隐患问题、测试和监控的缺失问题,以及故障排查艰难等各种品质隐患,咱们在业务实际中,也摸索出一系列解决这些隐患的品质保障措施,包含组件接口保护、组件依赖治理、双重自测卡控、异样监控交融、双端故障 SOP、跨端复用流程标准。这些措施能无效保障复用场景下双端的线上品质,民宿业务在跨端复用推动中,因为这些措施的保障护航,没有呈现任何的线上故障。
1. 组件接口保护
复用组件随着业务迭代会不断更新降级,组件降级过程中便会带来的组件接口、输出、输入的变动,进而产生兼容性隐患,比方组件输出参数类型变动,而小程序端或 RN 端没有及时兼容或者未通晓,非常容易引发线上品质问题。为此,咱们制订了组件接口保护打算,包含复用组件接口标准、组件版本治理标准、组件接口文档建设等。复用组件接口标准要求复用组件接口、参数必须严格依照标准来,如参数类型应用根底类型、只增少减准则、接口命名清晰、参数个数限度等等,缩小双端的接入组件难度,防止参数频繁变动产生品质隐患。组件版本治理标准要求组件版本升级必须遵循語意化 2.0,并且有相应的版本升级文档。组件接口文档建设也是很重要的一环,每个复用组件都有相应的文档保护,记录参数的增删改查,接入方对组件接口变动高深莫测,天然缩小了接入危险。
2. 组件依赖治理
组件依赖次要存在两个问题,第一,复用框架自身也在一直降级优化、新的复用组件可能用新的编译版本转化而来并且依赖新的运行时渲染器,然而旧的复用组件可能会呈现不兼容问题,因而咱们开发相干的工具,如果组件依赖的运行时渲染器版本和小程序内置的不统一就会收回正告,提醒组件兼容性问题。第二,因为不同的复用组件来自不同的 RN 模块,它们可能依赖不同版本的第三方库,容易产生版本不统一的品质问题。目前的解决方案是把这些依赖库别离打入各自的包里,这样复用组件间依赖互相独立,互不影响。再联合 Tree-Sharking 的优化,打入的依赖的实在包大小并不大,用小量的包大小换取更持重的质量保证。
3. 双重自测卡控
在跨端复用场景下,一个复用模块的改变要思考双端兼容和新旧版兼容问题,相比与之前有更高的出错危险,更全面的自测能帮咱们尽早裸露问题,缩小故障危险。所以咱们在 App 侧和小程序侧做了代码自测覆盖率卡控,要求改变代码执行覆盖率超过 90% 能力提测和上线。复用组件既在 RN 侧自测过一遍,在小程序接入后又强制要求再自测一遍,双重自测卡控更能保障组件品质和线上品质。
4. 异样监控交融
RN 和小程序侧都有独自的异样监控机制,包含 JS 异样监控、API 异样监控、自定义异样监控等。然而双端的异样监控机制差异较大,在复用场景下两者穿插混用导致异样监控体系凌乱,上报数据格式、策略、日志不对立而造成监控体系误告、漏告、排查艰难、运维凌乱等问题。所以咱们把双端的异样监控模块买通,适配了底层异样上报逻辑,对立了双端的上报标准,告警策略、日志、解决流程。异样监控体系双端交融后,异样上报、监控、运维都顺畅许多,也帮咱们发现不少的线上异样,是 RN- 小程序跨端复用场景线上品质的坚硬屏障。
5. 双端故障 SOP
鉴于双端同学存在技术上的隔膜和信息不对称,当呈现复用组件的故障或异样时,如何疾速排查问题成为一个痛点,小程序的谬误日志 RN 同学不相熟,小程序同学不相熟 RN 的业务代码实现,框架层面的谬误更难排查。为此,咱们整体了梳理双端故障 SOP,这外面包含常见日志剖析帮忙甄别是复用组件、小程序端、底层复用框架的问题和相应的解决方案,同时开发了 Source Map 谬误反解工具帮助 RN 同学反解小程序日志帮忙疾速排错等等。这些 SOP 和工具可能在第一工夫帮忙双端同学自主或帮助排查相干故障,疾速止损。
6. 跨端复用流程标准
流程标准包含后面提到的复用组件标准、编码标准、需要同步标准、分支治理标准等等也是品质保障的重要的一环,它让研发流水线每一环都有严格的法律束缚,保障整条研发流水线最终能把残缺的产品交付到用户手里。
3.6 成绩
RN- 小程序跨端复用的设计方案在业务实际中不断完善,摸索出效率绝对最大化的复用模式。从开发效率角度来看,晋升显著。咱们总结了代码复用率与人效晋升率来评估效率的晋升,两个指标具体计算公式如下:
- 代码复用率:∑(RN 复用模块代码行数 - 模块中 RN 与小程序平台分支判断代码行数) / ∑(RN 代码总行数 + 小程序原生代码行数);其中,RN 复用模块代码行数是依据框架转换生成的组件来确定。
- 人效晋升率:∑(RN 开发耗时 + 小程序开发耗时 – (RN 开发耗时 + 转换适配耗时)) / ∑(RN 开发耗时 + 小程序开发耗时);复用前须要 RN 与小程序侧两端的开发耗时,复用后只须要 RN 开发与复用组件转换适配的耗时,依据复用前后的耗时能够得出人效晋升率公式。
依据转换采纳的模式不同,能够得出代码复用率与人效晋升率,如下表所示:
转换模式 | 代码复用率 | 人效晋升率 |
---|---|---|
组件 + 逻辑复用模式 | 76% | 42.36% |
页面复用模式 | 91% | 46.71% |
从表中能够看出,页面转换模式复用了页面与组件的代码,代码复用率能够达到 90% 以上;组件复用模式复用了组件与局部业务逻辑代码,复用率也能够达到 76%。在人效晋升方面,所有模式都能达到较高的人效晋升率,代码复用率越高人效晋升率也越高,页面转换模式能够复用页面与数据状态解决逻辑人效晋升比组件转换模式更高。
4. 总结
民宿大前端团队为解双端研发效率之痛,倾力而寻跨端之技,浅尝百草、深谙其理而后自建之,举偏补弊、终解跨端框架性能之枷锁,青出蓝而胜于蓝。而后践于实业,瑕弊昭然若揭。为此,重设框架以谋其变(复用架构设计),寻之旧式以尽其效(复用模式设计),立之新法以固其序(跨端复用流程标准),磨之利器以护其城(跨端复用品质保障),至此成绩初成。然朝夕变动不休,路漫远兮,吾当持之求索以适其变、顺其道。跨端复用前行之鉴,故记以文,望有启发,文毕。
作者简介
凯林、森伟、熙辰、戈弋、少元等,均为美团民宿前端团队研发工程师。
招聘信息
美团民宿长期招聘 Android、iOS、FE 前端工程师,坐标在福建厦门。感兴趣的同学可将简历发送至:tech@meituan.com(邮件主题请注明:美团民宿大前端)。
浏览美团技术团队更多技术文章合集
前端 | 算法 | 后端 | 数据 | 平安 | 运维 | iOS | Android | 测试
| 在公众号菜单栏对话框回复【2020 年货】、【2019 年货】、【2018 年货】、【2017 年货】等关键词,可查看美团技术团队历年技术文章合集。
| 本文系美团技术团队出品,著作权归属美团。欢送出于分享和交换等非商业目标转载或应用本文内容,敬请注明“内容转载自美团技术团队”。本文未经许可,不得进行商业性转载或者应用。任何商用行为,请发送邮件至 tech@meituan.com 申请受权。