| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> JavaScript知识库 -> Fiber 调度机制 -> 正文阅读 |
|
[JavaScript知识库]Fiber 调度机制 |
作者:温荣蛟 Fiber这个名词并不是React的首创,和服务器端开发中的中纤程(Fiber)相同,后端开发中的纤程,也有着不同的名字,例如C/C++的协程、Java中的Loom(孵化中)、Go中的goroutine;这些不同名字的背后其实都是一个目的——通过线程复用降低线程的使用成本。 操作系统提供了进程和线程供用户进行使用,其中线程是操作系统调度的最小单位。但是线程的使用成本很高,主要体现在每个线程都是自己独立的内存空间、线程切换需要的控制时间很长。这就导致了当出现大量线程时,会引起操作系统的压力变大,从而消耗大量的资源,降低性能。因此,在服务端开发等需要用到大量线程的场景下,会通过一些机制对操作系统的线程进行复用,这个机制就是服务器端的Fiber. 但是在前端领域,js只提供了一个线程,不存在线程切换的场景。是不是就说明了Fiber机制无法应用到前端?React又为何将自身调度机制命名为Fiber?Fiber在前端领域的作用体现在什么方面?或者换句话说,前端Fiber的意义又是什么? 本章将从Fiber的结构入手,为读者揭开React Fiber的神秘面纱。接着,分析Fiber机制在Task调度过程中的运行机制,最后分析Fiber的意义。 第一节 Fiber架构 如图2-1所示,Fiber架构由2部分组成:分发器(dispatcher)和调度器(scheduler)。分发器负责接受页面触发的事件,并将其转换为由 FiberNode组成的Task。交给调度器进行调度。调度器负责依据调度规则对Task进行细粒度的调度。 dispatcher: 它可以是一个组件的初始化挂载动作,也可以是某个事件触发的更新。 scheduler: 不管是挂载任务还是更新任务,都会推送到schedule调度器模块中,schedule模块将确定该任务的执行时机。 例子 图2-2展示了一个外卖页面的示意图,当用户点击加入购物车时,会触发该按钮的点击事件,将页面整体刷新为右图的样子。 当用户点击按钮时,触发点击事件,将事件会触发分发器的转换动作。可以先简单的认为分发器将触发4个FiberNode的更新,分别是:
需要读者明确的是,本节提到的例子只是为了方便读者理解React Fiber机制。实际上,事件任务的拆分会依据一套更复杂的机制进行。并不是简单的按照显示的效果进行切分。 第二节 Task 分发器与调度器之间通过Task进行通信。Task对应的是组件的挂载或更新动作。由FiberRoot和FiberTree构成。 FiberRoot: 上述触发的挂载或则更新将初始化一个FiberRoot对象,是此次任务FiberTree的根节点。FiberRoot的currentTree上的stateNode属性指向触发本次事件的DOM节点,即FiberRoot节点链接了DOM节点和对应的任务节点。 FiberTree: 多个node节点组成。是事件涉及的所有节点的更新动作的集合。 2.1 FiberTree 如图2-2,FiberTree是由一个一个FiberNode以单链表的形式组合成的节点集合。FiberNode是调度器执行的最小单位,每执行完一个FiberNode更新后,线程的控制权将转交给调度器,由调度器来选择下一个执行的任务(继续或中断插入其他任务)。 第三节 分发器 第一节中提到分发器负责事件触发和更新,分发器除了处理事件的分发还需要负责节点的更新分发。当FiberNode进行更新操作时,分发器会根据FiberNode上的tag属性进行分发处理,不同的类型进入不同的更新逻辑。本文挑选3个最常用的向读者介绍。 3.1 HostComponent 3.2 FunctionComponent
3.3 ClassComponent
第四节 Task调度过程
4.1任务启动 4.2任务挂起 4.3任务恢复 4.4任务结束 第五节 React Fiber的意义 React Fiber本质上将js提供的一个工作线程进行复用,以实现对任务细粒度的控制。React Fiber和服务端开发的Fiber相比,都是通过精妙的设计改变当前线程正在执行的任务,从而实现线程复用。因此React将自身的调度机制命名为Fiber也是合理的。 前文已经说明了,js是单线程语言,不存在线程切换的成本,那么React设计的Fiber的意义就剩一个了:提高任务的调度效率。 5.1 响应时间和周转时间 T周转时间=T完成时间-T到达时间 周转时间指的是任务进入系统到最终完成所经过的时间。平均周转时间则用来评价调度器的调度性能。考虑一个极端情况,T0时刻,ABC三个任务同时进入调度器,A任务需要4秒,B任务需要10s,C任务需要2s。若调度器按照BAC的顺序执行任务,ATT=(10+14+16)/3=13.33秒。若调度器按照CAB的顺序执行,则ATT=(2+6+18)/3=8.67秒。 响应时间指的是调度器第一次执行任务时所经过的时间,平均响应时间用来衡量调度系统响应任务的能力。对于交互多的系统而言,平均响应时间是一个非常重要的指标,毕竟用户不希望自己输入按下键盘后需要等待很长时间才能得到响应。 5.2 任务粒度 图2-2展示了一个任务切分后调度的一个示例。例子中使用的是最短执行时间优先的调度策略。不难看出,通过将大任务切分为小任务后进行调度,可以有效降低系统的平均周转时间和平均响应时间,大幅度提高了调度效率。但是本例中的最短执行时间优先的算法在实际中不可能被应用,因为在现实中很难事先获取任务的执行时间,React中有一些更精妙的调度策略,会在下一章进行详细讲述。 这种切分的本质是降低了任务的粒度,因此,任务的粒度很大程度上决定了调度的效率。任务粒度大的系统,无法有效地进行调度。 5.3 Fiber意义 React Fiber的意义在于细化任务粒度,调度策略会影响不同场景下的调度效果,但这些调度策略的前提是任务粒度要足够小,否则任何调度策略都会遇到调度系统的系统瓶颈。 第六节 总结 本章梳理了Task建立到Task拆分再到挂起恢复的逻辑。从中不难发现Fiber架构对Task进行拆解,降低了任务阻塞的时长,对任务整体来说没有提速。 本章对Fiber的底层机制进行了分析,分析了任务粒度对调度的影响。在通过Fiber机制对任务进行细粒度的切分后,通过调度策略优化性能成为了可能,下一章将详细介绍调度器中的不同调度策略。 |
|
JavaScript知识库 最新文章 |
ES6的相关知识点 |
react 函数式组件 & react其他一些总结 |
Vue基础超详细 |
前端JS也可以连点成线(Vue中运用 AntVG6) |
Vue事件处理的基本使用 |
Vue后台项目的记录 (一) |
前后端分离vue跨域,devServer配置proxy代理 |
TypeScript |
初识vuex |
vue项目安装包指令收集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 2:52:54- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |