React 原理分析

news2024/11/18 5:34:09

优质博文:IT-BLOG-CN

一、简介

为什么我要用react?JQuery也挺好的呀?
1、因为浏览器和JavaScript一直在更新,新版前端框架可以更好对接新的API,更好的利用浏览器的能力, 提供更新潮强大的功能。
2、react有其庞大的生态系统,如插件、工具、库等,对开发者更省力

二、React主要发展历程

2011 Facebook内部使用
2013 Facebook开源
2015 Facebook发布React Native(干掉了iOS和Android开发岗位)
2017 React发布Fiber架构
2019 React16.8引入Hooks
2022 React 18 发布Concurrent Mode和Server Component
2024 React 19RC发布

三、React特性

1、组件化: 代码复用度高
2、虚拟DOM: 减少不必要的DOM操作和渲染
3、JSX: 易于理解和使用
4、跨平台: ReactNative
5、Concurrent Mode: 可中断的异步更新

四、React原理

React15架构:
1、Reconciler(协调器)—— 负责找出变化的组件
2、Renderer(渲染器)—— 负责将变化的组件渲染到页面上

此架构弊端: Reconciler是递归渲染,过程不可中断,当更新任务过大用时过久就会造成页面卡顿

React16架构:
1、Scheduler(调度器)—— 调度任务的优先级,高优任务优先进入
2、ReconcilerReconciler(协调器)—— 负责找出变化的组件
3、Renderer(渲染器)—— 负责将变化的组件渲染到页面上

此架构基于Fiber,时间切片,优先级调度,实现了渲染过程的可中断更新,在浏览器资源上限内最高效率流畅更新页面。

实现步骤:
1.虚拟DOM一个用来描述 UI 结构的 JavaScript 对象,用于抽象表示浏览器中真实的DOM节点,体积轻量,不绑定实际DOM具有的属性和方法。

// 虚拟 DOM 对象
const virtualDOM = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world!'
  }
};

虚拟DOM的作用

每一个浏览器引擎都包含渲染引擎和JS引擎,二者各司其职。JS引擎执行JS快速不费力,可对用户不可见。
在这里插入图片描述

渲染引擎渲染页面比较耗费浏览器资源,直接和用户交互。
在这里插入图片描述

在接收到DOM更新任务时,虚拟DOM可作为真实DOM替身,缓冲计算好,最后统一更新到真实DOM树上,减少不必要的对DOM的操作和渲染。

当虚拟DOM有唯一标识时,还可以实现对应真实DOM节点的复用。
在这里插入图片描述

React Fiber 架构

Fiber Node: 一个典型的 Fiber 节点包含以下几个关键属性:
1、type: 组件的类型(例如函数组件、类组件、DOM 元素等)。
key: 用于标识节点的唯一键。
stateNode: 与 Fiber 节点对应的实际 DOM 节点或组件实例。
child: 指向第一个子节点的指针。sibling:指向下一个兄弟节点的指针。
return: 指向父节点的指针。
pendingProps: 新的属性,在 Fiber 树更新时使用。
memoizedProps: 上一次渲染时的属性。
memoizedState: 上一次渲染时的状态。
alternate: 指向当前 Fiber 节点的另一个版本(用于双缓存机制)。

Fiber Tree: 通过每个Fiber的child,sibling,return节点链接形成的链表结构。这种结构使得 React 可以在不影响其他节点的情况下,灵活地插入、删除或更新Fiber节点。React 遍历 Fiber 树时,通常使用深度优先搜索(DFS)。

双缓存机制: 在React中最多会同时存在两棵Fiber树。当前屏幕上显示内容对应的Fiber树称为current Fiber树,正在内存中构建的Fiber树称为workInProgress Fiber树。

current Fiber树中的Fiber节点被称为current fiber,workInProgress Fiber树中的Fiber节点被称为workInProgress fiber,他们通过alternate属性连接。

React应用的根节点通过使current指针在不同Fiber树的rootFiber间切换来完成current Fiber树指向的切换。

