【锁定直播】字节、华为云、阿里云等技术专家讨论如何将大模型接入 AIOps 解决实际问题,戳>>> 了解详情
写点什么

React Native 优先的多端统一化方案

  • 2020-12-27
  • 本文字数:3096 字

    阅读完需:约 10 分钟

React Native 优先的多端统一化方案

一、方案背景


长期以来 APP、H5、小程序等各个端的定位和发展历程都不一样,各端技术栈差异性也较大,基于成本和效率考虑并不追求各端一致性,结果就是各端真的就渐行渐远了。


移动端增量红利越来越少的情况下,产品这边逐渐追求各端的产品体验一致性,多端同时上的需求越来越多,但是由于技术上割裂较大,工时基本都会按端加倍,开发成本奇高,迫切的需要一套减少多端开发成本的方案。


二、方案调研


开始之前我们对业界现有的一些跨端方案进行了简单的调研和了解。



通过对比目前的多端开发主要有以下几个大方向:


  1. 对 IOS 和 ADR 的 native 端 APP 的适配

  2. 中国特色的针对各小程序平台的适配

  3. 都希望可以兼顾到对 H5 的转换


而实现方向上看起来五花八门,但总体思路上主要还是两个大方向:


  1. 提供自定义 DSL 静态编译转化成目标源代码(运行体验好)

  2. 运行时适配兼容(开发体验好)


这两种方式的优缺点都非常明显(相关框架和方案对比文章都较多,可自行详细了解)。目前社区基本都想在运行上努力,开发当然要自己爽啊,实际体验下来除了在微信小程序上性能问题较大之外,也没啥大毛病。


taro 作为较早的多端方案,适配性和兼容性都不错,自定义 DSL,JSX 由于其转译复杂性限制也较多。


taro-next 和 remax 都是运行时适配的方案,而 remax 的口号是 “使用真正的 react 构建小程序” (好好体会,后面要考)。


Chameleon 是号称兼容性和运行效率上都比较高的,编译和运行时适配的技术都用到了,不过由于他是支持的 weex 就没做深入尝试了。


其他像 alita,KBone,react-native-web 都在自己的小领域内能较好的运行。


三、方案介绍


1、解决思路


调研完发现上面的方案其实并不能很好的直接解决我们的问题:


Qunar 整体技术栈以 react 为主,几年前已将 APP 整体迁移到 RN 技术栈上,解决了 IOS 和 ADR 的 2 端问题。APP 的体验和开发是最重要的,不能为了多端用新的 DSL 语法来限制对 RN 技术的使用,降低 RN 的性能和开发体验。基于现状,其实我们想要的是:能直接将 RN 转换到 H5 和各小程序平台的多端方案,可惜没有。


不能直接找到一次将 RN 运行到多端的方案,其实如果能分别解决 RN 到 H5 和 RN 到小程序的问题也是能达到目标的,分析前面的跨端方案还是有一定可行性的。



2、RN 到 H5


react-native-web 是 Twitter 开源的可将 RN 代码运行在 H5 上的方案,而且他们 H5 端的官网就是直接用 RN 转出来的,自信到连自己主站都敢用的方案肯定是要尝试一下的,于是出去看了下线上效果:



发现保真度和体验还可以,对该方案的实现原理进行了解之后,觉得 H5 可行,后续到小程序的方案也深受启发。


3、react-native-web 原理


先看一行 RN 代码:



再看 react-native-web 的源代码:



使用方式:



他的方案其实挺简单粗暴的,把 RN 的组件和 API 都用 H5 实现适配一遍,适配其行为和默认样式,在打包的时候使用 webpack 的别名机制将用到的组件替换成 react-native-web 里的对应组件。


简单的方案实现起来工作量还是挺大的,所以 react-native-web 里也大量的直接使用了 react-native 的源代码,谁让他们都是 JS 呢。


既然到 H5 可以这么简单粗暴,那到小程序是否可以呢?


4、RN 到小程序


我们知道小程序都有一套自己的 DSL 语言,而且与常规前端不同的是他将逻辑层和视图层完全隔离在了两个线程里,两边数据和对象都不共享,只能通过 Native 层来传递数据通讯。


RN 广义上来说也是一样的双线程机制,不过 RN 的渲染是用的 native,小程序用的是 webkit。


RN 是完全基于 React 语言的,比小程序的 DSL 要灵活复杂得多,要把 React 语法和 JSX 编译成一个子集的话困难性还是很大的。


