React Native如何构造应用布局(以及Fabric将如何对其进行更改)

司徒高丽
2023-12-01

The React Native team has been working on something which is fundamentally going to change how the internals of React Native communication work with the host Operating System. It is nicely codenamed “project fabric” (until there’s an official name released).

React Native团队一直在进行一些工作,这些工作将从根本上改变React Native通信内部与主机操作系统的工作方式。 它很好地代号为“ project fabric”(直到正式名称发布)。

Let us discuss what it actually is and what changes it brings to you as a developer.

让我们讨论一下它的真正含义以及它为开发人员带来的变化。

React Native现在如何工作 (How React Native works right now)

If we take a look, React Native right now uses 3 threads:

如果我们看一下,React Native现在使用3个线程:

  1. UI Thread — This is the main application thread on which your Android/iOS app is running. It has access to UI and your UI can be changed only by this thread.

    UI线程—这是运行Android / iOS应用程序的主要应用程序线程。 它具有访问UI的权限,并且只能通过此线程更改UI。
  2. Shadow Thread — This thread is the background thread used by React Native to calculate your layout created using React library.

    阴影线程—此线程是React Native用于计算使用React库创建的布局的背景线程。
  3. JavaScript Thread — This thread is the place where your JavaScript code (your React code, essentially) lives and executes.

    JavaScript线程-该线程是您JavaScript代码(本质上是您的React代码)生活和执行的地方。

内部工作原理 (The inner workings…)

Let’s start from the beginning. Suppose you want to draw a red box in the center of your screen. So what happens is that your JS thread contains code to create a layout, i.e. that red box on the screen. Here’s a typical code snippet which might achieve that for React Native (RN):

让我们从头开始。 假设您要在屏幕中央绘制一个红色框。 因此,发生的事情是您的JS线程包含用于创建布局的代码,即屏幕上的红色框。 这是一个典型的代码片段,可以为React Native(RN)实现:

<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<View style={{width: 100, height: 100, backgroundColor: "red"}}></View>
</View>

The host operating system has its own layout implementation and does not follow the kind of flexbox code you just wrote. Therefore, RN first of all has to convert your flexbox coded layout into a layout system which your host operating system can understand.

主机操作系统具有其自己的布局实现,并且不遵循您刚刚编写的那种flexbox代码。 因此,RN首先必须将您的flexbox编码布局转换为主机操作系统可以理解的布局系统。

Hold on! Before doing that, we need to offload this layout calculation part to another thread so we can keep executing our JavaScript thread. Hence, RN uses the Shadow Thread which essentially constructs a tree of your layout you coded in your JS thread. In this thread, RN uses a layout engine called Yoga which converts the flexbox-based layout into a layout system which your native host can understand.

坚持,稍等! 在此之前,我们需要将该布局计算部分卸载到另一个线程,以便我们可以继续执行我们JavaScript线程。 因此,RN使用了影子线程,该线程本质上构造了您在JS线程中编码的布局树。 在此线程中,RN使用了名为Yoga的布局引擎,该引擎将基于flexbox的布局转换为本地主机可以理解的布局系统。

React Native uses something called a React Native bridge to communicate this information from the JS thread to the Shadow thread. In a nutshell, this simply serializes the data in JSON format and transfers it as a string over the bridge.

React Native使用一种称为React Native的桥将这些信息从JS线程传递到Shadow线程。 简而言之,这只是简单地以JSON格式序列化数据并将其作为字符串通过桥传输。

At this point, we’re in the Shadow thread. The JS thread is executing and there’s nothing drawn on the screen.

至此,我们进入了影子线程。 JS线程正在执行,并且屏幕上没有任何内容。

Now, once we have the rendered markup from yoga, this information is again transferred to UI thread via the React Native bridge. Again, this does some serialization on the Shadow thread and deserialization on the main thread. Here, the main thread then renders the UI.

现在,一旦从瑜伽中获得了渲染的标记,该信息就会再次通过React Native桥传输到UI线程。 同样,这会对Shadow线程进行一些序列化,并对主线程进行反序列化。 然后,主线程在此处呈现UI。

这种方法的问题 (Problems with this approach)

If you see, all the communication among threads happens over a bridge which works, but is full of limitations. These include:

如果看到的话,线程之间的所有通信都是通过一个有效的桥进行的,但是充满了局限性。 这些包括:

  • it’s slow to transfer large chunks of data (say an image file converted into base64 string), and

    传输大量数据的速度很慢(例如,将图像文件转换为base64字符串),并且
  • there’s unnecessary data copying if the same task can be implemented just by pointing to the data in memory (again, say an image)

    如果仅通过指向内存中的数据(同样是图像)就可以执行相同的任务,则不需要复制数据

Next, all communication is asynchronous, which in most cases is good. However, there is no way currently to update the UI thread from the JS thread synchronously. This creates a problem when you’re using, say, FlatList with a huge list of data. (You can think of FlatList as a weaker implementation of RecyclerView.)

