深入了解下React Fiber
原文:blog.logrocket.com/deep-dive-i…
本文核心
- 当react遍历tree的时候,在execStack里面干这件事
- 当updates到来的时候,他们在eventQueue里干这件事(调用setState)
- 只有当execStack为空了,eventQueue里的updates被得到执行(被延迟的setState在这里被真正执行)
Fiber就是彻底重构了上述Stack的流程,创建了virtual stack,里面加入了puase(暂停),resume(恢复),abort(终止)等
简单来说,之前React创建不可修改的objects的tree,通过递归遍历来处理
现在,React创建一个可修改的fiber nodes的tree,fiber node高效的来处理state,props,Dom Element等
因为fiber nodes可以改变所以不需要recreate,只需要cloen然后update
__同时不需要进行递归遍历,而是创建单链表然后parent-first和depth-first遍历
开始
“Stack” reconciler (Last-in,first out)
从ReactDOM.render(<App />, document.getElementById('root'))
开始。
<App/>
是个啥?<App/>
就是虚拟dom,描述了dom的类型,属性,子元素等信息。
React里面的Element有两种
- Dom Element
<div></div>
- Component Element
<Button></Button>
这两个类型都是简单的object,都是虚拟dom,告诉React应该渲染什么
React如何处理Component Element
<Form>
<Button>
Submit
</Button>
</Form>
复制代码
- React会根据Form,Button以及他们相应的props询问他们渲染了什么东西?
- 如果Form是一个function component,React就会调用render获取其渲染的内容
const Form = (props) => {
return(
<div className="form">
{props.form}
</div>
)
}
复制代码
- React会一直重复下去,直到获取所有Component Elment的渲染内容
- 这个获取Dom Element的过程就是我们熟知的reconciliation
- reconciliation结束后,React就可以直到了Dom的结构,
- 也就是说ReactDOM.render或setState都会触发reconciliation;在setState的时候,通过new state tree和rendered tree的diff,来最小粒度的更新current tree
如果setState立即被执行就很可能发生掉帧
现在的设备fps一般在60fps,也就是1/60≈16ms每帧,假如React的渲染时间大于了16ms,那么这次渲染到了16ms的时候并没有拿到结果,这个渲染就不会被正常的渲染出来,这就是掉帧,掉帧就引起了卡顿。然而现实中我们只有10ms的时间来完成渲染,因为浏览器还要做其他的事情。
Fiber是如何工作的
Fiber的4个目标
- 给不同类型的渲染分配不同的优先级
- 暂停渲染,之后再回来
- 终止渲染,如果不再需要了
- 重复利用已经计算好的渲染
Fiber的挑战在于JavaScript引擎的工作原理,如何才能多线程的工作。
先了解下JavaScript引擎的工作原理(执行环境)
- JavaScript引擎开始的时候创建全局的执行环境(window in browser, global in node)
execStack: [globalExecContext]
function a() {
console.log("i am a")
b()
}
function b() {
console.log("i am b")
}
a()
复制代码
- 执行a的时候,创建a的执行环境并push到全局中
execStack: [aExecContext, globalExecContext]
- 因为b在a中执行,也创建b的执行环境并push到全局中
{execStack: [bExecContext, aExecContext, globalExecContext]}
- 异步的时候有个eventQueue
{execStack: [aExecContext, globalExecContext], eventQueue: {http}
- JavaScript引擎只会在execStack为空或者只有globalExecContext的时候才会去遍历eventQueue
回到React的Stack Reconciler
- 当react遍历tree的时候,在execStack里面干这件事
- 当updates到来的时候,他们在eventQueue里干这件事(调用setState)
- 只有当execStack为空了,eventQueue里的updates被得到执行(被延迟的setState在这里被真正执行)
Fiber到底干了啥
Fiber就是彻底重构了上述Stack的流程,创建了virtual stack,里面加入了puase(暂停),resume(恢复),abort(终止)等
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END