即当workInProgress Fiber树构建完成交给Renderer渲染在页面上后,应用根节点的current指针指向workInProgress Fiber树,此时workInProgress Fiber树就变为current Fiber树。

这种在内存中构建并直接替换的技术叫做双缓存。
在这里插入图片描述

时间切片

前面提到的每一个浏览器引擎都包含渲染引擎和JS引擎,这两个引擎的工作是互斥的,同一时刻只能工作一个。

浏览器的刷新频率受限于显示器的刷新频率。以60Hz为例,浏览器每1000ms刷新16次,说明浏览器的一个刷新周期是16.6ms。
在这里插入图片描述

在浏览器每个刷新周期内,会按次序执行以下工作,JS脚本执行 ----- 样式布局 ----- 样式绘制
在这里插入图片描述

其中的JS脚本执行时间如果过长,就会导致刷新周期内无法执行样式绘制,形成掉帧,造成用户视觉上的页面卡顿。

为了解决这种问题,于是诞生了时间切片。

React,在浏览器每一帧刷新周期内,预留一些时间给 JS 线程,利用这部分时间更新组件(可以看到,在源码中,预留的初始时间是 5ms)。

当预留的时间不足以执行完全部的JS时,React将线程控制权交还给浏览器使其有时间渲染 UI,React则等待下一帧时间到来继续被中断的工作。
在这里插入图片描述

function performUnitOfWork(fiber) {  
	// 处理当前 Fiber 节点  
	beginWork(fiber);  

	// 如果有子节点,处理子节点  
	if (fiber.child) {    
		return fiber.child;  
	} 
	 
	// 如果没有子节点,处理兄弟节点或返回父节点  
	let nextFiber = fiber;  
	while (nextFiber) {    
		completeWork(nextFiber);    
		if (nextFiber.sibling) {      
			return nextFiber.sibling;    
		}    
		nextFiber = nextFiber.return;  
	}
}

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

	if (!nextUnitOfWork) {    
		commitRoot();  
	} else {    
		requestIdleCallback(workLoop);  
	}
}

// 开始渲染
requestIdleCallback(workLoop);

优先级调度

优先级级别: React 定义了多个优先级级别,用于区分不同类型的任务。主要的优先级级别包括:
1、Immediate: 立即执行的任务,通常用于用户输入等需要立刻响应的操作。如文本框输入、按钮点击等。
2、User-blocking: 用户阻塞任务,稍低于立即执行的任务,但仍然需要快速响应,影响用户界面交互流畅性。如拖拽、滑动等。
3、Normal: 正常优先级任务,常规更新,如组件的状态更新、网络请求完成后的数据处理等。Low:低优先级任务,如后台数据同步,定时器。
4、Idle: 空闲优先级任务,只有在浏览器空闲时才会执行。

优先级实现: lane模型借鉴了同样的概念,使用31位的二进制表示31条赛道,位数越小的赛道优先级越高,某些相邻的赛道拥有相同优先级。
在这里插入图片描述

