神经喵 發表於 2020-5-12 08:51:00

React Native 架构一览

<h2 id="%E4%B8%80%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1" class="mume-header">一.架构设计</h2>
<p>整体上分为三大块,Native、JavaScript 与 Bridge:</p>
<p><img class="size-large wp-image-2013" src="http://www.ayqy.net/cms/wordpress/wp-content/uploads/2019/09/React_Native_layers-1024x576.jpg" alt="React Native layers" width="625" height="352"></p>
<p>Native 管理 UI 更新及交互,JavaScript 调用 Native 能力实现业务功能,Bridge 在二者之间传递消息。即:</p>
<p class="sync-line" data-line="8">&nbsp;</p>
<p><img src="https://formidable.com/uploads/old-diagram-full.png" alt=""></p>
<p class="sync-line" data-line="9">&nbsp;</p>
<p>最上层提供类 React 支持,运行在JavaScriptCore提供的 JavaScript 运行时环境中,<strong>Bridge 层将 JavaScript 与 Native 世界连接起来</strong>。具体的,Shadow Tree 用来定义 UI 效果及交互功能,Native Modules 提供 Native 功能(比如蓝牙),二者之间通过 JSON 消息相互通信</p>
<p>Bridge 层是 React Native 技术的关键,设计上具有 3 个特点:</p>
<ul>
<li>
<p>异步(asynchronous):不依赖于同步通信</p>
</li>
<li>
<p>可序列化(serializable):保证一切 UI 操作都能序列化成 JSON 并转换回来</p>
</li>
<li>
<p>批处理(batched):对 Native 调用进行排队,批量处理</p>
</li>
</ul>
<p>将 UI 操作描述成一系列指令,序列化成 JSON 格式的消息:</p>
<blockquote>
<p>Just as React DOM turns React state updates into imperative, mutative calls to DOM APIs like document.createElement(attrs) and .appendChild(), React Native was designed to return a single JSON message that lists mutations to perform, like [["createView", attrs], ["manageChildren", ...]].</p>
</blockquote>
<p>相当灵活,甚至基于这种命令式的机制可以让 JS 代码跑在另一个 JS 引擎上,即Chrome debugging:</p>
<blockquote>
<p>Chrome debugging, which runs all the JavaScript code asynchronously over a WebSocket connection.</p>
</blockquote>
<p class="sync-line" data-line="28">&nbsp;</p>
<h2 id="%E4%BA%8C%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B" class="mume-header">二.线程模型</h2>
<p>React Native 中主要有 3 个线程,分别是:</p>
<ul>
<li>
<p>UI Thread:Android/iOS(或其它平台)应用中的主线程</p>
</li>
<li>
<p>Shadow Thread:进行布局计算和构造 UI 界面的线程</p>
</li>
<li>
<p>JS Thread:React 等 JavaScript 代码都在这个线程执行</p>
</li>
</ul>
<p>此外,还有一类 Native Modules 线程,不同的 Native Module 可以运行在不同的线程中(具体见Threading):</p>
<p><img class="size-large wp-image-2014" src="http://www.ayqy.net/cms/wordpress/wp-content/uploads/2019/09/react-native-threading-model-1024x576.jpg" alt="React Native threading model" width="625" height="352"></p>
<p>线程间交互关系如下:</p>
<p class="sync-line" data-line="44">&nbsp;</p>
<p><img src="http://chain-react-bridging.surge.sh/dist/96efedea67e784036f946c487a06cdc9.png" alt=""></p>
<p class="sync-line" data-line="45">&nbsp;</p>
<p>P.S.图中的 queue 指的是GCD dispatch queue,可以简单理解为线程(虽然不正确)</p>
<p class="sync-line" data-line="48">&nbsp;</p>
<h2 id="%E4%B8%89%E5%90%AF%E5%8A%A8%E8%BF%87%E7%A8%8B" class="mume-header">三.启动过程</h2>
<p>时序上,App 启动时初始化 React Native 运行时环境(即 Bridge),Bridge 准备好之后开始 run JS,最后开始 Native 渲染:</p>
<p class="sync-line" data-line="52">&nbsp;</p>
<p><img src="https://facebook.github.io/react-native/blog/assets/RNPerformanceStartup.png" alt=""></p>
<p class="sync-line" data-line="53">&nbsp;</p>
<p>完整的启动过程是这样:</p>
<p><img class="size-large wp-image-2015" src="http://www.ayqy.net/cms/wordpress/wp-content/uploads/2019/09/react-native-app-start-up-flow-1024x576.jpg" alt="React Native App start up flow" width="625" height="352"></p>
<p>其中,上半部分是初始化 Bridge 的过程:</p>
<p class="sync-line" data-line="60">&nbsp;</p>
<p><img src="https://tadeuzagallo.com/blog/react-native-bridge/initialisation.svg" alt=""></p>
<p class="sync-line" data-line="61">&nbsp;</p>
<p>分为 4 个部分(这些操作都在启动时进行):</p>
<ul>
<li>
<p>加载 JavaScript 代码:开发模式下从网络下载,生产环境从设备存储中读取</p>
</li>
<li>
<p>初始化 Native Modules:根据 Native Module 注册信息,加载并实例化所有 Native Module</p>
</li>
<li>
<p>注入 Native Module 信息:取 Native Module 注册信息,作为全局变量注入到 JS Context 中</p>
</li>
<li>
<p>初始化 JavaScript 引擎:即 JavaScriptCore</p>
</li>
</ul>
<p>Bridge 建立之后,JavaScript 代码开始执行,渲染用户界面并实现业务功能</p>
<p class="sync-line" data-line="74">&nbsp;</p>
<h2 id="%E5%9B%9B%E6%B8%B2%E6%9F%93%E6%9C%BA%E5%88%B6" class="mume-header">四.渲染机制</h2>
<p><img class="size-large wp-image-2016" src="http://www.ayqy.net/cms/wordpress/wp-content/uploads/2019/09/react-native-threads-1024x576.jpg" alt="React Native threads" width="625" height="352"></p>
<p>JS 线程将视图信息(结构、样式、属性等)传递给 Shadow 线程,创建出用于布局计算的 Shadow Tree,Shadow 线程计算好布局之后,再将完整的视图信息(包括宽高、位置等)传递给主线程,主线程据此创建 Native View</p>
<p>对于用户输入,则先由主线程将相关信息打包成事件消息传递到 Shadow 线程,再根据 Shadow Tree 建立的映射关系生成相应元素的指定事件,最后将事件传递到 JS 线程,执行对应的 JS 回调函数,即:</p>
<p><img class="size-large wp-image-2017" src="http://www.ayqy.net/cms/wordpress/wp-content/uploads/2019/09/react-native-ui-interaction-1024x576.jpg" alt="React Native UI interaction" width="625" height="352"></p>
<p>至此,一切都清楚了</p>
<p class="sync-line" data-line="86">&nbsp;</p>
<h3 id="%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99" class="mume-header">参考资料</h3>
<ul>
<li>
<p>Part One: React and Codegen</p>
</li>
<li>
<p>Performance</p>
</li>
<li>
<p>React Native Scheduling</p>
</li>
<li>
<p>Bridging in React Native</p>
</li>
<li>
<p>React Native - Fabric review-2018-07-25</p>
</li>
<li>
<p>How React Native constructs app layouts (and how Fabric is about to change it)</p>
</li>
<li>
<p>Optimising React Native: Tools and Tips</p>
</li>
<li>
<p>React Native: Under the Hood:以及配套 Slides</p>
</li>
<li>
<p>React Native Architecture Overview:以及配套 Slides</p>
</li>
<li>
<p>Chain React 2017: Breaking Down Bridging in React Native by Peggy Rayzis:以及配套 Slides,以及文字版</p>
</li>
</ul>
<p class="sync-line" data-line="109">&nbsp;</p>
<h3 id="%E6%9C%89%E6%89%80%E5%BE%97-%E6%9C%89%E6%89%80%E6%83%91%E7%9C%9F%E5%A5%BD" class="mume-header">有所得、有所惑,真好</h3>
<p>点击关注,你将收获一系列「用<strong>心</strong>原创」的高质量技术文章,主题包括但不限于前端、Node.js以及服务端技术</p>
<p>本文首发于&nbsp;ayqy.net&nbsp;,原文链接:http://www.ayqy.net/blog/react-native-architecture-overview/</p>

</div>
<div id="MySignature" role="contentinfo">
    <img src="http://pic.cnitblog.com/face/610080/20140608102954.png" style="vertical-align: top;
float: left;
margin: 7px;
border: 0;"/>
<原创>黯羽轻扬 欢迎转载 不必注明原文出处&lt/原创&gt<br>
<声明>作者水平有限 错误在所难免 欢迎指正&lt/声明&gt<br><br><br>
来源:https://www.cnblogs.com/ayqy/p/react-native-architecture-overview.html
頁: [1]
查看完整版本: React Native 架构一览