目前主流跨端开发技术一览

关键词:React Native, uniapp, Flutter ,Tauri, Ionic 和 weex

前言

去年在一些社交网站上,随着 RN 和 WEEX 等动态页面技术的火热兴起,业态大量的声音都在表达着一个观点:多端一致性,多端复用性。无论是 write once,run anywhere,还是 learn once,write anywhere ,不断的在从成本的角度去吸引开发者和企业的关注,业内的开发者们开始有一种担忧:是不是我作为一名客户端开发工程师要失业了。有一段时间里,脉脉的匿名区大量充斥着 iOS 工程师找不到工作的悲观言论。

直到后来,Apple 跳出来撸了一把高调的 JSPatch,侧面敲击了 RN,大家都开心的表示还是 Apple 心疼自己 —— 我们不去过嘴瘾争论这些业内的口水,这个文章我们聚焦到客户端工程师这一个行业来看一些问题,在讲客户端工程师发展之前,我们一起回顾下这几年移动端开发的经历。

结论

先说结论,RN,Flutter,uniapp各有优劣,还是看你是什么类型的应用,你的团队成员技术栈。

几种常见跨端技术对比

在这里插入图片描述

RN, 要求开发者学习React,要求精通Flex布局,要求原生开发协作。

Flutter,要求开发者学习Dart,了解Dart和Flutter的API、要求精通Flex布局,要求原生开发协作。

Weex,已经内嵌到uni-app中,就不单独提了。

uni-app,要求开发者学习Vue,了解小程序。

在这里插入图片描述

加快ReactNative开发的Expo

Expo是解决什么问题的?是为跨平台服务的,就是你只管写纯JS的应用,它帮你构建部署到手机上,Android或iOS。它需要在你手机上安装一个应用Expo Go,然后你开发的Expo应用就被Expo Go托管,就像小程序和微信的关系。

Expo is an open-source platform for making universal native apps that run on Android, iOS, and the web. It includes a universal runtime and libraries that let you build native apps by writing React and JavaScript.

Expo包含一个命令行工具Expo CLI和一个移动客户端Expo Go。在开发机器上,你只需要按照Nodejs环境即可,无需Android SDK和xcode这些编译环境。

在这里插入图片描述
Expo Go只是给开发阶段用的,最后要发布产品时还得用Expo提供的工具打成apk和ipa包。

你可以在https://snack.expo.dev/上试用一下简单的例子。

Taro

Taro 是一套遵循 React 语法规范的多端开发解决方案。Taro 是一个开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发 微信 / 京东 / 百度 / 支付宝 / 字节跳动 / QQ / 飞书 小程序 / H5 / RN 等应用。
Taro 和 uni-app一样是多端开发框架。Taro基于React技术栈,京东主导,uni-app基于vue技术栈,DCloud主导。但Taro 3同时支持了React 和 Vue两种DSL。

uni-app

uniapp 其实就是 webview 包皮,性能上不及 rn 和 flutter 。好处是,它不仅可以编译成 iOS 和安卓,还能直接做成各个平台的小程序以及快应用。但是 bug 多也是很多开发者诟病的。如果是面向国内,uniapp 应该问题不大,毕竟大量小公司都在用,1 个程序员同吃所有端,甚至后台(unicloud),美其名曰新全栈。

在这里插入图片描述

通用 JSBridge 设计

有时RN和H5需要利用一些底层的能力,在 Native 层,RN 和 H5 可以共用一份 JS Bridge 实现。底层的一些通用服务能力,分别通过两个 Bridge 暴露上去,可以让 H5 和 ReactNative 直接调用:
在这里插入图片描述

转载:移动开发技术的这几年发展

以手淘为背景,分析下这几年的技术发展历程,从我个人角度看,手淘为代表的移动平台技术这几年的发展可以分为以下几个阶段:

百花齐放

