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...
本文解决的问题有哪些
- 什么是代数效应?
- 代数效应的应用?
限制浏览器快速响应和渲染速度的因素有哪些?
- CUP瓶颈:当需要大量计算和性能操作时遇到的卡顿
- IO瓶颈:页面渲染大量DOM或更新DOM时遇到的卡顿
在计算机中,GUI线程和JS线程是互斥的,所以JS执行和浏览器渲染DOM、布局等操作是不能同时进行的。(PS: 有兴趣的同学可以了解下虚拟DOM、浏览器渲染机制、重绘、重排)
解决浏览器渲染问题的方法——#时间切片
- 什么是时间切片:将一个长任务分解成多个执行时间少的小任务执行,这样在用户感知上就会觉得流畅
时间切片的例子:
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) }
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节点能插队,实现异步更新。当异步更新完成后,又回来接着更新上次的内容,这里就是代数效应的应用
参考链接
- React的Suspense:https://zh-hans.reactjs.org/d...
- JS中Generator的使用:https://es6.ruanyifeng.com/#d...
- React技术揭秘:https://react.iamkasong.com/#...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。