ReactNative 知識小集(2)-渲染原理

初學ReactNative的同學肯定特別好奇, 我寫的每一段布局, 每一行樣式是如何被渲染到手機上的. 其實過程和webview渲染H5的過程有一些類似了. 而且最終調用的都是手機底層的OpenGL ES 庫在渲染了. 只不過 WebView 採用的Webkit內核來解析和繪製你寫的

你寫的代碼是如何被渲染的

1. JSX -> ReactElement

AS you know, React.js 發明了JSX 語法. JSX 只是一個語法糖,它用類似 XML 的語法來快速構建 Component. 最後JSX和 StyleSheet 對象都會被統統被轉化為ReactElement 對象.

From:

<Text style={{color: "blue"}} numberOfLines={2}> Hello World!</Text>

To:

React.createElement( Text, // type {style: {color: "blue"}, numberOfLines: 2}, // props "Hello World!" // ...children)

React.js 和 ReactNative 渲染過程異同

如果你了解React.js 的渲染過程(左半邊), 那麼去理解ReactNative 就很容易. 是從Render部分開始有了分歧, 之前的生命周期都是一樣的. 差別最大的是 render 函數里使用的View不同. 所以ReactNative 可以理解是 React.js 在Native上的一種表現. 因為那個O(n)複雜度的Diff演算法是基於 Virtual Dom, 應該就是 ReactElement. 所以這一部分也是共享的.

大家的差別就在於

  1. 如何把渲染指令發送給瀏覽器/Native
  2. 具體如何渲染.
  3. 瀏覽器對 StyleSheet 具體怎麼解析, 支持哪些 CSS3的屬性

2. ReactElement -> YogaNode

Yoga Facebook出品跨平台的布局引擎, 注意不是渲染引擎. 主文件只有6個 written by C, 然後出了各個平台UIKit,幫你跨平台. 他做的事情就是把 Flexbox布局 關鍵字以及 margin, padding, border, position 等影響布局的CSS 屬性, 解析成一個一個的 YogaNode, 然後生成一個YogaNodeTree.

兩句話解釋清楚:

  • 給他外部容器大小和繼承關係, 以及你想怎麼布局. (這不就是Virtual Dom的骨架么)
  • 生成一個帶有Tree, 每個節點都有計算好的 Frame(x,y, width, height)

我敢說瀏覽器渲染Dom的時候也有這一步過程. 不過除了布局,還要支持更多的CSS3屬性.因為它設計的不錯, 也足夠通用. Weex也在使用他

3. YogaNode -> Native Element

現在你有了布局描述, 你還需要做兩件事情.

  • 把布局文件變成具體的 UIView / View
  • 增加更多的樣式和標籤支持, 支持 圖片, 文字 等元素的渲染

將 YogaNode 的屬性對應成各個平台的基類

比如iOS上的RCTShadowView 就相當於把YodaNode的屬性轉變成Objc的類型.

哈哈 shadowView 這命名很React

對於各種不同對象的特殊樣式,ReactNative 在js側, 新建了不同的StyleProps, 在渲染不同的View的時候做對應, 這些都是和布局無關的.

其他 styleProps

這裡不同的是, animation 不是通過css 實現的. 而是提供了 NativeAPI

4. Render Queue

具體的繪製我們講到, 那麼大家肯定很好奇,這一條條的渲染指令是如何發送到Native測的.

下圖中的UIManger就在不停的CreateView和setChildren.

開啟MessageQueue.spy(), 程序初始化的log

他(MessageQueue)其實就是在將 Virtual Dom Tree 按照深度優先的方式便利, 發送給Native. 先變成YogaNode, 然後組裝成YogaNodeTree. 然後執行具體渲染的.

setState 引發的 Rerender的過程也是類似.

MessageQueue 承載的內容很多, 例如

  • network request,
  • network response
  • layout measurement
  • render request
  • user interaction
  • animation sequence instructions
  • invocation of native modules
  • I/O operation

接下來的文章會詳細介紹他

其他:

例子: 垂直水平居中,裡面兩個元素space-between

iOS上 ReactNative 最終渲染效果, RCT會有幾層的默認包裹, 原因未知?

對應的使用AutoLayout布局的效果

可以看到NSLayoutConstraint約束對象.


推薦閱讀:

VRay for SketchUp工業產品表現之煤油燈
VRay for SketchUp環境阻光(AO)的簡介與應用
##譯## The Comprehensive PBR Guide by Allegorithmic — Vol.2

TAG:ReactNative | 移动端 | 渲染 |