09-10年左右的手淘还是个很小的 team,整个手淘的技术团队清晰的划分为 服务端、客户端、架构组。其实大头在服务端和WAP 前端,App 还是一个很小的内容,也并非是重点(因为机型本身还在高速演进期,用户未形成对 App 的成熟心智)。一个项目的落地执行由服务端和客户端团队各自出人,遇到一些较为复杂通用的技术问题,拉架构组的同学进来提供方案。
那时候没有什么所谓的移动技术中间件,都是遇到问题解决问题,比如当时比较典型的标准版 WAP 手淘网站、中端版、高端版、Android 版等划分,一个请求上来,要区分这个用户所使用的 OS 类型、browser 类型等,是通过一个叫 warlf(记不太清了) 库来区分的,这个库就是个字典,里面内置的资源文件有各种各样的 UA 和机型的对应关系的记录,用request.UA 去查表,然后通过 URL Redirect 的方式路由到不同的版本 URL 上;

后来集团开始发力 App,各个 BU 都开始热火朝天的 build 自己的业务 App,这一波暖流给 App 开发领域带来了春天。但是遇到一个问题:BU 里技术团队没有那么多人会写 iOS 和 Android。但是有大量的人会写前端,能不能让前端的同学来写 App 的界面。12年的时候,PhoneGap 被少量的开发者开始关注,但是集团并未有自己的实现方案,于是 HybridSDK 的事情,手淘开始布局发力。

同样的,在App 开发技术的这次农耕时代,从上层业务组件化封装 TBUikit(最早手淘 iOS 用的还是 FB 的 Three20)、到 Hybrid、再到 Android 的热部署 Atlas,都开始出现一些通用方案。再往后,随着 Mtop 的集团铺开,以围绕 RPC 过程的 MtopSDK、安全团队的安全黑匣子 SDK、围绕资金安全的人机识别 SDK、 围绕数据收集的 UT、围绕绘制效率的 GLSDK、设备识别的 UTDID、围绕通用业务模块的如 LoginSDK、shareSDK、messageSDK、Agoo PUSH SDK 等都开始爆发式增长。同时移动研发支撑方面也高速发展,比如 Motu、打包平台、真机适配等衍生技术体系也开始成型—— 这是让移动开发者最舒适的时代,因为你总能找到一个别人还没有看到的机会,并且完成它,这个过程一致持续了大概到了2015年初。

特别的,上面提到了 PhoneGap 可能很多人会想为什么不直接用?其实 PhoneGap 做的事情很简单,一个 JSBridge + NativeHybridAPI,它所提供的 API 都是对 H5 Native 能力的补全(而且5种 JSBridge 实现方案里他用的是最 low 的 location 的方式——可以理解第一个吃螃蟹的人),尚未能称之为一个 hybrid 解决方案来解决 H5 所备受诟病的性能和功能障碍问题,而且当时 Facebook 对业内有一个很糟糕的声音:Hybrid 并不是一个可以商业应用的技术。当时一个版本 facebook 大跃进式的把整个 App 改成了 H5+Native 壳子,但是什么都没有额外附送解决 H5的性能和体验问题,结果备受诟病,于是 FB 又一个版本改了回去,CEO 在社交网站上公开的表达了对 Hybrid 的失望,业内于是形成了跟风抵抗 Hybrid 的浪潮。

精细耕作

农耕时代很快就过去了,土地上都插满了旗帜,大家开始更多的去关注土地底下的东西。比如那时候微信1s 法则在业内声音很大,手淘感受到了很大压力,因为 All in 无线后,手淘的性能问题越来越矛盾凸显,于是 ACCS 找到了属于自己的时代。阿里云的同学提供了 Anet,手淘的架构同学向上建设了 ACCS ,并且在后来将 MTOP SDK 也迁移到了 ACCS SDK 上。在 Hybrid 方面,packageApp、zCache 等方案开始发力 H5性能的1s 法则。UT 开始关注大数据量的成本问题。在图片加载方面,TBWebImageSDK 开始发力深耕数据指标。 HotPatch、TLog、安全气垫、启动模式、UISkeleton、业务上类似首页、搜索、详情、交易等场景,深耕定制化解决方案的场景 SDK 都开始发力,不断的用一个版本一个数据对标的方式去深挖每一个点。包括后来在存储方面,统一存储 SDK 等相关产物。数据同步框架 ACDS、消息 powerMsg 等。这个时代是数据说话的时代,有病没病数据论证。
随着一轮又一轮的合并,在手淘,各个垂直技术领域,开始出现了唯一性方案,比如 WindVane、UT、MtopSDK、SecuritySDK、ACCS……
同样的事情也在支付宝发生,支付宝在动态化、热修复等方面的产出,也随着一样的时代规律在发展
在这个时代,客户端开发工程师开始感受到压力:没有那么多好挖的土地了,挖开了土地也被各项数据对标折腾的压力很大。