接下来,所有通信都是异步的,这在大多数情况下是好的。 但是,当前无法同步从JS线程更新UI线程。 当您使用带有大量数据的FlatList时,这会产生问题。 (您可以将FlatList视为RecyclerView的较弱实现。)

Finally, due to this asynchronous nature of communication between the JS thread and UI thread, native modules which strictly require synchronous data access cannot be used to a complete extent. For example, RecyclerView’s Adapter on android requires synchronous access to the data it is rendering for not having flickers on screen. This is not possible right now due to the multi-threaded architecture setup by React Native.

最后,由于JS线程和UI线程之间的这种异步通信特性,严格要求同步数据访问的本机模块无法完全使用。 例如,Android上的RecyclerView适配器需要同步访问它正在渲染的数据,因为屏幕上不会出现闪烁。 由于React Native设置了多线程架构,因此目前无法实现。

面料介绍 (Introducing Fabric)

Take a step back and think about your browser. If you take a deeper look, the input fields, the buttons, etc. are actually Operating System-specific. Therefore, it is your browser which asks your OS (Windows, Mac, Linux, or pretty much anything else) to draw, for example, an input field somewhere on a webpage. Holy moly! See the beautiful mapping from browsers to React Native.

退后一步,思考一下您的浏览器。 如果您进行更深入的研究,输入字段,按钮等实际上是特定于操作系统的。 因此,是您的浏览器要求您的OS(Windows,Mac,Linux或几乎其他任何设备)绘制例如网页上某处的输入字段。 天哪! 查看从浏览器到React Native的漂亮映射。

  • UI Thread → UI Thread

    UI线程→UI线程
  • Browser rendering engine → React Native rendering engine (Yoga/Shadow thread)

    浏览器渲染引擎→React Native渲染引擎(瑜伽/阴影线程)
  • JavaScript thread → JavaScript thread

    JavaScript线程→JavaScript线程

We know that modern browsers are very mature and handle all these tasks efficiently. So why not React Native? What is the missing piece of the puzzle which brutally restricts React Native but not browsers?

我们知道,现代浏览器非常成熟,可以高效地处理所有这些任务。 那么为什么不使用React Native? 残酷地限制了React Native但没有限制浏览器的难题的缺失部分是什么?

将本机API调用直接暴露给JavaScript (Exposing Native API calls directly to JavaScript)

Have you ever just written commands like document.getElementById and commands like setTimeout and setInterval in your console and seen the output? Oh! Their implementation is actually [native code] ! What does that mean?

您是否曾经在控制台中编写过诸如document.getElementById类的命令以及诸如setTimeoutsetInterval类的命令,并看到了输出? 哦! 它们的实现实际上是[native code] ! 那是什么意思?

You see, when you execute these functions, they do not call any JavaScript code. Instead, these functions are linked directly to native C++ code which is called. So the browser does not let JS communicate with the host Operating System using bridging, but instead, directly exposes JS to the OS using native code! In a nutshell, this is what React Native Fabric would do: eliminate the bridge and let the UI be controlled directly from the JS thread using native code.

您会看到,执行这些函数时,它们不会调用任何JavaScript代码。 相反,这些函数直接链接到被调用的本地C ++代码。 因此,浏览器不允许JS使用桥接与主机操作系统进行通信,而是使用本机代码将JS直接公开给OS! 简而言之,这就是React Native Fabric的工作方式:消除桥接,并使用本机代码直接从JS线程控制UI。

外卖 (Takeaways)

  1. RN Fabric allows the UI thread (where UI is drawn) to be in sync with the JS thread (where the UI is programmed)

    RN Fabric允许UI线程(在其中绘制UI)与JS线程(在其中对UI进行编程)同步
  2. Fabric is still under development, and the React Native team did hasn’t mentioned a public release date as of now. But I’m pretty sure that we’ll see something awesome this year.

    Fabric仍在开发中,到目前为止,React Native团队还没有提到公开发布日期。 但是我很确定,今年我们会看到很棒的东西。
  3. Frameworks for app development like these (RN, NativeScript, Flutter) are getting better day by day!

    诸如此类的应用程序开发框架(RN,NativeScript,Flutter)日趋完善!

Image sources: https://www.slideshare.net/axemclion/react-native-fabric-review20180725

图片来源: https : //www.slideshare.net/axemclion/react-native-fabric-review20180725

TL; DR (TL;DR)

喜欢这篇文章吗? (Liked this article?)

If you liked this article, feel free to give me some claps and connect with me on twitter. You know the best part? Claps and twitter both are free! If you have any questions, feel free to drop them in the comments!

如果您喜欢这篇文章,请随时给我鼓掌,并在twitter上与我联系。 你知道最好的部分吗? 拍手和推特都是免费的! 如有任何疑问,请随时在评论中添加!

Quick shameless plug: If you’re getting started with React Native, here’s my 95% off course on how to get started with it: React Native — The First Steps

快速无耻的插件: 如果您要开始使用React Native,这是我入门的95%课程: React Native —第一步

翻译自: https://www.freecodecamp.org/news/how-react-native-constructs-app-layouts-and-how-fabric-is-about-to-change-it-dd4cb510d055/

 类似资料: