美文网首页
3.Fiber(我是在内存中的dom)

3.Fiber(我是在内存中的dom)

作者: 全栈潇晨 | 来源:发表于2021-02-17 08:29 被阅读0次

    人人都能读懂的react源码解析(大厂高薪必备)

    3.Fiber(我是在内存中的dom)

    视频课程&调试demos

    视频课程的目的是为了快速掌握react源码运行的过程和react中的scheduler、reconciler、renderer、fiber等,并且详细debug源码和分析,过程更清晰。

    视频课程&调试demos

    视频课程的目的是为了快速掌握react源码运行的过程和react中的scheduler、reconciler、renderer、fiber等,并且详细debug源码和分析,过程更清晰。

    视频课程:进入课程

    demos:demo

    课程结构:

    1. 开篇(听说你还在艰难的啃react源码)
    2. react心智模型(来来来,让大脑有react思维吧)
    3. Fiber(我是在内存中的dom)
    4. 从legacy或concurrent开始(从入口开始,然后让我们奔向未来)
    5. state更新流程(setState里到底发生了什么)
    6. render阶段(厉害了,我有创建Fiber的技能)
    7. commit阶段(听说renderer帮我们打好标记了,映射真实节点吧)
    8. diff算法(妈妈再也不担心我的diff面试了)
    9. hooks源码(想知道Function Component是怎样保存状态的嘛)
    10. scheduler&lane模型(来看看任务是暂停、继续和插队的)
    11. concurrent mode(并发模式是什么样的)
    12. 手写迷你react(短小精悍就是我)

    react15在render阶段的reconcile是不可打断的,这会在进行大量dom的reconcile时产生卡顿,因为浏览器所有的时间都交给了js执行,并且js的执行时单线程。为此react16之后就有了scheduler进行时间片的调度,给每个task一定的时间,如果在这个时间内没执行完,也要交出执行权给浏览器进行绘制和重排,所以异步可中断的更新需要一定的数据结构在内存中来保存dom的信息,这个数据结构就是Fiber(虚拟dom)。

    Fiber的数据结构

    Fiber的自带的属性如下:

    function FiberNode(
      tag: WorkTag,
      pendingProps: mixed,
      key: null | string,
      mode: TypeOfMode,
    ) {
      //保存节点的信息
      this.tag = tag;//对应组件的类型
      this.key = key;//key属性
      this.elementType = null;//元素类型
      this.type = null;//func或者class
      this.stateNode = null;//真实dom节点
    
      //连接成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;
    }
    
    

    Fiber双缓存

    现在我们知道了Fiber可以保存真实的dom,真实dom对应在内存中的Fiber节点会形成Fiber树,这颗Fiber树在react中叫current Fiber,也就是当前dom树对应的Fiber树,而正在构建Fiber树叫workInProgress Fiber,这两颗树的节点通过alternate相连.

    function App() {
      return (
        <div>
          xiao
          <p>chen</p>
        </div>
      )
    }
    
    ReactDOM.render(<App />, document.getElementById("root"));
    
    
    image
    • 在mount时:会创建fiberRoot和rootFiber,然后根据jsx对象创建Fiber节点,节点连接成current Fiber树。

      _4
    • 在update时:会根据新的状态形成的jsx(ClassComponent的render或者FuncComponent的返回值)和current Fiber对比形(diff算法)成一颗叫workInProgress的Fiber树,然后将fiberRoot的current指向workInProgress树,此时workInProgress就变成了current Fiber。

      fiberRoot:指整个应用的根节点,只存在一个

      rootFiber:ReactDOM.render或者ReactDOM.unstable_createRoot创建出来的应用的节点,可以存在多个。

    我们现在知道了存在current Fiber和workInProgress Fiber两颗Fiber树,Fiber双缓存指的就是,在经过reconcile(diff)形成了新的workInProgress Fiber然后将workInProgress Fiber切换成current Fiber应用到真实dom中,存在双Fiber的好处是在内存中形成视图的描述,在最后应用到dom中,减少了对dom的操作。

    现在来看看Fiber双缓存创建的过程图

    mount时:

    1.刚开始只创建了fiberRoot和rootFiber两个节点

    _30

    2.然后根据jsx创建workInProgress Fiber:

    _31

    3.把workInProgress Fiber切换成current Fiber

    _32

    update时:

    1.根据current Fiber创建workInProgress Fiber

    _33

    2.把workInProgress Fiber切换成current Fiber

    _32

    相关文章

      网友评论

          本文标题:3.Fiber(我是在内存中的dom)

          本文链接:https://www.haomeiwen.com/subject/kcubxltx.html