渲染流水线三个阶段

  • 渲染(Render):在 JavaScript 中,React 执行那些产品逻辑代码创建 React 元素树(React Element Trees)。然后在 C++ 中,用 React 元素树创建 React 影子树(React Shadow Tree)。
  • 提交(Commit):在 React 影子树完全创建后,渲染器会触发一次提交。这会将 React 元素树和新创建的 React 影子树的提升为“下一棵要挂载的树”。 这个过程中也包括了布局信息计算。
  • 挂载(Mount):React 影子树有了布局计算结果后,它会被转化为一个宿主视图树(Host View Tree)。

渲染流水线的各个阶段可能发生在不同的线程中:

渲染三阶段-流程

渲染流水线存在三种不同场景:

  1. 初始化渲染;
  2. React状态更新;
  3. React Native渲染器的状态更新。

RNOH的渲染三阶段实例化介绍

RNOH 中,以一次典型的渲染流程(点击按钮,跳转到包含1500个text组件的页面)为例,从 Trace 来实例化说明渲染三阶段:

渲染三阶段-trace

渲染(Render)

  1. 手指点击界面控件,然后抬起手指(上图步骤①),此事手势事件点击会被传递到 RNOH JS线程,线程中响应点击事件,在 JS 虚拟机中开始执行前端 React 代码,React 代码会加载并执行一些前端业务逻辑所必须的依赖函数(上图步骤②)。
  2. React 的业务代码在创建组件时,会通过 JSI(Javascript与原生C++代码相互调用的接口层)调用到 RN Common 中的 ShadowTree 创建,这一段的流程中涉及频繁的 JS 原生相互调用(上图步骤③)。

提交(Commit)

  1. 一旦完成 ShadowTree 构建,会通过 Yoga 引擎进行布局计算(上图步骤④)。对于 UI 组件的布局计算,在 Yoga 引擎中直接完成,对于文本的布局计算,Yoga 引擎通过回调函数 TextMeasurer::measure(),由原生侧来完成,完成后的结果通过 AttributedString ParagraphAttributes LayoutConstraints 这 3 个对象传回 Yoga。
  2. ShadowTree 创建并布局完成后(new tree),会与上一次创建的 ShadowTree(old tree)进行对比,对比的核心函数是:calculateShadowViewMutationsV2()(上图步骤⑤)。
  3. 新老 ShadowTree 对比完成后,会生成差异结果,RN JS 调用主线程函数,将差异结果送到主线程启动渲染(上图步骤⑥)。

挂载(Mount)

  1. 需原生端渲染的组件,以 Mutation 对象表达,在主线程处理每一个 mutation 对象。
  2. 通过 MountingManagerCAPI::handleMutation() 执行具体的 mutation 处理,包含的方法为:CREATE, DELETE, UPDATE, INSERT, REMOVE, REMOVE_DELETE_TREE(按子树进行删除,当前尚不支持)。
  3. REMOVE 方法会将 ArkUI 组件 Node 从组件树上移下来,此时界面刷新,对应的组件不再呈现;DELETE 方法触发组件 Node 删除。
  4. CREATE 方法创建 ArkUI 组件 Node,但并不刷新界面;INSERT 方法将组件 Node 挂到组件树上,此时界面刷新;UPDATE 会更新 Node 的属性,同时也会触发界面刷新。
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