Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

react native架构 #50

Open
into-piece opened this issue May 10, 2021 · 2 comments
Open

react native架构 #50

into-piece opened this issue May 10, 2021 · 2 comments

Comments

@into-piece
Copy link
Owner

into-piece commented May 10, 2021

React Native 新架构

  • JS thread。JS代码执行线程,负责逻辑层面的处理。Metro(打包工具)将React源码打包成一个单一JS文件(就是图中- JSBundle)。然后传给JS引擎执行,现在ios和android统一用的是JSC。
  • UI Thread(Main Thread/Native thread)。这个线程主要负责原生渲染(Native UI)和调用原生能力(Native Modules)比如蓝牙等。
  • Shadow Thread。 这个线程主要是创建Shadow Tree来模拟React结构树。Shadow Tree可以类似虚拟dom。RN使用Flexbox布局,但是原生是不支持,所以Yoga就是用来将Flexbox布局转换为原生平台的布局方式。

当我们写了类似下面的React源码。

<View style={{
        backgroundColor: 'pink',
        width: 200, 
        height: 200}}/> 

JS thread会先对其序列化,形成下面一条消息

UIManager.createView([343,"RCTView",31,{"backgroundColor":-16181,"width":200,"height":200}])

通过Bridge发到ShadowThread。Shadow Tread接收到这条信息后,先反序列化,形成Shadow tree,然后传给Yoga,形成原生布局信息。

接着又通过Bridge传给UI thread。

UI thread 拿到消息后,同样先反序列化,然后根据所给布局信息,进行绘制。

从上面过程可以看到三个线程的交互都是要通过Bridge,因此瓶颈也就在此。

Bridge三个特点:

  • 异步。这些消息队列是异步的,无法保证处理事件。
  • 序列化。通过JSON格式来传递消息,每次都要经历序列化和反序列化,开销很大。
  • 批处理。对Native调用进行排队,批量处理。
@into-piece
Copy link
Owner Author

code push

  • 修改加载 jsBundle 的代码,转而从指定的本地存储位置去加载。如果没有,下载 bundle, 并且本次打开使用 app 包中的 bundle。
  • 如果找到 jsBundle 文件,调用 api 比较版本号,如果不一致,则从指定服务器下载最新的 bundle 进行替换。
  • 通过反射调用私有方法,在下载完成的回调中更新运行时资源,从而能立即看到更新的效果。
  • 使用类似 google-diff-match-patch 的 diff 工具,生成差异化补丁,不必下载完整 bundle,从而大大减小补丁包体积。

@into-piece
Copy link
Owner Author

into-piece commented May 19, 2021

js interface

JSI是整个架构的核心和基石,所有的一切都是建立在它上面。

JSI是Javascript Interface的缩写,一个用C++写成的轻量级框架,它作用就是通过JSI,JS对象可以直接获得C++对象(Host Objects)引用,并调用对应方法。

另外JSI与React无关,可以用在任何JS 引擎(V8,Hermes)。

有了JSI,JS和Native就可以直接通信了,调用过程如下:

JS->JSI->C++->ObjectC/Java

自此三个线程通信再也不需要通过Bridge,可以直接知道对方的存在,让同步通信成为现实。具体的用法可以看 官方例子。

另外一个好处就是有了JSI,JS引擎不再局限于JSC,可以自由的替换为V8,Hermes,进一步提高JS解析执行的速度。

  • 同步能力
  • 直接引用
  • 支持Concurrent mode

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant