学习React是跟随着卡颂老师学习的React技术揭秘,非常的好,值得学习。
React的核心是什么? 为什么使用React?
React官方是这样解释的: React是用于构建Web应用和原生交互界面的库,把自身定义为js的一个库,对于我使用react开发的感受而言,React是在js语法的基础上,使用新的语法,开发应用,其增加了两个方面的内容:
1.开发本身:对于创建应用和更新现有的应用,使得开发者的开发效率,开发体验有了显著的提升。模块化开发虽然不是React提出的,但是React中广泛使用,父-子-孙组件的创建,使用,扩展,封装通用组件变得越来越简单,父-子之间props传递信息的便捷和React-Redux的提出,使得兄弟之间,或者是全局的数据流通变得更加方便。越来越多的React库提出,如React-Router,antd等,对于开发者而言,一个应用或者系统,开发成本变得越来越低--
2.应用本身:Fiber架构的提出,使得React不再只关注React-->js这一过程和解决方案,从React代码转译到js,就像盖房子一样,假设React是黏土,js是砖头,在我们把React烤制成砖头时,如果不加入其他能够增强砖头硬度的黑科技,倒不如直接寻找砖头(使用js开发)。Fiber架构将目光瞥向性能,在限制我们应用的两个瓶颈:CPU瓶颈和IO瓶颈。
应用本身--React性能方面
CPU瓶颈:
React的虚拟DOM,是每一个初学者必要了解的知识,在真实DOM渲染之前,会对比虚拟DOM是否一致,如果一致,则不再重新渲染,否则,重新渲染DOM树。这一过程本身会提高我们的应用性能,不会每次更新某个组件,对我们全局进行更新渲染,但-->生成虚拟DOM-->两个虚拟DOM对比-->渲染真实DOM是需要时间的,当DOM树足够长,深度遍历的时常会持续增加,处理时间超过了16.6毫秒(1秒/60赫兹=>16.6毫秒刷新一次),将会出现卡顿现象。React提出,在代码中,通过useMome+mome,跳过某些组件的对比,即当页面发生更新时,不再生成当前节点的虚拟DOM,减少生成和对比时长。
IO瓶颈:
IO指的是读取或写入内存中的这个过程,网络原因是无法解决的,但是对于人机交互而言,React提出Susoense,在加载完成之后再展示真正的UI。
有没有更好的解决方案?可以帮助缓解两个瓶颈,为用户带来更好的体验? -->Fiber架构
Fiber架构核心: 把同步不可中断的任务 -----> 可中断的异步任务
1.将-->生成虚拟DOM-->两个虚拟DOM对比-->渲染真实DOM。在每个16.6毫秒的处理时长中,React把其中5毫米给了这个过程,其他时长,用来页面渲染,在下一个16.6毫米中,继续执行当前任务。
2.IO同步读取渲染到页面-->异步先渲染旧值,再更新读取数据
Fiber架构--解决了什么问题
React15架构 :
Reconciler --1协调器 任务:Render --> jsx转化-->虚拟DOM对比-->不同-->Renderen
Renderen --2渲染器 任务:接收不同-->Renderen渲染新页面
上述过程是React15的更新过程,假设我们将此过程定义为任务,一次渲染,有三处更新:
开始更新->任务1开始->任务1结束->任务2开始->任务2结束->任务3开始->任务3结束->完成
可以看出,当我们更新页面时,如果一个长尾任务的更新足够多,对于浏览器的渲染而言,卡顿是不可避免的,所以,新的Fiber将解决这类问题。
React16+ Fiber架构
Scheduler --1调度器 任务:高>中>低->级别任务排序-->Reconciler
Reconciler --2协调器 任务:接收任务-->Render --> jsx转化-->虚拟DOM对比-->不同-->打标签
Renderen --3渲染器 任务:接收所有标签-->Renderen渲染新页面
在此执行中,1,2可以根据情况中断,假设有三处更新X,Y,Z,执行过程:
Scheduler调度-->优先级X>Y>Z-->Reconciler执行任务X开始-->Reconciler执行任务X结束-->Reconciler执行任务Y开始-->Reconciler执行任务Y结束-->Reconciler执行任务Z开始-->Reconciler执行任务Z结束-->执行完成交给Renderen-->Renderen渲染新页面
注意,在执行完成交给Renderen之前,任务可中断,加入两种情况:1.高优先级任务插入 2.时间耗尽
1. Y任务执行未完成时,插入高优先级任务A,执行过程:
Scheduler调度-->优先级X>Y>Z-->Reconciler执行任务X开始-->Reconciler执行任务X结束-->Reconciler执行任务Y开始-->Reconciler执行任务Y中断-->Scheduler调度插入任务A-->Reconciler执行任务A开始-->Reconciler执行任务A结束-->Reconciler继续执行Y任务-->Reconciler执行任务Y结束-->Reconciler执行任务Z开始-->Reconciler执行任务Z结束-->执行完成交给Renderen-->Renderen根据标签渲染新页面
2. Y任务执行未完成时,当前帧下任务时间耗尽,执行过程:
Scheduler调度-->优先级X>Y>Z-->Reconciler执行任务X开始-->Reconciler执行任务X结束-->Reconciler执行任务Y开始-->Reconciler执行任务Y中断-->Reconciler继续执行Y任务-->Reconciler执行任务Y结束-->Reconciler执行任务Z开始-->Reconciler执行任务Z结束-->执行完成交给Renderen-->Renderen根据标签渲染新页面
Fiber任务可中断的两点好处:
1.避免造成X,Y,Z三处更新,中断Y时,页面只更新了X这种情况。
2.避免造成当前帧卡顿,执行可在下一帧的时间继续执行。
Fiber架构了解的大致这么多,其实现原理和实现过程,还需继续探索---
站在巨人的肩膀上,勿在浮沙筑高台!(卡子的肩膀上)