最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 动手实现 React (二)

    正文概述 掘金(Sunsmile59975)   2021-03-07   569

    我们将从头开始一步一步重写React。遵循真实的React代码中的架构,但没有所有的优化和非必要的功能

    1. createElement
    2. render
    3. Concurrent Mode
    4. Fibers
    5. Render 和 Commit 阶段
    6. Reconciliation
    7. Function Components
    8. Hooks

    回顾

    function render(element, container) {
      const dom = document.createElement(element.type) 
    
      element.props.children.forEach(child =>
        render(child, dom)
      )
    
      container.appendChild(dom)
    }
    

    回顾上一篇文章中的render函数,我们发现直到渲染完后,才会停止。如果element很大,则它可能会阻塞主线程太长时间。而此时如果浏览器需要执行高优先级的操作(例如处理用户输入或保持动画流畅),则必须等到渲染完成才会执行。

    众所周知,主流的浏览器的刷新频率为60HZ,即每16.6ms(1000ms/60HZ)浏览器就会刷新一次。我们知道JS可以操作DOMGUI渲染线程JS线程是互斥的。所以JS脚本执行浏览器布局绘制不能同时执行。

    为了保证用户体验,在16.6ms之内,浏览器需要执行以下流程

    动手实现 React (二)

    我们先介绍一个浏览器api requestIdleCallback -- 在浏览器一帧的剩余空闲时间内执行优先度相对较低的任务。

    动手实现 React (二)

    插播

    var lowTasks = 10000
    
    requestIdleCallback(unImportWork)
    
    function unImportWork(deadline) {
      while (deadline.timeRemaining() && lowTasks > 0) {
        console.log(`执行了${10000 - lowTasks + 1}个任务`)
        lowTasks--
      }
    
      if (lowTasks > 0) { // 在未来的帧中继续执行
        requestIdleCallback(unImportWork)
      }
    }
    

    deadline 有两个参数

    • timeRemaining(): 当前帧还剩下多少时间
    • didTimeout: 是否超时

    另外 requestIdleCallback 后如果跟上第二个参数 {timeout: ...} 则会强制浏览器在当前帧执行完后执行。

    步入正题

    经过上面的分析,我们可以得出以下结论 -- 我们将工作 render 为多个单元,在完成每个单元后,如果需要执行其他任何操作,我们将让浏览器中断渲染

    let nextUnitOfWork = null
    
    function workLoop(deadline) {
      let shouldYield = false
      while (nextUnitOfWork && !shouldYield) {
        nextUnitOfWork = performUnitOfWork(
          nextUnitOfWork
        )
        shouldYield = deadline.timeRemaining() < 1
      }
      requestIdleCallback(workLoop)
    }
    
    requestIdleCallback(workLoop)
    
    function performUnitOfWork(nextUnitOfWork) {
      // TODO
    }
    

    通过上面代码,我们把下一个需要处理的单元存储在nextUnitOfWork中,在浏览器空闲的时候我们再继续处理,这样就实现Concurrent Mode

    我们又发现了新的问题,nextUnitOfWork 的结构是什么呢?我们如何创建它?请看下一小节 -- Fibers

    未完待续...... 防止走失,请关注作者。


    起源地下载网 » 动手实现 React (二)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元