1. reactDom.render 和 setState 做了什么

前置知识

  • react里有两种元素:DOM元素、组件元素
  • 组件元素的render方法将会把组件转换成真正的DOM树(此时还是指的虚拟dom)

递归遍历一个组件树以获取虚拟DOM树的过程称之为reconciler解调

  1. reactDom.render 和 setState 时,需要更新页面,也就会触发解调
  2. setState的时候除了解调,还需要对比新旧树的区别,然后将更改的地方应用到当前树,即更新状态。

2. 为什么是fiber

前置知识

浏览器的js执行和UI绘制是同一个线程执行的。这是因为js可能会改变DOM,为了保证DOM正确展示,所以之前就设计成单线程。

之前的(react15)解调模式是整个虚拟DOM树递归执行解调,全部解调完毕后去进行patch和UI更新。当js递归整个树这个行为占用浏览器线程太久的时候,UI就会卡顿。这是旧的同步更新机制。

fiber

为了解决递归解调占用太长时间这个问题,react团队推出了fiber架构,利用了fiber栈(链表)的数据结构,将之前的递归行为改成可以中断、并恢复执行的行为:

  • 为不同的工作设置优先级
  • 在适当的时候暂停任务,释放占用的线程,让浏览器接管UI渲染
  • 在浏览器空闲的时候,继续执行栈内剩下的任务

利用的是浏览器的一个新api,requestIdleCallback,在每个16.67ms周期内,如果浏览器执行完js、UI渲染之后还有剩余的事件,就会执行requestIdleCallback里面的任务,任务本身会收到当前周期还剩多少时间可以用来执行。— 时间分片 当然由于这个api之前只有chrome实现了,react团队自己实现了一个类似的方法。

总结: fiber本身是一个对象,描述了虚拟dom,并且以链表的形式链接了父元素、子元素、兄弟元素。 但是fiber的链表特性是为了实现时间分片的结果。

https://www.jianshu.com/p/ed14378d8867 https://juejin.cn/post/6844903975112671239#heading-0 https://zhuanlan.zhihu.com/p/297971861 https://www.jianshu.com/p/a0ac4b29969e