react渲染机制?

如题所述

第1个回答  2024-09-04
React设计理念

React的函数调用栈可以分为三个部分

对应react源码调度体系的三个模块

React是一个可以满足构建快速响应web应用程序的库

制约快速响应的因素主要是计算能力和网络延迟也就是CPU和IO

React的刷新频率是60Hz也就是1000ms/60Hz=16.6ms浏览器刷新一次

在这16.6ms的过程中,浏览器要做三件事情:

如果,JS脚本执行时间过长,那么就没有时间执行样式布局和样式绘制,这样浏览器就会出现卡顿的情况

为了解决这种情况,React采用的方法是:将同步的更新更改为异步可中断的更新

也就是,React和浏览器做了一个约定,浏览器在每一帧都预留给React一定时间进行样式布局和样式绘制,如果某一项工作需要的时间比较长,React会中断自己的工作,把控制权交还给浏览器,等待下一帧预留的时间,继续之前中断的工作

在一些需要请求数据结果才能做出响应的场景下,React为实现快速响应的解决办法是:将人机交互的研究的结果整合到真实的UI中

React15的架构中分为两部分,一部分决定渲染什么组件,另一部分决定将组件渲染到视图中

也就是Reconciler(协调器)和Renderer(渲染器)

在Reconciler中会将新旧组件做一个对比,找到要更新的组件,然后把组件交给Renderer,不同的渲染器会把组件渲染到不同环境中

也就是:协调器找到更新,渲染器更新DOM

但是,如果采用异步可中断的更新这种方式,这种架构就会导致更新的卡顿

比如,有一个列表,需要把1,2,3更新到2,4,6,到更新完1--2,这个时候中断了更新,那么用户看到的就是2,2,3

在新架构中,React新增了一个Scheduler(调度器)

这个调度器可以把需要更新的模块分好优先级,高优先级的任务可以优先进入协调器,如果这个时候有更高优先级的更新,那么前面那个任务会被中断

协调器完成diff操作,更新会进入渲染器

完成渲染后,调度器会开始新一轮的调度

举个例子,三个li显示1,2,3,现在要把他们更新为4,5,6,大概过程为:

Fiber一共有三层含义

新架构中的协调器是基于Fiber节点实现的,称为StackReconciler

在这里,Fiber是纤程的意思,和进程(Process)线程(Thread)协程(Coroutine)同为操作系统中的执行过程

它可以实现

每个Fiber节点对应一个组件,这个节点保存了关于这个组件的一些属性,这也就是我们常说的虚拟DOM

Fiber保存了组件需要更新的状态以及需要执行的副作用

Fiber架构中,采用了双缓存机制,双缓存就是,在内存中构建好要更新的内容,然后替换上一帧的内容

举个例子:

当首次render的时候,会创建一个FiberRootNode节点,这是整个应用的根节点,还会创建当前应用的根节点RootFiber,FiberRootNode的current指向RootFiber

接下来,首屏渲染时,会再创建一棵Fiber树,叫做workInProcessFiber树

当workInProcessFiber树完成渲染时,FiberRootNode的current就指向workInProcessFiber树

当更新导致的渲染时候,会再创建一个workInProcessFiber树,在这个过程中,会将currentFiber和返回的jsx结构作对比,这个过程也就是diff算法

然后,FiberRootNode的current会指向新生成的workInProcessFiber树

理解React:Fiber架构和新旧生命周期

React16.3之后React的Reconciler架构被重写(Reconciler用于处理生命周期钩子函数和DOMDIFF),之前版本采用函数调用栈递归同步渲染机制即StackReconciler,dom的diff阶段不能被打断,所以不利于动画执行和事件响应。React团队使用FiberReconciler架构之后,diff阶段根据虚拟DOM节点拆分成包含多个工作任务单元(FiberNode)的Fiber树(以链表实现),实现了Fiber任务单元之间的任意切换和任务之间的打断及恢复等等。Fiber架构下的异步渲染导致了componentWillMount、componentWillReceiveProps、componentWillUpdate三个生命周期在实际渲染之前可能会被调用多次,产生不可预料的调用结果,因此这三个不安全生命周期函数不建议被使用。取而代之的是使用全新的两个生命周期函数:getDerivedStateFromProps和getSnapshotBeforeUpdate。

可能导致的bug:在需要重置SimpleInput组件的情况下,由于props.attr未改变,导致组件无法正确重置状态,表现就是input输入框组件的值还是上次遗留的输入。

React(五)深入React-Hooks工作机制,原理

1.原则:只在React函数中调用Hooks;不要在循环、条件或嵌套函数中调用Hook,确保Hooks在每次渲染时都保持同样的执行顺序

2.Hooks的正常运作,在底层依赖与顺序链表。首次渲染mountState构建链表并渲染;更新时updateState会依次遍历链表、读取数据并渲染。react不会看命名的变量名是什么,它只认为这是一次useState调用

关于render渲染优化

除初始化组件渲染外,组件会在以下两种情况下发生重渲染:

1、当调用setState()函数时,组件会发生重渲染,即使组件的state未发生改变;

2、当父组件发生重渲染时,其全部子组件都会重渲染。

虽然React的重渲染机制是严谨的,但是也是非常耗时的,我们有两种方式来阻止组件不必要的重渲染。

shouldComponentUpdate(nextProps,nextState)是重渲染时render函数调用之前被调用的函数,它接收两个参数:nextProps和nextState,分别表示下一个props和下一个state的值,并且,当函数返回false时,阻止接下来的render()函数的调用,阻止组件重渲染,而返回true时,组件照常重渲染,React默认返回true。

PureComponet原理:只需要把组件的继承类从Component换成PureComponent即可。PureComponent自动加载了shouldComponentUpdate函数,当组件更新时,shouldComponentUpdate对props和state进行了一层浅比较,如果组件的props和state都没有发生改变,render方法就不会触发,省去VirtualDOM的生成和对比过程,达到提升性能的目的。

但是由于PureComponent对props和state只进行了浅比较,所以对与嵌套的对象并不适用。

logo设计

创造品牌价值

¥500元起

APP开发

量身定制,源码交付

¥2000元起

商标注册

一个好品牌从商标开始

¥1480元起

公司注册

注册公司全程代办

¥0元起

    官方电话官方服务
      官方网站八戒财税知识产权八戒服务商企业需求数字市场

相关了解……

你可能感兴趣的内容

大家正在搜

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网