本文主要介绍
- React Native新旧框架对比
- React与React Native区别
- React Native性能优化
其中第3点React Native性能优化的拆包分包,是项目实战中使用过的,在这里整理分享,如果没有用过的小伙伴会觉得晦涩难懂,建议按照在实际项目中需要去实践,纸上得来终觉浅,绝知此事要躬行。
一、jsBridge
在React Native 中,web和native通过jsBridge进行通信,以js引擎或webview容器作为媒介,通过协定协议进行通信,实现native端和web端双向通信的一种机制。
web
端调用native
端主要的方法:
1、拦截webview请求的URL_Schema
如果符合我们自定义的URL_Schema,进行拦截,拿到相关操作,从而操作native;
如果不符合自定义的URL_Schema,直接转发,请求真正的服务。
2、向webview中注入JS API
通过webview提供的接口,App将Native的相关接口注入到JS的Content对象中,一般来说这个对象内的方法名与native内方法名相同,Web端就可以在全局下使用暴露的js对象,进而调用原生端方法。
二、React Native旧架构的问题
1、消息通知是异步的,对于连续的手势操作可能产生卡顿
2、JSON本身在性能上也存在问题,JSON parse、JSON stringfy类似于深拷贝,耗费内存
3、消息的通信,是在一个channel里,异步通信可能会阻塞。
在我们刚做过的一个大型RN项目中,遇到的直接问题有:
1、性能和问题反馈最大的组件
-
ScrollView:一次渲染不做任何回收,启动性能慢,占用内存大
-
FlatList:做了组件回收,快速滑动中容易出现白屏和卡顿
-
Shadow层最终呈现到原生的UI是异步的,滑动太快会有大量的UI没加载
2、ui渲染阻塞
整体UI渲染太过于依赖JsBridge,容易出现阻塞影响整体UI体验
3、时间阻塞
事件阻塞在JsBridge,导致了长时间白屏的出现
三、React Native新架构的变化
新架构放弃了"桥"的概念,转而采用另一种通信机制:JavaScript 接口(JSI
)。JSI 是一个接口,允许 JavaScript 对象持有对 C++ 的引用,反之亦然。
一旦一个对象拥有另一个对象的引用,它就可以直接调用该对象的方法。例如一个 C++ 对象现在可以直接调用一个 JavaScript 对象在 JavaScript 环境中执行一个方法,反之亦然。
这个想法可以带来几个好处:
- 同步执行:
现在可以同步执行那些本来就不应该是异步的函数。
- 并发:
可以在 JavaScript 中调用在不同线程上执行的函数。
- 更低的开销:
新架构不需要再对数据进行序列化/反序列化,因此可以避免序列化的开销。
- 代码共享:
通过引入 C++,现在有可能抽象出所有与平台无关的代码,并在平台之间轻松共享它。
- 类型安全:
为了确保 JS 可以正确调用 C++ 对象的方法,反之亦然,因此增加了一层自动生成的代码。这些代码必须通过 Flow 或 TypeScript 类型化的 JS 规范来生成。
这些优势是TurboModule系统的基础,也是进一步增强功能的跳板。例如,我们有可能开发出一种新的渲染器,它的速度更快,性能更强:Fabric及其Fabric 组件。
新架构使用了JSI、Hermes 引擎、 Fabric和TurboModules
,旨在提高性能和开发效率,其中一个重要的改进就是允许 JS 和 Native 之间更直接的调用
,减少了不必要的消息通信。
1. JSI
新的架构使用JSI屏蔽js引擎的差异,允许用不同的js引擎,比如Hermes
有了JSI之后,js能持有C++对象的引用,从而允许js和native之间直接调用
,而不用通过跨线程消息通信。
-
一个用 C++ 写成的轻量级框架
-
实现JS引擎的互换
-
通过JS直接调用Native
-
减少不必要的线程通信,省去序列化和反序列化的成本,
-
减轻了通信压力,提高了通信性能
2. Hermes 引擎
Hermes 是一个专为 React Native 优化的 JavaScript 引擎。它通过优化字节码执行和减少内存占用
等方式来提高 JavaScript 代码的执行速度。
Hermes 对代码的预编译和优化
减少了在运行时的解释开销,使得 JavaScript 代码的执行更加高效,这在一定程度上为更直接的交互提供了基础。
3.重构Bridge
新的Bridge被划分为Fabric和TurboModules
- Fabric:负责管理UI
- TurboModules:负责与Native交互
4. Fabric 渲染器
Fabric 是 React Native 的新渲染器。它重新设计了 React Native 的渲染体系结构,使渲染过程更加高效和可预测。
在 Fabric 中,JS 和 Native 之间的交互通过共享内存和直接函数调用等机制
来实现,而不是完全依赖于消息传递。例如,对于一些常见的 UI 操作和交互,JS 端可以直接调用 Native 层的某些函数来触发相应的操作,而不需要经过复杂的消息序列化和传递过程。
Fabric 还采用了异步渲染和可中断渲染
等技术,进一步提高了应用的响应性和性能。
例如,在处理 UI 动画时,以前可能需要通过消息将动画的参数从 JS 传递到 Native 层,然后 Native 层再进行动画的渲染。在新架构下,JS 可以直接调用 Native 层的动画函数,并传递参数,Native 层可以直接响应并开始动画渲染,减少了中间的消息传递环节,提高了动画的流畅性和响应速度。
5. TurboModules
实现Native模块按需加载,并在初始化后直接持有其引用,不再依靠消息通信来调用模块功能。
总的来说,React Native 新架构重新设计了 JS 和 Native 之间的交互方式,使得它们之间可以更直接地进行调用,从而提高了应用的性能和开发体验。
四、React 和 React Native 的概念区别
- React:是一个用于构建用户界面的 JavaScript 库,主要用于在网页开发中构建高效、动态的用户界面,运行在浏览器环境中。
- React Native:是基于 React 开发的用于构建原生移动应用的框架。它允许开发者使用 JavaScript 和 React 编写应用,然后将其编译为原生代码,运行在 iOS 和 Android 等移动平台上。
1、移动应用
import {
AppRegistry} from 'react-native';
import App from './App';
AppRegistry.registerComponent('YourApp', () => App);
在 React Native 中,入口文件通常会使用 AppRegistry.registerComponent
方法来注册应用的根组件。
2、移动组件
import React from 'react';
import {
Text } from 'react-native';
function MobileComponent() {
return (
<Text>This is a mobile component.</Text>
);
}
export default MobileComponent;
可以看到,React Native 组件中使用的是 react-native
提供的组件(如 Text
),而 React 网页组件通常使用 HTML 元素或自定义的 Rea