这个时候我们想到了 remax:使用真正的 react 构建小程序。


如果我们像 react-native-web 一样,把 react-native 组件用 remax 来实现一遍,是不是就可以将 RN 运行到小程序上了呢?


5、remax 实现原理


这部分网上有详细的原理介绍,这里只简单说一下:


react 在内部做完 VirtualDOM 的更新后最终都要调用宿主环境的更新方法(add remove)来更新界面,为了更好地对接各个平台 react 提供了 react-reconciler 库来传入真正宿主元素的更新方法(HostConfig)。基于这个库可以方便的实现出 ReactDOM、RN 等 react 渲染层。remax 就是基于该组件实现的一个 react 的渲染层,不过小程序里不能直接去更新界面,所以 reamx 会把更新收集起来,然后生成一个更新数据通过小程序的 setData 触发渲染层的更新。然后在小程序渲染层实现一个通用模板来渲染这些数据。


这个方案带来的好处和缺点,在微信小程序里的性能限制下面 remax 和 taro next 的原理介绍里都讲得很透彻,这里就不在复述了。


remax 原理介绍:


https://juejin.im/post/6844904131157557262


taro next 也采用了类似的原理:


https://juejin.im/post/6844904036743774216


6、RN 到小程序组件库


基本原理同 react-natvie-web,只不过在对 RN 组件的具体实现上采用直接使用对接到 remax 组件上的方式。看代码例子的话目录结构等是不是都和 react-native-web 很像。



四、最终多端方案


最终经过调研和尝试,我们选择了按平台用不同的方案进行转换的方案:


  1. H5 上直接用 react-native-web 进行转换

  2. 到小程序端使用 reamx 组件实现一套 RN 的组件库,借用 remax 来适配到多端

  3. 借助 webpack 的特性来实现针对不同平台的打包




qrn-mirror 就是前面提到的针对 RN 组件到小程序的组件适配库,使用 remax 实现。


我们的主要工作量集中在 qrn-mirror 层对 RN 组件的适配,借助现有开源方案小成本的实现了这个事情。


当然在实现小程序组件的时候我们才理解 remax 只说了 “使用真正的 react 构建小程序” , 从来没说过支持多端一致的,这差别你体会体会……不过幸运的是 remax 确实也通过 remax/one 提供了多个多端兼容的基础组件。当然我们最终还是选择继续使用 remax 来开发了组件库,谁让他是完整支持 react 的呢,另一个我们也不追求一次把所有小程序端都适配了。


五、多端动态方案


前面实现了将 RN 代码在多端运行的机制,但是在实际迁移中并不是所有的 RN 特性小程序和 H5 都能支持,产品和交互本身也有差异,这时候还是需要对各端做差异化和降级的。


如何做到多态其实 webpack 都已经替我们做好了,我们只需要用和定好规范就好了。


1、文件内小范围的多态


借助 webpack 的 tree shaking 和 webpack.DefinePlugin 插件,可实现按端执行逻辑且不出现冗余代码。



2、文件组件级别的多态


受益于 react 良好的组件化机制,只要我们按文件导出同样 API 的 react 组件,可以无缝的针对多端做替换。remax 也能做到自动识别小程序的原生组件。而我们只需要根据平台动态修改 webpack 查找文件后缀的优先级顺序就好了。



最终打包时在 H5 端使用 index.web.js 内导出的兼容组件,其他端用 index.js 里导出的组件。


六、效果展示


最终我们实现了一个开发工具,在规范 RN 工程目录结构的情况下可以一键转换出 H5 和小程序的版本。目前已经在低价机票,机票订单详情,公共订单列表等项目中进行了应用。后续也希望在主流程和更多新项目中直接使用。



七、后续计划


这次我们只分享了整个方案的大致思路,后续会逐步分享一些我们在实践过程中踩的一些坑和应对方案。


  1. 第三方不侵入打包过程介绍

  2. 和 nanachi 的环境整合方案

  3. react,react-native-web, remax 的版本对应和锁定问题

  4. 小程序不支持全局 global 对象的问题

  5. 小程序中 RN 动画解决方案

  6. 小程序中的渲染性能优化

  7. stylesheet 样式解决方案

  8. 多平台工程的工程结构限制

  9. 库 Size 大小分析优化过程和解决方案



头图:Unsplash

作者:冯地木

