再聊跨端技术,React Native 0.64 新变化

本文由阿里的柏锦授权转发,本文主要聊聊 React Native 最近的一些更新,以及与你聊聊跨端技术。

???? 谈一谈跨端技术的现状、变化和未来,集中讨论下其在渲染层面上的回顾与展望。

一些想说的

Flutter 最近也出了 2.0 版本,但大家可能觉得变化不大,而且社区的讨论主要围绕着 Dart 的空类型,可是我也看到了 Flutter 对于目前它的最弱项——对周边能力的支持做出努力。可以看出在未来,Flutter 作为主流跨平台开发潜力无限。

而作为老牌 Hybrid 框架,React Native 也逐渐要面临新的变革:

React 团队目前正朝着 CM 模式进行努力,这是一个 UI 框架的一个变革,因为像是 Vue、Angular 等 UI 框架,他们解决的大部分还是开发者本身的问题,只是为了赋能开发流程本身而存在,而目前 React 在 CM 的方向意味着终于能有一个 UI 框架能够去注重用户的体验了

React Native 自从 0.6x 以来,就开始着力于对原先较为低效的线程模型进行重构,并在 UI 渲染、JS 引擎和原生模块加载进行大刀阔斧的变革。这个方向从19年到现在仍然在进行着,而在即将到来的 0.64 版本中,这些变革即将迎来终章。而就算完成了这些变革,React Native 仍然将处于 0.x 版本下,对于这些变革产生的一系列问题的解决,将也会长期困扰整个框架的开发。

我们再回到跨端技术本身上来谈谈:

跨端技术的核心问题就是如何使多个平台达到一致性的 UI / 逻辑 / 体验。而这本身就是个伪命题,因为不可能存在完全一致的体验,我们在开发跨端框架的过程中,要注重的是尽量抹平这些差异。

UI 渲染的两种方案:

  1. 采用统一渲染引擎,由设备 GPU 绘制页面,类似于 Unity 等一众游戏引擎,优点:页面一致性几乎完全保证、事件绑定解决;缺点:引擎需要初始化,预热通常较慢。安装包体积通常较大,因为封装了强大的渲染引擎。渲染引擎通常着力于压榨 GPU 性能,会使移动端设备耗电较快。

  2. 使用原生组件拼接,通过 DSL 中间层对原生组件样式和布局进行修改,优点:页面渲染效率高,TTI(用户可交互时间) 较快,安装包体积相对较小。缺点:需要花大量时间抹平各平台差异,比如事件绑定问题、页面一致性(最经典的就是阴影、圆角和 scroll 体验问题),对于用户体验略有影响。

而 UI 渲染是所有人最关切的东西,所以大家通常都觉得像是 mini program、Flutter、Web 等这种统一或半统一渲染引擎的方案会是未来,而随之带来的引擎体积和预热似乎可以在他们所构想的场景中可以忽略。我个人可能觉得,如果作为个人开发者,对于 Flutter 可能不会太感冒,因为它带来的周边问题对于一个应用要经历最长的生命周期——启动周期是非常致命的

比如一个新的 App,在产品角度来讲,最重要的是“冷启动”(此冷启动非彼冷启动),而冷启动是触达链路的最低层,触达链路如果有一个地方出现意外,很容易导致用户直接放弃 “从认识、到接触” 整个事务流程,而 Flutter 巨大安装包和较为缓慢的预热,会造成“冷启动”成本过高,而冷启动成本过高的后果就是用户很容易去放弃完成这个事务

应用本身的性能和表现一致性往往并不是用户最有欲望去关心的,而是开发者或团体为了提升开发效率进行努力(有人会说:但长期来讲,提升开发效率是为了优化用户体验呀。其实这就像是:老师说,如果我能快速给你们批作业,你们一定能考上好大学。显然提高开发效率这本不是提升用户体验的充分必要条件,开发效率的提升带来的是开发成本的降低,一个是成本,一个是体验,差距已经很明显了吧。),所以这就目前造成了用户和开发者的认知和目标具有偏差的原因

这可能是我对 Flutter 和 Game Engine App 有一种莫名的偏见的原因(其实也不是偏见,这些厉害关系一般纯技术的开发者也很难去注意到的),因为如果你将这些厉害关系讲给 PM / 个人开发者,他们是很难接受去全面去使用这种东西的(除非是纯跟风)。技术选型肯定不能光考虑技术团队的需要,去对整个业务进行一定尺度的考量也是很有必要的

