react fiber个人理解

聂琨
2023-12-01

react fiber
首先要从jsx说起,
jsx是javascript的一种语言扩展,具备js的能力,且可以插入变量、进行一些运算等。看起来和html很像,需要借助Babel转换。
react.createElement()方法负责接收jsx被babel转换后的参数进行解析最终返回一个虚拟dom
React.render(vdom,container)方法接收一个虚拟dom对象和一个真实的DOM容器作为虚拟dom渲染完成后的挂载点,主要作用就是将虚拟dom渲染为真实的dom并挂载到容器下

react fiber就是把整个更新过程碎片化,在每个小任务执行完成之后,把执行权交还给主线程,这样唯一的线程就不会被独占,让其他的任务依然有运行的机会

之前的render方法在更新的时候是进行递归操作的,且该过程无法被打断,如果有大量的节点需要更新,就会出现长时间占用js主线程,由于js线程和GUI线程是互斥的,导致可能会看到UI卡顿

所以要实现fiber架构主要解决两个问题:
一:保证任务在浏览器空闲时执行
① requestIdleCallback
依赖浏览器提供的api requestIdleCallback()
requestIdleCallback(callback)浏览器空闲时会执行传入的回调函数
回调函数收到一个deadline对象,该对象的timeReamaining()方法可以获取到浏览器的空闲时间,如果有空闲时间,就执行一段小任务,如果时间不足了,就在次requestIdleCallback等待执行
二:任务碎片化
② 链表结构
时由于虚拟dom是树结构被打断后无法恢复之前任务继续执行,所以需要一种新的数据结构,即链表结构,链表可以包含多个指针,可以轻松找到下一个节点,从而恢复任务执行,Fiber采用的链表包含3个指针,return指向父Fiber节点,child指向大儿子Fiber节点,sibling指向兄弟Fiber节点。一个Fiber节点对应一个任务节点

Fiber具体实现:
render方法中将不再递归遍历虚拟dom,创建真实dom并加入到容器中。我们需要在render()中初始化一个rootFiber,并把rootFiber当作currentFiber,首次渲染时,只有rootFiber有真实的dom(容器)
其他的都需要创建dom,形成链表
最后提交阶段,提交整个根Fiber并渲染出界面,将子fiber的dom加入到父fiber的dom中

实现dom-diff 主要就是对比两个Fiber节点的type(div、span)是否一致,如果一致则进行复用上一次的dom节点,然后更新dom属性即可

 类似资料: