什么是 Virtual DOM?
本质来说:Virtual DOM是一个JavaScript对象,通过对象的方式来表示DOM结构
为什么要用virtual Dom
优势:当页面内容需要发生变动时,React可以通过对新旧虚拟DOM的比对,计算出如何以最小的代价操作真实DOM,以提高性能,input select值不会被重新覆盖或失去焦点,跨平台等。
劣势:reactd的jsx 代码在初始化阶段要通过 babel 转换成 Virtual DOM 在通过 React.createElement 创建 Virtual DOM 每一个dom节,在appendChild插入到页面上。这一过程是比原生dom直接渲染慢的
React 为什么要引入 Fiber 架构?
React V15之前(使用二叉树结构) 会递归比对VirtualDOM树, 这个过程 React 会 (Reconcilation协调)的方式进行,找出需要变动的节点,然后同步更新它们(这个过程不能中断),在 Reconcilation 期间如果,React 会霸占着浏览器资源,计算结果超过了16ms的事件,一则会导致用户触发的事件得不到响应, 二则会导致掉帧,用户可以感知到这些卡顿。
在 react v16后 引入 Fiber 使用(链表结构)后 递归比对VirtualDOM树时,划分一个个更小的执行单元,使用window.requestIdleCallback 浏览器执行完这个方法后,返回(timeRamining)当前帧还剩多少时间供用户使用 ,如果此帧的剩余时间大于0(有空闲时间)或者已经超时,且当时存在任务,则直接执行该任务。如果没有剩余时间,则应该放弃执行任务控制权,把执行权交还给浏览器。如果多个任务执行总时间小于空闲时间的话,是可以在一帧内执行多个任务的。
fiber 对象主要的属性
// 链表结构
{
//作为静态的数据结构 保存节点的信息
this.tag = tag;//对应组件的类型
this.key = key;//key属性
this.elementType = null;//元素类型
this.type = null;//func或者class
this.stateNode = null;//真实dom节点
//作为fiber数架构 连接成fiber树
this.return = null;//指向父节点
this.child = null;//指向child
this.sibling = null;//指向兄弟节点
this.index = 0;
this.ref = null;
//用作为工作单元 来计算state
this.pendingProps = pendingProps;
this.memoizedProps = null;
this.updateQueue = null;
this.memoizedState = null;
this.dependencies = null;
this.mode = mode;
//effect相关
this.effectTag = NoEffect;
this.nextEffect = null;
this.firstEffect = null;
this.lastEffect = null;
//优先级相关的属性
this.lanes = NoLanes;
this.childLanes = NoLanes;
//current和workInProgress的指针
this.alternate = null;
}
react fiber 链表结构
- 链接在遍历时可在中断时保存栈内存可方便恢复下次继续遍历,二叉树在中断后不能保存中断位置。
- 二叉树特点(存取速度快,插入删除元素慢,有空间限制),链表特点(存取速度慢,插入删除元素快,无空间限制)链表在频繁删除和插入时性能更加。
hooks
hook 结构有哪些字段?
const hook: Hook = {
memoizedState: null,//对于不同hook,有不同的值
baseState: null,//初始state
baseQueue: null,//初始queue队列
queue: null,//需要更新的update
next: null,//下一个hook
};
为什么hooks不能写在条件判断中
hook会按顺序存储在链表中,如果写在条件判断中,就没法保持链表的顺序
在FunctionComponent中,多个hook会按顺序形成hook链表,如果写在if 中会会导致链表顺序的破坏。保存在Fiber的memoizedState的上,而需要更新的Update保存在hook.queue.pending中。