深入理解React中的虚拟Dom和Fiber
什么是虚拟Dom
个人理解来说它是一个JS对象对象内有某个DOM的详细信息,比如说当前节点对象的id class
等,当某个元素发生变化的时候,比如说它的message、ID、Class
就会重新遍历渲染当前这个节点对象,而不是整个所有的Dom
结构重新渲染
虚拟Dom和普通Dom节点不同之处
直接操作普通Dom
之前用过原生JS和jQuery开发,都是直接操作Dom节点,但是直接操作缺点非常明显,因为用户直观看到的是整个Dom节点,如果直接进行操作,没有经过计算,并且操作过多,则页面会一直闪来闪去、刷新白屏体验极差!
如何优化
既然修改的时候要发生状态变更,那就可以计算前后两次变更的具体地方,从而计算出最少的一个操作值这样对Dom操作是最少的,对用户体验和影响也是最小的。
为什么要用虚拟Dom
说到计算两个前后变更的地方,直接计算Dom节点也可,但是一个节点就会有几十几百的属性值,如果一一对比则计算量庞大浪费资源,直接构建虚拟Dom对象,只计算重要的属性值,成本低很多
import {React} from 'react'
const test = (
<div className = 'box-border'>
<h1>你</h1>
<h2>我</h2>
<FunctionComponent name='组件' />
</div>
)
在React中写JSX语法的时候用到Dom,它会编译成一个对象,这就是虚拟Dom,在React16中通过babel-loader进行编译,需要通过
import
引入react
,在Reatct17提供了自动引入,不需要每次手动引入
Fiber
fiber是在react16之后出现,在React16之前,开发组件和页面多,相应的Dom结构也会非常复杂
export function updateHostCompoent(wip){
if(!wip.stateNode){
wip.stateNode = document.createElement(wip.type)
}
reconcileChildren(wip,wip.props.children)
}
如果使用虚拟Dom来进行更新,则需要遍历,但是成本较高因为需要一个一个来遍历,如果在某一个遍历时间较长,很有可能会造成阻塞
为什么需要Fiber
Fiber
它是一个JS对象来描述虚拟的Dom节点
- 分级别进行处理,也就是把多个渲染任务的多个模块进行拆分
- 能够随时进行暂停、终止计算 总结来说,它是一个链表结构,给每个Dom节点给予不同的级别,通过循环来分别对比
function reconcileChildren(returnFiber,children){
const newChildren = isArray(children) ? children : [children]
for(let i =0;i<newChildren.length;i++){
const newChild = newChildren[i]
const newFiber = createFiber(newChild,returnFiber)
if(i == 0){
returnFiber.child = newFiber
}else{
proviousNewFiber.sibling = newFiber
}
proviousNewFiber = newFiber
}
}
newChildren
是当前节点的子节点对象,根据它来进行判断和循环遍历,如果它为空,则当前这个子节点就是新节点,反之则是新节点
转载自:https://juejin.cn/post/7106148927606358030