react16之前存在什么问题

279 阅读3分钟

react 是一个用于构建用户界面的javascript库

react的基本原理:构建虚拟DOM,新旧DOM树对比,计算出差异,更新到真实DOM中

渲染流程:由jsx通过babel转成React.createElement,createElement函数对key、ref、children等属性进行处理,最终构成了一个ReactElement对象(也就是虚拟DOM),ReactDOM.render将生成好的虚拟DOM渲染到指定容器上。

1. Fiber 出现的目的是什么

为了提高 React 渲染页面的效率,减少页面卡顿,提升用户体验。

2. 在 Fiber 出现之前 React 存在什么问题

在 React 15 版本中采用的是 Virtual DOM 对比方案,通过对比 Virtual DOM 找出差异部分,从而只将差异部分更新到页面中,避免更新整体 DOM 以提高性能。

在 Virtual DOM 比对的过程中 React 使用了采用深度优先遍历的方式,循环递归遍历DOM树,递归调用的过程不能被终止,如果 Virtual DOM 的层级比较深,递归比对的过程就会长期占用主线程,而 JavaScript 又是单线程,不能同时执行多个任务,其他任务只能等待执行,而且 JavaScript 的执行和 UI 的渲染又是互斥的,此时用户要么看到的就是空白界面,要么就是有界面但是不能响应用户操作,处于卡顿状态,用户体验差。

核心就是递归比对的过程长期占用主线程产生了性能问题。

3. Fiber 如何解决性能问题

在 Fiber 架构中 React 放弃了递归调用,采用循环来模拟递归,因为循环可以随时被中断。

React 利用浏览器空闲时间执行比对任务, 解决了 React 执行比对任务长期占用主线程的问题。

React 在执行完一个任务单元后,查看是否有其他的高优先级任务,如果有,放弃占用主线程,先执行优先级高的任务。

Fiber 是一个执行单元

在 React 15 中,将 VirtualDOM 树整体看成一个任务进行递归处理,任务整体庞大执行耗时且不能中断。

在 React 16 中,将整个任务拆分成了一个一个小的任务进行处理,每一个小的任务指的就是一个 Fiber 节点的构建。

任务会在浏览器的空闲时间被执行,每个单元执行完成后,React 都会检查是否还有空余时间,如果有就交还主线程的控制权

4. Fiber构建链表的过程

react16之后,采用链表比对,需要构建fiber对象和链表,为每一个react元素构建fiber对象。

首先以下整个遍历的过程都会构建fiber对象,当遍历完DOM树左支的最后一个叶子节点,开始构建链表,左支最后的那个叶子节点是链表第一个节点,接下来看这个节点是否有兄弟节点,如果有兄弟节点,就找兄弟节点的子节点,再到兄弟节点,如果没有兄弟节点,就到父节点,一直循环,一直到根节点。

5. 既然比对的过程从递归变成了可以中断的循环,那么 React 是如何解决中断更新时 DOM 渲染不完全的问题呢?

其实根本就不存在这个问题,因为在整个过程中,比对的工作是在内存中完成的是可以被打断的,渲染器的工作被设定成不可以被打断,所以不存在DOM 渲染不完全的问题

6. vue和react

未完:插图