专业驱动

经历了两个技术时代的手淘,具备了各项优秀的移动中间件技术和整套的移动研发支撑体系,成为集团最为核心的移动技术贡献者。2016年是充满挑战的一年,阿里开始主动出击这个行业,为这个行业开始注入强心剂。这一年作为开发者最大的一个感受是,同样是一块新领域,但是不是谁都能干了,门槛更高的回归到了技术本身,典型的两个技术产物代表就是 WEEX 和直播—— 你大概知道他怎么实现的,但是绝不是单兵作战能搞定的。还有一个是集成式服务化的建设开始出现,比如 google 的 firebase为代表的各个大厂的开发者平台,从 App 研发生命周期(build、growth、earn)给出了完备的解决方案,拼刺刀变成了拼火炮。包括今天手淘架构团队在做的移动中台战略。
发现新的技术垂直领域的机会越来越少 —— 这不是悲观而确实是事实,有的团队的解决方案是重复造车,把同一个技术方案在自己 BU 内重新实现一个所谓的独立版 —— 在聊客户端工程师的春天来自哪里之前,我们来分析下这几年几个比较有代表性的产物:

为什么会是 WindVane

解决最主要的 H5 性能和能力问题并不是重点,重点是提供了阿里集团的统一 Hyrbid 规约,在浏览器的时代,W3C 承载着厂商规范化的标准建设,在阿里 Hybrid 的时代,同样曾经有这样一批人在承载 Hybrid W3C 规约的标准建设,本质是不让各个不同 Hybrid 的实现方案破坏掉H5 原有的标准化,不把 Native 的碎片问题带入 H5.让业务跑的“真”的快。你会发现方案归一只是个结果,更多的这个过程是真的以德服人。
为什么会是手淘520架构改造
不只是解决one project 的拆分问题,而更多的提供了支撑几百人开发一个 App 的研发交付模式,真正的将服务端 SOA 的思想带入了客户端研发体系,它所提供的 URL 标准化、URL 统一路由、服务容器等机制,是奠定手淘今天航母姿态的基础。

热修复 HotPatch

提供一个 Patch 的机制让崩溃可以有所拯救,但你有没有想过 Application 的启动过程过程是没法 patch 的(性能原因考虑)?这背后所配套的整个是手淘启动容器标准化、安全模式、安全气垫、crash 收集+自动分析、舆情收集分析一整套的机制在配合。另,感兴趣的同学可以继续去看看聚划算的 iam 方案。

为什么会是 Atlas

在业务高速发展时期,我们需要有一个高速发动机,来驱动整艘大船的行进速度,如果每一个方向的调整都需要先换机油,那估计大象还没转身,蚂蚁已经到达终点。大象转身虽然慢,但是转完身后的奔跑速度一定比蚂蚁快。所以 Atlas 更多的是一种交付模式,有明确的可为可不为的限定。

其实 ACCS 不只是 ACCS

我们看到的 ACCS 是一个长链通道,有着 bindApp 和 bindUser 的 API,底下有着 DNSLookup 和 connection 的过程。但是手淘的1s 法则跟微信的1s 法则有最大的区别是,手淘的数据传输量是页面级的,1s 要求的不是1s 建立连接,而是1s 种载入完页面,这是完全不同的段位要求。配合以 ACCS 所做的Mtop 底层网络切换、 CDN 下载页面的网络加速、页面 package 预载入等配合,才有了今天手淘在性能体验上的整个优势。

为什么会是 Orange