调度流程:
1、当需要执行一个任务时,React 会创建一个任务对象,并将其添加到优先级队列中。任务对象包含任务的优先级、执行回调和其他相关信息。
2、调度器会根据任务的优先级对队列中的任务进行排序。高优先级任务会排在队列的前面,低优先级任务则排在后面。
3、调度器会从队列中取出最高优先级的任务并执行它。如果当前有更高优先级的任务到来,调度器会中断当前任务,优先执行高优先级任务。
4、调度器会根据浏览器的空闲时间和任务的优先级来调度任务的执行,确保高优先级任务能够及时响应。(React 使用 requestIdleCallback 和 requestAnimationFrame 等浏览器 API 来实现这一点。

五、流程汇总

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2184334.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++中,如何使你设计的迭代器被标准算法库所支持。

iterator&#xff08;读写迭代器&#xff09; const_iterator&#xff08;只读迭代器&#xff09; reverse_iterator&#xff08;反向读写迭代器&#xff09; const_reverse_iterator&#xff08;反向只读迭代器&#xff09; 以经常介绍的_DList类为例&#xff0c;它的迭代…

番茄间的一分钟休息

很多人喜欢使用番茄工作法&#xff0c;在25分钟内集中工作。这种方法提高了25分钟内的工作效率&#xff0c;但是也增加了自己的疲劳程度。 我建议&#xff0c;在25分钟的工作时间内&#xff0c;要保持对自己身体的觉察。如果感觉呼吸短促&#xff0c;有一些紧张&#xff0c;用…

C0007.Clion中添加ui文件及运行的完整步骤

1.创建ui文件 选择Ui文件目录&#xff0c;右击&#xff0c;打开Qt Designer&#xff1b; 创建完成后&#xff0c;保存ui界面&#xff0c;并且命名为test.ui&#xff1b; 2.新建头文件test.h 在include目录中&#xff0c;新建头文件&#xff0c;文件名为test.h 3.新建test.…

ScrapeGraphAI 大模型增强的网络爬虫

在数据驱动的动态领域&#xff0c;从在线资源中提取有价值的见解至关重要。从市场分析到学术研究&#xff0c;对特定数据的需求推动了对强大的网络抓取工具的需求。 NSDT工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线…

C++语言学习(1): std::endl 在做什么?

std::endl 是一个函数&#xff08;而不是变量&#xff09;&#xff1a; std::endl 会向控制台写入 \n 字符&#xff0c;并且刷新缓冲。 刷新缓冲肯定比不刷新缓冲慢。 这就是为什么有些 guide 里提到&#xff0c;少用 std::endl, 多用 \n.

Notepad++ 之 AndroidLogger插件

背景 最近一段时间在分析Android log 定位问题&#xff0c;Notepad 之前用的比较少&#xff0c;现在看log觉得确实好用&#xff0c;美中不足的是 看Android log的时候不像 logcat -v color 可以区分不同等级的颜色&#xff0c;于是调研了一下&#xff0c;发现大部分都是使用An…

DAY84服务攻防-端口协议桌面应用QQWPS 等 RCEhydra 口令猜解未授权检测

Day84&#xff1a;服务攻防-端口协议&桌面应用&QQ&WPS等RCE&hydra口令猜解&未授权检测_wps漏洞复现 rce-CSDN博客https://blog.csdn.net/qq_61553520/article/details/137119893?ops_request_misc%257B%2522request%255Fid%2522%253A%25220E34BCAF-166A-4…

Python 实现指定股票三日趋势分析脚本及原理详解

以下是一个基于Python的股票三日趋势分析脚本&#xff0c;它能够分析指定股票在三天内的趋势变化情况。脚本主要依赖pandas、numpy、matplotlib和yfinance等库。分析内容包括收盘价的涨跌趋势、成交量变化&#xff0c;并生成可视化图表来帮助用户更好地理解短期趋势。 脚本的分…

汇总binder相关一些常见面试题-安卓系统常见面试题

背景&#xff1a; 国庆前有几个学员朋友在群里讨论了几个binder相关的面试题&#xff0c;讨论较为激烈&#xff0c;这里马哥统一整理一下列出来了&#xff0c;并且也补充了几个&#xff0c;大家有兴趣的可以尝试做一下&#xff0c;后续方便每个学员进行查缺补漏。后续会进行整…

三维地图场景学习总结 20241002

1. 学习内容 1.1 cesium 学习 基础教程&#xff1a;提供了cesium的配置方式及简单案例 dvgis&#xff1a;该网址提供了关系cesium的使用案例 1.2 OpenStreetMap 学习 List_of_OSM-based_services&#xff1a;提供了openstreetmap所有相关工具及相关使用案例 1.3 三维场景渲…

生信初学者教程(十一):数据校正

文章目录 介绍加载R包导入数据准备数据ComBatremoveBatchEffectVoom SNM批次效应校正结果比较校正后的结果输出校正后的结果总结介绍 批次效应在生物学数据分析中是一个普遍存在的问题,它指的是由于实验过程中非生物学因素(如样本处理时间、实验条件、测序平台等)的差异,导…

如何使用ssm实现基于HTML的中国传统面食介绍网站的搭建+vue

TOC ssm758基于HTML的中国传统面食介绍网站的搭建vue 第1章 绪论 1.1选题动因 当前的网络技术&#xff0c;软件技术等都具备成熟的理论基础&#xff0c;市场上也出现各种技术开发的软件&#xff0c;这些软件都被用于各个领域&#xff0c;包括生活和工作的领域。随着电脑和笔…

前端框架对比和选择指南

前端框架对比和选择指南 随着 Web 开发技术的快速发展&#xff0c;前端框架已经成为了现代 Web 开发的核心工具之一。它们为开发人员提供了快速构建高效、交互性强的应用的基础。当前流行的前端框架主要包括 React.js、Vue.js 和 Angular.js。在这篇技术博客中&#xff0c;我们…

dubbo微服务

一.启动nacos和redis 1.虚拟机查看是否开启nacos和redis docker ps2.查看是否安装nacos和redis docker ps -a3.启动nacos和redis docker start nacos docker start redis-6379 docker ps二.创建三个idea的maven项目 1.第一个项目dubboapidemo 2.1.1向pom.xml里添加依赖 …

uniapp微信小程序使用ucharts遮挡自定义tabbar的最佳解决方案

如图所示&#xff1a; 使用的ucharts遮挡住了我自定义的tabbar&#xff08;如果不是提需求的有病&#xff0c;我才不会去自定义tabbar&#xff09; 查阅了不少文档&#xff0c;说是开启 ucharts 的 canvas2d 即可&#xff1a; 官网文档地址&#xff1a; uCharts官网 - 秋云…

忽有庞然大物,拔山倒树而来 – 盖RAD Studio 12.2是也

忽有庞然大物&#xff0c;拔山倒树而来 – 盖RAD Studio 12.2是也 不知为什么, 在看到RAD Studio 12.2推出的新功能之后, 脑中出现的第1个反应就是小时候唸的”忽有庞然大物&#xff0c;拔山倒树而来” 这句话, 因为12.2的新功能出乎我意料之外的巨大, 根本不象是一个0.2…

攻防世界---->SignIn

做题笔记。 下载 查壳。 64ida打开。 先运行一下程序&#xff1a; 那么&#xff0c;我们可以直接查找字符串看看&#xff0c;锁定位置。 ### 纠正一下&#xff1a;应该是 n 值 不是d值 n p*q 。。。### ### v6的值 应该就是 我们func(input,49) 进行加密后的值。 (猜测的&a…

《向量数据库指南》——非结构化数据挑战升级:如何高效导入向量数据库?

哈哈,说到 AI 应用中的非结构化数据处理,这可真是个让人又爱又恨的话题啊!今天呢,咱就聊聊这个话题,尤其是那个让人头疼的如何将各种数据源和格式的非结构化数据导入向量数据库的问题。 非结构化数据处理:挑战与复杂性 在 AI 应用领域,非结构化数据无处不在,从社交媒…

【递归】11. leetcode 129 求根节点到叶节点数字之和

1 题目描述 题目链接&#xff1a; 求根节点到叶节点数字之和 2 解答思路 第一步&#xff1a;挖掘出相同的子问题 &#xff08;关系到具体函数头的设计&#xff09; 第二步&#xff1a;只关心具体子问题做了什么 &#xff08;关系到具体函数体怎么写&#xff0c;是一个宏观…

Vue3实现动态菜单功能

文章目录 0.效果演示1.搭建Vue3项目1.1 vite 脚手架创建 Vue3 项目1.2 设置文件别名1.3 安装配置 element-plus1.4 安装配置路由2.登录页面3.后台管理页面3.1 搭建后台框架3.2 左侧菜单栏3.3 header 用户信息3.4 主要内容3.5 footer4.配置静态路由5.记录激活菜单5.1 el-menu 绑…