原文React Native 优先的多端统一化方案

来源:Qunar 技术沙龙 - 微信公众号 [ID:QunarTL]

转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2020-12-27 22:372867

评论

发布
暂无评论
发现更多内容

TSBS 是什么?为什么时序数据库 TDengine 会选择它作为性能对比测试平台?

TDengine

性能测试 时序数据库 ​TDengine

从计费出账加速的设计谈周期性业务的优化思考

鲸品堂

运营商 业务流程优化 企业号 3 月 PK 榜

ChunJun 1.16 Release版本即将发布,bug 捉虫活动邀您参与!

袋鼠云数栈

假如面试官要你手写一个promise

helloworld1024fd

JavaScript 前端

山东大学数字图像处理实验:MATLAB的图像显示方法

timerring

数字图像处理

重磅福利!阿里云机器学习平台PAI+AI开源项目测评来啦

阿里云大数据AI技术

AI

CutLER:更好地训练无监督识别模型

Zilliz

应用模型开发指南上新介绍

HarmonyOS开发者

HarmonyOS

轻量易部署!Coolbpf 发布不依赖 Clang 的脚本化编程特性 lwcb | 龙蜥技术

OpenAnolis小助手

开源 rust ebpf coolbpf lwcb

推荐系统[四]:精排-详解排序算法LTR (Learning to Rank)_ poitwise, pairwise, listwise相关评价指标,超详细知识指南。

汀丶人工智能

自然语言处理 推荐系统 搜索算法

Operator-sdk 在 KaiwuDB 容器云中的使用

KaiwuDB

operator-sdk KaiwuDB

云原生可观察性工具泛滥的思考

HummerCloud

云原生 可观察性

ChatGPT 爆火,社交应用如何 Get 新技能

融云 RongCloud

IM ChatGPT

MASA MAUI Plugin (九)Android相册多选照片(使用Android Jetpack套件库)

MASA技术团队

.net MASA MAUI

还不知道线程池的好处,快来了解一下

华为云开发者联盟

开发 华为云 华为云开发者联盟 企业号 3 月 PK 榜

Switchquery:移动端秒级配置触达平台

京东科技开发者

App 配置原理 用户触达 企业号 3 月 PK 榜

如何使用C LinkSDK(4.x)快速接入阿里云物联网平台?——实践类

阿里云AIoT

阿里云 物联网 IoT

【明晚直播】KunlunBase 1.1 版本发布:完善MySQL 兼容性,OLAP性能提升

KunlunBase昆仑数据库

MySQL 数据库 PgSQL 线上直播

走进RocketMQ(三)消息存储与消费

白裤

Java RocketMQ RocketMQ消息存储 RocketMQ消息消费

开发者体验:现代企业架构的关键一环

SEAL安全

平台工程 企业号 3 月 PK 榜 开发者体验

不要因为这件小事,让你的网站在危险中“狂飙”

嘉为蓝鲸

自动化运维 weops 嘉为蓝鲸

网络性能总不好?网络调优专家AOE帮你来“看看”

华为云开发者联盟

人工智能 华为云 网络性能 华为云开发者联盟 企业号 3 月 PK 榜

从一次CPU打满到ReDos攻击和防范

京东科技开发者

正则表达式 Web 企业号 3 月 PK 榜 ReDoS

基于头肩部检测的过线客流统计

华为云开发者联盟

人工智能 华为云 华为云开发者联盟 企业号 3 月 PK 榜

基于大规模边缘计算的千万级聊天室技术实践

环信

聊天室 大规模边缘计算 千万级

可观测指标管理体系建设落地及插件功能设计和生态打造

嘉为蓝鲸

可观测 自动化运维 嘉为蓝鲸

直播 | StarRocks 实战系列第三期--StarRocks 运维的那些事

StarRocks

数据库 开源 运维

LED广告宣传车与LED流动舞台车的区别

Dylan

广告 LED 户外LED显示屏

企业号 3 月 PK 榜,火热开启!

InfoQ写作社区官方

热门活动 企业号 3 月 PK 榜

干货 | 中小型金融企业该如何进行灾备建设?

嘉为蓝鲸

金融 自动化运维 嘉为蓝鲸 灾备建设

顶层设计出台 浪潮云破局再生长丨与千行百业扬帆数字蓝海

浪潮云

云计算

React Native 优先的多端统一化方案_语言 & 开发_Qunar技术沙龙_InfoQ精选文章