如果你以为 orange 是通过accs 投递的一种config 版本化开关方案,那么你有没有想过如果 ACCS 也要使用开关控制该怎么办?Orange 跟 RPC 过程的整套配合,如何做到秒级的开关下发,看似简单,其实这背后有多少复杂度,只有 Mtop 服务器上内存里的那个 version 字段自己知道。

为什么会是 WEEX

WEEX 对集团移动技术的贡献,不只是提供了一套 DSL 的解析引擎,而且真正意义的从NA 动态化技术上统一了集团技术体系,真正的让上层的业务组件能够跨端跨业务跨 BU 复用的基础,解决成本和效率的问题。他所提供的技术能力,不是腾讯 OCS 那么激进,就是专注在页面动态化本身,这不损伤 OS 自身 sandbox 的商业规约,同时也引入了 VUE 优秀的 MVVM 思想,真正意义的将移动开发从 MVC 拽入了 MVVM 的时代。

为什么会是 Poplayer

曾经我和大部分同学一样,认为 Poplayer 是很简单的东西,但是你可知这个东西在业务上的爆发力有多强:PUSH 可以在站外召回用户,但是在应用内随时随地的触达引导流量灌入某个业务模块或活动,从数据分析来看,这是最有效的一种方式。不客气的说,poplayer 确实是一个很值得每个技术人深思的产物。
设计模式到底有多么让人讨厌
玩设计模式,老外是专业的,Relay、graphQL、 flux、componentKit这些套路,最大的一个问题是如何量化讲清楚收益的数字。但是,ACDS TQL 的努力,并非只是提供一套 DSL 语言来解耦服务端和客户端,解决 RPC 数量爆发的问题,而更多的是从更大的层面去解决公司的技术成本问题。
极客是兴趣,匠心是天生的
极客是玩别人想不到的东西,刺激亮点,但匠心是踏实的写好每一根线程,组织好每一个 GCD,代码写的漂亮是一个很笼统的印象,但是编码规范、注释规范、日志规范是一个体现,开了多少线程占了多少内存,应该有很强的敏感性。有时候安全气垫也兜不住任性写代码的后果。因为自己的代码让 App 整体发不出去包的事情,值得当事人好好反思。
你讲了这么多然并卵,工作中我就是个页面工程师
我每天的动作就是 initWithRect 和 addSubView,你讲了这么多都是架构层面的事情,然并卵。我想表达的是你做了一年又一年的体力活,我相信有业务和团队定位的限制因素存在,但是你有没有真的去努力:
发现技术机会
QuestMobile 给的各种报告中,有一份关于移动平台流量发展趋势的分析。这里面提及了各个 App 的市场占有量和交叉用户量,但是你有没有想过这个东西到底准确度有多少?集团通过离线计算的方式给出的交叉用户的 deviceId 的结果,在1111中经过验证是很低准确率的,这不是计算和算法逻辑的问题,而是数据本身存在很大的误差性,我们知道 iOS 本身在跨 App 层面的 deviceId 以及 android 的 imei+imsi 的组合式带有很大误差性的,并不能唯一性的识别一台设备,尤其是跨 App 场景的关联识别。那么 iOS 的 canOpen+info.plist 方法可以为你提供一个实现:彼此探测友军 App 是否安装。基于此我们做了一个简单的埋点和交叉计算,在引流项目中,得到了近似100%准确率的结果。—— 这是一个很小的发现机会的点,技术不复杂,但是价值很大。

App 之间通过 schema 或者 package name 的方式可以互相跳转,定义一个标准的 schema 可以解决 App 之间跳转问题,通过定义不同的 URL 可以完成不同页面的路由。但是如果剥开业务逻辑将 app 之间互相跳转的方式以 Link 规约的方式进行定义,提供单项路由和双向 callback 的两种模式,可以满足App 之间跳转的需求,也能满足一个 App 开放本地能力给另一个 App 提供 local service 的能力,即“任何一个 App 在一台是设备上都是另一个 App 的一台 Local Server”的理念,比如授权登录,比如加购等等。—— 这是设计模式上的机会,你可以提供的不只是一个看起来很简单的 applink 的 URL,而是真正意义的 “AppLink+” 为业务提供了更多的可能性。

