1

React源码Part2——渲染原理: https://segmentfault.com/a/11...
React源码Part3——Fiber架构:https://segmentfault.com/a/11...
React源码Part4——Render渲染(Mount阶段):https://segmentfault.com/a/11...
React源码Part4——Render渲染(Update阶段):https://segmentfault.com/a/11...
React源码Part5——commit阶段(处理class组件生命周期): https://segmentfault.com/a/11...
React源码Part6——Commit阶段(beforeMutation):https://segmentfault.com/a/11...
React源码Part7——Commit(Mutation阶段): https://segmentfault.com/a/11...
React源码Part8——Commit(Layout阶段):https://segmentfault.com/a/11...
参考链接:React技术揭秘——https://react.iamkasong.com/p...

本文解决的问题有哪些

  • 什么是代数效应?
  • 代数效应的应用?

限制浏览器快速响应和渲染速度的因素有哪些?

  1. CUP瓶颈:当需要大量计算和性能操作时遇到的卡顿
  2. IO瓶颈:页面渲染大量DOM或更新DOM时遇到的卡顿
    在计算机中,GUI线程和JS线程是互斥的,所以JS执行和浏览器渲染DOM、布局等操作是不能同时进行的。(PS: 有兴趣的同学可以了解下虚拟DOM、浏览器渲染机制、重绘、重排)

解决浏览器渲染问题的方法——#时间切片

  • 什么是时间切片:将一个长任务分解成多个执行时间少的小任务执行,这样在用户感知上就会觉得流畅
  • 时间切片的例子:

    1. Demo1:用JS创建1W个DOM元素,创建一个添加一个到页面中

       let list = document.querySelector('.list')
       let total = 100000
       for (let i = 0; i < total; ++i) {
         let item = document.createElement('li')
         item.innerText = `我是${i}`
         list.appendChild(item)
       }
    2. Demo2: 将1W个DOM元素分成多个小任务,一个任务对应一个文档片段,里面包含20个DOM元素,一次添加一个文档片段到页面中

       let list = document.querySelector('.list')
       let total = 100000
       let size = 20
       let index = 0
       const render = (total, index) => {
         if (total <= 0) {
             return
         }
         let curPage = Math.min(total, size)
         window.requestAnimationFrame(() => {
             let fragment = document.createDocumentFragment()
             for (let i = 0; i < curPage; ++i) {
                 let item = document.createElement('li')
                 item.innerText = `我是${index + i}`
                 fragment.appendChild(item)
             }
             list.appendChild(fragment)
             render(total - curPage, index + curPage)
         })
       }
       render(total, index)
  • 浏览器渲染的每一帧在底层都有一个时间范围,因为时间很短,所以感知不到。平常说的一帧渲染多少,指的就是在这个时间范围内能做多少事。
  • 结论:使用时间切片的概念能解决CPU和IO的瓶颈,因为造成瓶颈的原因都是任务执行时间超过渲染帧时间引起的
  • React中的应用:在浏览器每一帧的时间中,预留一些时间给JS线程,React利用这部分时间更新组件,预留的初始时间是5ms。当预留的时间不够用时,React将线程控制权交还给浏览器使其有时间渲染UI,React则等待下一帧时间到来继续被中断的工作

什么是代数效应?

  • 代数效应是函数式编程中的一个概念,用于将副作用从函数调用中分离(PS:不说人话😄)
  • 我的理解是可以在同步代码中实现异步效果,可以参考JS中Generator的使用,但要理念比其先进。(PS: React中saga的原理实现就是这个原理,后续会写其源码实现)
  • 应用:React中的Suspense和和Hook实现参考了代数效应
  • 代数效应的代码理解(PS: 图中你没见过的语法都是虚构的,仅帮助理解)
  • 代数效应的代码理解

代数效应的应用

  • React15中的缺陷:上文中提到解决UI渲染瓶颈的问题采用时间切片处理,但React15中的渲染逻辑是递归处理,一旦开始就不能终止。若是在其更新过程中有新的交互,触发数据更新就不能及时响应。这是React15中的缺陷。
  • React16中如何解决: React16中引入代数效应的理念,增加调度机制,给fiber节点打上标记,对应不同的渲染优先级。在渲染过程中优先级高的fiber节点能插队,实现异步更新。当异步更新完成后,又回来接着更新上次的内容,这里就是代数效应的应用

参考链接


冷咖啡
22 声望3 粉丝

知识的搬运工😄