当然,如果是那种有极其完善的触达方案,而且该方案和方法论经过业界数年检验,项目立项时对于 App 本身的冷启动并不感冒的话,这样的开发者或团队去使用这东西完全没啥问题

统一渲染引擎说完了,那我们再疯狂吐槽下类似于 React Native / Weex / Taro / NativeScirpt 这样的原生组件布局渲染(实际上也不是吐槽,因为我这个人在表达意见之前,尽可能会从一些别人难以注意的角度,把所有厉害关系给讲得很明白),这种方案的精髓在于两个单词:Bridge + Compile ,桥接和编译。

为什么是 Bridge 而不是 Runtime?因为 Runtime 本身就分为:Bridge + VM,而且我们讨论的是渲染引擎,Bridge 本质上是为了抹平平台差异而存在的。而 Compile 通常也是为了抹平平台差异而存在的,而两者的关系举个不恰当的例子,就是 JIT 和 AOT 的关系(笑)———都是为了一个目的,但发生作用的情况是不同的

而大家都知道,平台千变万化,API 适配、平台权限调用、硬软件性能表现(配置和操作系统)、原生组件实现和调用方法等等,这些东西就完全难以预测,就像我们使用冒泡排序排数组一样,多一个元素,就相当于多一个 N,而多一种场景,就要牵一发而动全身,框架本身就要追求极高的设计(为了解耦合),而且还要去设计各种策略(也就是各种 if switch-case),框架本身的各种方法的圈复杂度因为支撑的能力,就会变得极高,这就导致框架到了一定程度,就会出现难以维护、难以 debug、代码难以预测等等问题,这些问题就会造成了现在很多框架目前的一些现象:React Native 更新极其缓慢,不断重构代码设计,版本号仍然停留在 0.x 版本;Weex / Taro 表现力差,迭代逐渐乏力,而且让开发者感到难用又让用户感到难用;NativeScript 生态极差,甚至很多简单的第三方组件还是闭源状态,社区也鲜见讨论(说明快凉了)。

以上仅仅只是从 UI 渲染角度来讲这些跨端技术目前存在的问题,而像是统一业务逻辑、涉及到 I / O 和网络层调用的东西等等,我还只字未提,毕竟大家最关注的是 UI 渲染,这方面的东西确实大有可聊,理想的跨端方案是不存在的,Web 的问题我相信前端同学也是非常清楚,各种浏览器兼容问题都还没解决好,哪有空去管对于原生层面的调用。

跨端技术本身就是研究起来很让人感到兴奋的东西,我虽然表面上说在选型时对于各种跨端方案要慎重慎重再慎重,但实际上,抛弃技术选型本身要进行的各种思考,这些方案的存在和如今的成长本身就已经极其伟大了!

聊天结束,正文开始:

iOS 平台支持 Hermes Engine

Hermes 作为 facebook 开发的面向新一代移动端 JS 引擎,在 Android 的表现很令人感到兴奋,在大大减少安装包大小的同时,也将 RN 在安卓平台的首屏加载时间也大幅度优化,同时也优化了最令人头疼的内存问题。

Hermes 将 JS 代码编译为 Hermes bytecode,使得 JS bundle 体积大幅度减少。

Hermes 编译为字节码,再将字节码交给引擎解释运行,而一般的 JS 引擎或者 JVM,会对热点代码进行 JIT 优化,而 Hermes 没有这一步,因为 JIT 的问题是——预热缓慢,影响 TTI 和首屏逻辑加载,Hermes 通过编译字节码的方式避免了这种问题。

而对于内存的优化,由于是字节码,Hermes 使用了 mmap,逻辑加载速度提升,用内存读写取代 I/O 读写,提高了 JS 逻辑文件读取效率。并且对于垃圾回收,它也做到了针对移动端的垃圾回收策略。

我们总说,优化是要基于场景的,Hermes 对于 Hermes bytecode 的运行效率是极高的,但 Hermes 对于直接运行 JS 代码的效率却不及 V8 JSC,必须要经过一定时间的 AOT,才能达到最好的优化效果,这种场景对于目前的主流浏览器来讲,估计有些有限,因为需要一段漫长的预编译过程。但对于像是服务端 / 移动 App 场景去使用这种技术,所带来的效果估计会比现在的主流 JS 引擎的效果会好得多。(Nodejs 考虑动态换引擎不?)

而且对于 Hermes 的支持,来源于 RN 团队对于 JSI 的努力,JSI 使得原先低效的 JSON payload 通信方式成为历史,现在我们可以直接使用 JSI 来进行渲染进程和逻辑进程的通信,没有了序列化和反序列化的成本使得通信效率大大提升,同时也为未来可能会有的同步渲染作准备。而 JSI 同时也让 RN 对于 JS 引擎的限制彻底解锁,使得类似于 react-native-v8 / hermes 这样的方案横空出世,来去替代原先的 JSC