这些 case 越来越多,就像服务端也一样的,集团有大量的共享性质的系统方案,每一个方案的背后的抽象过程,就是寻找技术人自身价值机会的过程。 OK,不谈服务端,回到客户端,每一个客户端工程师都需要成为:
一个有“高度”的客户端研发工程师
技术无非是横向和纵向两个维度,纵向解决的是深度问题,横向解决的是宽度问题,客户端工程师们需要更多在纵向有深入,横向有宽度的去思考每一个点的问题,就好比上面的 AppLink有一个插件用来唤醒手淘 App 商品详情页,大量的用户都会流失在返回按钮(业务绘制的),那么是否可以考虑,这个返回按钮,其实本身也就是个反向流量的流量入口,这里要做的事情,是让对当前商品或店铺不感兴趣的人,在这里二次发现兴趣,如果这样去考虑,第一步,搞定你的 PD,第二步,这里就进入另一个场景的设计:一个按钮式的流量入口应该是什么样子,技术上的指标是什么?
客户端工程师的第一步要跳出自身这一个端的角色限制,从更为全局的角度看问题,思考问题,你思考的问题中,对于终端的实现实现要求只是其中一小块内容而已,所以做动态化不应该只是做 DSL 解析,而要更高的从页面全生命周期的角度去看问题,页面哪里产生,如何发布,发布在哪里,如何下载,如何解析,如何校验,如何渲染。分支链路上如何提前发现错误,如何数据自动化分析,如何提供各种快捷组件提高效率等等。看问题要看全面。

比如让你来做一个客户端日志收集工具,站在客户端角度去看就是用一种高效的方式去设计如何打印日志到文件,如何上传,如何避免文件锁抢占,如何避免主线程阻塞等等,但是 TLog 的重点是在于客户端的日志收集,还是在于服务端的日志分析和错误自动发现,自动开启开关,自动上报,这里面的核心技术指标是收集完整度,还是收集时效性,还是发现问题的提前性?跳出端来看问题。无线曾经有过一次经典的关于 TLog 的争论,大家知道问题发生的那一刻可能是瞬间的,如果出了问题再开日志,现场早就没了,所以最好的是以缓冲的方式来实时记录,有问题自动判定并上报的方式最稳妥。但提出异议的同学从手机存储擦写频次对使用生命的影响角度去提出问题,并且对日志埋点的规范可执行性上提出质疑,最后讨论到一块手机存储的成本会有多少钱,多少用户多长时间会换手机等等,这就不仅仅是如何埋日志的问题了。

如何来提升自己的高度,这个是个千人千面的事情,如果让我来给建议,我的建议是找一位好老师,榜样的力量。可以是一个团队,或者是一个技术方案,当然也可以是一个人。在有高度达成之前,每一个客户端工程师都必须要做的,是:
深度掌控数据和细节
大部分技术场景里,如果你对自己的技术产物或者业务产物是无法用数据化的方式来表述的,那么我觉得只有一个可能就是没想清楚这个技术解决的核心问题是什么。总体数据、分阶段数据、核心红线数据、多维度的分析,都必须是一个工具。数据报表分为技术报表和业务报表,作为一个技术人,必须对自己做的事情,有一份属于自己的技术报表持续关注。用数据说话,而不是靠理论。

细节如何掌握?试一下吧:写一个 GCD,里面塞100个任务,每个任务都阻塞10s 后打印一句日志然后再阻塞1s(或者你干脆 hold 住 runloop),然后任务并行执行同时启动,模拟器启动,看看你的控制台在日志打印上会是什么现象?你会得到一个数字:64. 这个细节可能没有什么卵用,但是你是否有真正的掌握,很多时候会救命的。

参考链接

  • https://github.com/NervJS
  • https://nerv.aotu.io/
  • https://github.com/alibaba/weex
  • Expo官网
  • https://taro.zone/
  • taro入门

猜你喜欢

转载自blog.csdn.net/jgku/article/details/128678023
今日推荐