react渲染机制

初次渲染和更新

  • 顶层来看,通过调用ReactDom.render( )实现渲染。
  • ReactDom.render方法根据传入的组件或元素,生成虚拟dom,然后生成真实dom 节点插入到目标节点。
  • 更新时,生成新的虚拟dom。每个虚拟dom会对应一个fiber对象。虚拟dom维护的组件的状态、与真实dom的对应关系,每个虚拟元素对应一个fiber节点。在fiber对象上通过diff算法,确定要更新的内容,再渲染到真实dom上,减少了频繁的dom操作。

虚拟dom的构建

jsx中的自定义组件和原生dom组件经过babel转译后变为React.createElement()的实 现。调用组件render方法时,调用React.createElement( )生成react元素(react element)。根据react元素type字段调用不同的组件对象生成方法。

  • 对于原生的dom元素

    React调用reactDOMComponent类的mountComponent方法生成真实dom。
  • 对自定义组件

    调用ReactCompositeComponentWrapper类的mountComponent,实例化组件。遇到嵌套的原生dom元素时使用上述处理方法。通过层层递归处理,最终都会调用到
    ReactDOMComponent类的mountComponent方法得到真实DOM。

虚拟dom优点

  • 提高开发效率,不用直接操作dom
  • 虚拟dom可以react diff算法结合,重新渲染时通过计算,实现更高效的更新。
  • react在虚拟dom上提供了自己的事件机制,跨浏览器兼容。

react diff算法

老的diff算法三个策略

  • Web UI 中 DOM 节点跨层级的移动操作特别少,可以忽略不计。
  • 拥有相同类的两个组件将会生成相似的树形结构,拥有不同类的两个组件将会生成不同的树形结构。
  • 对于同一层级的一组子节点,它们可以通过唯一 id 进行区分。

基于以上三个前提策略,React 分别对 tree diff、component diff 以及 element diff 进行算法优化。

react16 diff策略

所谓diff,就是新旧节点的比较。从链表头部开始,层层遍历,以新节点为标准,确定现有节点如何做到最小程度的修改,实现节点的复用。所要进行的增加、删除、修改、移动都是 在同 一层级上进行的。

需要diff的节点类型

textNode

判断当前层级下的对应节点是否为文本节点
1.是的话直接复用。
2.不是的话,删除当前节点,重新创建。(不会立即操作,会先标记,在后续的commit阶段操作)。

单个reactElement
判断当前节点能否复用
  • 节点的type字段和key字段都相同时,表明当前节点可复用。
  • 遍历时先对比该层第一个节点,不符合时,对比它的兄弟节点。
  • type不同、key相同时,不会进行后续对比;未找到时,新建节点。
节点数组

1.第一遍先遍历新节点数组,按index所对应元素依次对比,遇到不可复用元素时结束遍历。
2.按上步结果增添删除现有节点数组。新节点数组遍历完时,删除现有数组多余节点;现有数组遍历完时,创建新节点所需数组。
3.现有数组按key或index放入Map里,遍历新数组,重新插入数组元素,实现数组元素按顺序移动。

可迭代的children

与节点数组的处理相似。
来源

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 文章首发于个人博客 这是我 Deep In React 系列的第二篇文章,如果还没有读过的强烈建议你先读第一篇:详...
    勿忘巛心安阅读 1,069评论 1 2
  • 3. JSX JSX是对JavaScript语言的一个扩展语法, 用于生产React“元素”,建议在描述UI的时候...
    pixels阅读 2,925评论 0 24
  • 正式开始系统地学习前端已经三个多月了,感觉前端知识体系庞杂但是又非常有趣。前端演进到现在对开发人员的代码功底要求已...
    Obvious_96阅读 7,269评论 8 19
  • 前言 这次我们先巩固知识,再看问题。刚刚入门的前端程序员,或者其他语言的程序员,一般都会先学习该语言的变量类型。在...
    南宫__阅读 1,681评论 0 2
  • 原文:https://segmentfault.com/a/1190000010686582 React框架使用的...
    宋00阅读 850评论 0 0