而 RN 团队当初对于 JSC 选型的考虑,也是基于 iOS 开发者角度去思考的,JSC 让 Objective-C 和JavaScript 代码直接的交互变得更加的简单,但 JSC 在安卓上的表现较差。所以当初 Hermes 问世之时,RN 团队解决 Hermes 对安卓的的适配问题,而最后的成果是喜人的。

这次将 Hermes 应用在 iOS 平台上,意味着 Hermes 要向真正的移动端 JS Engine 发力。

但这次还算是比较实验性质的 feature,所面临的问题也会接踵而至:比如 ipa 包有明显的增加,性能提升不是十分明显**(因为依赖 iOS 硬件生态,在使用 JSC 时本身的性能也过硬,而且 iOS 平台对于 JSC 有蜜汁加成)**。

Hermes 支持 Proxy

这个属于 Hermes 的新功能,如果你之前对 RN 并不熟悉,看到这里你会极其震惊(竟然这玩意之前还不支持 ES6 的特性)。

为什么要拿到这里说呢?因为像是 immer、volit、react-native-firebase 和 mobx 等等基于 Proxy 实现的第三方库和框架在此之前对 Hermes 的支持极其有限(比如 immer 只能开启 enable ES5),导致这些第三方工具性能过差,以及甚至是不可使用

但是呢,我们也可以明显地看到,Hermes 对于各平台的支撑,这将是未来 FB 发力的重心。

默认启用 inline Require

inline Require 也就是在代码逻辑里将模块 / 代码按需引入进来,熟悉 Web 开发和 Webpack 的同学都很熟悉 bundle 的分包拆包优化,按需加载,按需引入,会加快页面的首屏渲染,这个道理放在 RN 上也是如此。

这个属于 metro 的一个 Feature,而目前它在 RN 上作为一个默认的配置项。

它的原理很简单,就是通过 babel,通过它定义的 transform 操作,将模块最上面 require 放到执行的地方附近。

当然,如果你使用的是 Hermes Engine,你其实并不用关心这个东西,因为 mmap 本身就能让 Hermes bytecode 进行按需加载和高效的逻辑加载。

React 17 Support

React 17 本身不包含面向开发人员的新功能或重大更改。而对于 React Native,主要的更改是使用了新的 JSX transformer,这意味着我们没必要在后缀为 JSX 的文件最顶部引入 React 后,才能正常去使用 JSX(更加 Free 了)。

举个例子,像是如下的 Hello World

import React from 'react';function App() {return 

Hello World

; }

之前的转换是这样的:

import React from 'react';function App() {return React.createElement('h1', null, 'Hello world');
}

而现在变成了这样:

// Inserted by a compiler (don't import it yourself!)
import {jsx as _jsx} from 'react/jsx-runtime';function App() {return _jsx('h1', { children: 'Hello world' });
}

(当然,如果你就喜欢使用 React.createElement,人家也不拦着你用)

其他小更新

以上都是比较 highlights 的 Features,其他的 change 也就是改改 Bug 和增加一点小 Support Features 之类的东西。我选择了一些较为重要的放在了下面:

  1. 安卓支持 color shadow(算是比较有用的新特性)

  2. Flipper 升级到 0.75.1(感觉还是很少有人用 Flipper)

  3. Node 最低支持版本支持从 v10 提升到 v12(在配置 CI / CD 的时候要注意下 Node 版本啦)

  4. CocoaPods 需要升级到 1.10.1 以上(更新时就遇到了这个坑,➡️:CocoaPods 更新指引)

  5. 不再支持 Android API 16-20 (很重要!)

  6. Image 的 onLoad 参数 source 的 source.url 更名为 source.uri (URL 为 URI 的子类,而且引入入图片资源的存储读消耗和网络慢读取相类似,而且如果使用 URL 只能特定于网络资源...所以更名为 URI 更准确)

全部更新请见:

https://github.com/react-native-community/releases/blob/master/CHANGELOG.md

相关推荐

Android 图形显示系统汇总

鸿蒙 OS 2.0 公测!已适配多款机型

一个人竟然撸了一个网易云音乐云村

12 年!Android 系统的漫漫设计路

迟来的一份总结:2020合集


如果你有写博客的好习惯
欢迎投稿
更文不易,点个“在看”小生感恩❤️


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部