ReactNative进阶(四):ReactNative 原理剖析之JS 层渲染 diff 算法_react native匹配dom节点

结尾

学习html5、css、javascript这些基础知识,学习的渠道很多,就不多说了,例如,一些其他的优秀博客。但是本人觉得看书也很必要,可以节省很多时间,常见的javascript的书,例如:javascript的高级程序设计,是每位前端工程师必不可少的一本书,边看边用,了解js的一些基本知识,基本上很全面了,如果有时间可以读一些,js性能相关的书籍,以及设计者模式,在实践中都会用的到。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

html5

文章目录

一、前言

ReactNative启动完成之后,就会加载jsbundle中的js代码,进入js层渲染。此篇博文重点讲解 ReactNative JS 层渲染涉及的 diff 算法。

使用 React 写过 WebReactNative的,很明显感觉到:除了组件命名不一样之外,生命周期、刷新机制等几乎是完全一样的,这也就是 Facebook 所说的“learn once, write anywhere”,只要会写 React,就能无压力同时开发 WebReactNative。而 React 框架相对于传统的纯 js 开发所具有的优势,核心就是组件化diff 算法刷新机制,这两点极大的提升了开发效率和程序的渲染性能。

React 通过setState界面刷新时,并不会马上对所有真实的 DOM 节点进行操作,而是先通过 diff 算法计算。然后,再对有变化的 DOM 节点进行操作(native 是对原生 UI 层进行操作),具体刷新步骤如下:

  1. state 变化,生成新的 Virtual Dom
  2. 比较 Virtual Dom 与之前 Virtual Dom 的异同;
  3. 生成差异对象;
  4. 遍历差异对象并更新真实 DOM;

二、Virtual Dom 概述

DOM 操作很耗时,使用 JS 对象来模拟 DOM Tree,在渲染更新时,先对 JS 对象进行操作,再批量将 JS 对象 Virtual Dom 渲染成 DOM Tree,从而减少对 DOM 的操作,提升性能。

整个 diff 算法,都是基于 Virtual Dom 的,那什么是 Virtual Dom 呢?

Virtual Dom 本质是用来模拟 DOMJS 对象。一般含有标签名(tag)、属性(props)和子元素对象(children)三个属性,不同框架对属性的命名会有点差别,但表达的意思是一致的。

例如:对于以下一段代码,怎么映射成对应的 Virtual Dom 呢?

<A>
  Hello World
  <B>
    <C key="key-C" style={{ width: 100 }} />
    <D key="key-D" style={{ color: 'red' }} />
  </B>
</A>

在该例中,按三个属性分析如下:

  • A、B、C、D是标签(tag
  • keystyle是属性(props
  • 节点B是节点A的子元素对象(children
  • 节点C和D是节点B的子元素对象(children
    最后,映射出来的 js 对象(Virtual Dom)如下:
    在这里插入图片描述

三、React Diff 算法的两个假设

为什么 React Diff 算法相对于传统的 diff 算法,复杂度从 O(n^3)降到 O(n)
React基于以下的两个假设,减少了不必要的计算。

1.两个相同组件将会生成相似的DOM结构,两个不同组件将会生成不同的DOM结构。
2.对于同一层次的一组子节点,它们可以通过唯一的id进行区分。

对于假设 1: 两个相同组件,一般指的是相同的类,包含 React 官方定义的组件(ViewText)和程序员自定义的组件(这也是React 组件化开发的一个原因,可以提升 diff 算法的效率);
对于假设 2: 一般指的是使用map遍历生成的列表视图或者使用ListView/FlatList等列表组件;

React Diff 算法的实现,几乎都是基于以上两个假设进行优化的,接下来来看看 React Diff 算法的具体实现原理。

四、React Diff 算法实现

基于以上的两个假设,React Diff 算法的实现,主要可以分相同类型节点的比较、不同节点类型的比较、列表节点的比较三类情况,这里也主要针对这三类情况进行分析。

4.1 相同类型节点的比较

修改节点 A 的属性 style
在这里插入图片描述

依据假设 1 的前半句:两个相同组件将会生成相似的 DOM 结构,由于新旧节点类型相同(tag 都是 A),DOM 结构没有发生变化,React 仅对属性(style)进行重设(将 styleBefore 改成将 styleAfter)从而实现节点的转换和界面的更新

这种情况,通过这类diff算法计算后,会调用 NativeupdateView 来刷新界面。

4.2 不同节点类型的比较

将节点 A 及其子节点(红色标签部分)改成节点 D 的子节点。

为了方便分析,首先抽象成 DOM tree 节点模型。

依据假设假设 1 的后半句:两个不同组件将会生成不同的 DOM 结构,当发现节点已经不存在,则该节点及其子节点会被完全删除掉,不会用于进一步的比较,因此,React 会直接删除前面的节点,然后创建并插入新的节点。

自学几个月前端,为什么感觉什么都没学到??


这种现象在很多的初学者和自学前端的同学中是比较的常见的。

因为自学走的弯路是比较的多的,会踩很多的坑,学习的过程中是比较的迷茫的。

最重要的是,在学习的过程中,不知道每个部分该学哪些知识点,学到什么程度才算好,学了能做什么。

很多自学的朋友往往都是自己去找资料学习的,资料上有的或许就学到了,资料上没有的或许就没有学到。

这就会给人一个错误的信息就是,我把资料上的学完了,估计也-就差不多的了。

但是真的是这样的吗?非也,因为很多人找的资料就是很基础的。学完了也就是掌握一点基础的东西。分享给你一份前端分析路线,你可以参考。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

还有很多的同学在学习的过程中一味的追求学的速度,很快速的刷视频,写了后面忘了前面,最后什么都没有学到,什么都知道,但是什么都不懂,要具体说,也说不出个所以然。

所以学习编程一定要注重实践操作,练习敲代码的时间一定要多余看视频的时间。

g.csdnimg.cn/img_convert/15be8206a9f6e5bd9e8e930303b613ee.png)

还有很多的同学在学习的过程中一味的追求学的速度,很快速的刷视频,写了后面忘了前面,最后什么都没有学到,什么都知道,但是什么都不懂,要具体说,也说不出个所以然。

所以学习编程一定要注重实践操作,练习敲代码的时间一定要多余看视频的时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值