计算机领域中有两个你们很熟悉也很重要的概念:进程(Process)和线程(Thread),算法
进程:就是包换上下文切换的程序执行时间总和 = CPU加载上下文+CPU执行+CPU保存上下文,一个进程能够有多个线程。 线程是共享了进程的上下文环境,的更为细小的CPU时间段。线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位
可是在计算机科学中还有一个概念叫作Fiber,英文含义就是“纤维”,意指比Thread更细的线,也就是比线程(Thread)控制得更精密的并发处理机制。浏览器
React Fiber 并非所谓的纤程(微线程、协程),而是一种基于浏览器的单线程调度算法,背后的支持 API 是大名鼎鼎的:requestIdleCallback。并发
Fiberl是一种将 recocilation (递归 diff),拆分红无数个小任务的算法;它随时可以中止,恢复。中止恢复的时机取决于当前的一帧(16ms)内,还有没有足够的时间容许计算。函数
咱们都知道,React最引觉得豪的技术,可能就是虚拟DOM,经过虚拟DOM,能够将原来十分耗时的DOM操做简化,从而提升页面性能。虚拟DOM的背后,须要的是一套快速对比(diff)出更新的算法。在React 16版本以前,React 经过递归比对新旧DOM树来完成这个过程,而且这个过程是同步进行的。虽然React已经对这个diff算法作了不少优化,可是挡不住组件个数多啊。性能
因此,当多个组件(100个以上)同步进行更新操做的时候,浏览器将处于一种“假死”状态,在这个状态将没法处理其余事件,因此致使页面卡顿等影响体验的问题。优化
经过使用React fiber技术,优化了虚拟DOM的diff算法,同时也建立真实DOM和组件渲染拆分为无数的小分片任务,每次执行完一个小分片后就冒泡看看有没有优先级比较高的任务,有的话就去执行优先级比较高的任务,没有就继续执行下一个分片任务。this
上面咱们说的,React fiber 把建立真实DOM和组件渲染拆分红小分片来轮训执行,若是有新的优先级较高的任务,就先执行高优先级的任务,而后再来执行分片,这样就会引发一个新的问题:一个更新任务尚未完成,就被另外一个更高优先级的更新过程打断了怎么办? spa
这时候,优先级高的更新任务会优先处理完,而低优先级更新任务所作的工做则会彻底做废,而后等待机会重头再来。线程
由于一个更新过程可能被打断,因此React Fiber一个更新过程被分为两个阶段(Phase):第一个阶段Reconciliation Phase和第二阶段Commit Phase。code
在第一阶段Reconciliation Phase,React Fiber会找出须要更新哪些DOM,这个阶段是能够被打断的;可是到了第二阶段Commit Phase,那就一气呵成把DOM更新完,毫不会被打断。
这两个阶段大部分工做都是React Fiber作,和咱们相关的也就是生命周期函数。
上面咱们说到,使用React Fiber技术后,生命周期函数可能在一次更新过程当中不止一次的被调用。
第一阶段可能会调用下面这些生命周期函数,说是“可能会调用”是由于不一样生命周期调用的函数不一样。
componentWillMount componentWillReceiveProps shouldComponentUpdate componentWillUpdate
下面这些生命周期函数则会在第二阶段调用。
componentDidMount componentDidUpdate componentWillUnmount
经过以上分析咱们了解到,原来的React 生命周期函数中:
componentWillMount componentWillReceiveProps componentWillUpdate
这三个应该为可能不止一次被调用,以前可能会有部分比较耗时的业务代码(操做真是DOM)写在这些函数里,当不止一次调用这些函数的时候,可能会一块儿很大的新能问题。
所以,React 16+ 引入了一个新的静态生命周期函数 getDerivedStateFromProps 来将属性从props中添加(同步)到state中,这是一个“静态函数”,它不属于任务一个实例,内部的 this并不指向组件自己,其实就是强迫把这个函数变成一个纯函数
getSnapshotBeforeUpdate这个函数在 commit阶段执行,咱们知道到commit阶段后,这个函数只会执行一次,因此能够在这里完成那些必须的操做真实DOM的操做。