React
关于 React 相关知识点总结, 持续更新中……
Fiber
什么是fiber,fiber解决了什么问题
在React16以前,React更新是通过树的深度优先遍历完成的,遍历是不能中断的,当树的层级深就会产生栈的层级过深,页面渲染速度变慢的问题,为了解决这个问题才引入了 fiber
,React fiber
可以说就是 虚拟DOM,它是一个链表结构,返回了return、children、siblings
,分别代表父 fiber
,子 fiber
和兄弟 fiber
,随时可中断。
fiber
是协程,是比线程更小的单元,可以被人为中断和恢复,当 React
更新时间超过1帧时,会产生视觉卡顿的效果,因此我们可以通过fiber把浏览器渲染过程分段执行,每执行一会就让出主线程控制权,执行优先级更高的任务,从而实现增量渲染,增量渲染指的是把一个渲染任务分解为多个渲染任务,而后将其分散到多个帧里。增量渲染是为了实现任务的可中断、可恢复,并按优先级处理任务,从而达到更顺滑的用户体验。
fiber
是一个链表结构,它有三个指针,分别记录了当前节点的下一个兄弟节点,子节点,父节点。当遍历中断时,它是可以恢复的,只需要保留当前节点的索引,就能根 据索引找到对应的节点。
Fiber
它主要解决了 React 在处理大型应用和复杂更新场景时的性能问题。Fiber 的目标是提高 React 在渲染和更新组件时的性能,并支持更高效的任务调度。
Fiber 是一种架构,让render 阶段可以调度任务的优先级
也是一种数据结构,通过两颗缓存树 current Fiber
和 workInProgress Filber
,一个用于展示,一个用于操作,当一轮操作完成后,react 才会切换到操作完成的Fiber 节点上,另一棵树会销毁重新构建用于操作。 每个节点进行对比是会进行一次 shouldYield()
判断,利用空闲时间去更新。
高优先级任务使用 RequestAnimatonFrame,
低优先级使用 RequestIdleCallback
从某种意义上来说 fiber 就是 vdom,但是 fiber != vdom 这里所谓的调度就是,调度器允许给任务分配不同的优先级,高优先级限制性,
diff算法
- 用JS对象模拟DOM(虚拟DOM)
- 把此虚拟DOM转成真实DOM并插入页面中(render)
- 如果有事件发生修改了虚拟DOM,比较两棵虚拟DOM树的差异,得到差异对象(diff)
- 把差异对象应用到真正的DOM树上(patch)
react 的 diff 主要有三种策略:
- tree diff 两个树对比时,只会比较同一层级的节点,会忽略掉跨层级
- component diff 在对比两个组件时,首先会判断它们两个的类型是否相同,如果不同,则将该组件判断为 dirty component,从而替换整个组件下的所有子节点
- element diff
对于同一层级的一组节点,会使用具有唯一性的key来区分是否需要创建,删除,或者是移动。React diff 提供了三种节点操作,分别为:
- INSERT_MARKUP(插入)
- MOVE_EXISTING(移动)
- REMOVE_NODE(删除)
diff 的大致流程:
react 检测到组件状态或属性发生改变,会出发重新渲染,从而生成新的vdom树, 然后diff算法对新旧vdom 树进行深度优先遍历,比较节点的类型属性以及存在的key, 如果节点发生变化,会销毁旧的节点,及其子节点,重新生成新的节点,属性则会保留节点,只更新属性, 最后react 根据计算结果得到的更新之后的vdom 更新在真是dom,保持一致。 主要作用是减少直接操作dom 导致的重排重绘,减少开销,提高效率
React diff 采用的是递增法,就是通过比较新的列表中的节点,在原本列表的位置是否有递增,来判断节点是否需要移动。
虚拟dom
就是 js和dom之间的一种映射吧,可以展现dom的结构还有属性,主要作用是在记录差异,最后把差异更新到真正的dom中 虚拟DOM 实际就是一个JS 对象,其结构主要包括:
- type 实际的标签
- props 标签内部的属性
- children 节点内容,依次循环 相比较真实的DOM 结构,其内部结构很简单,真实DOM 结构中还有属性和一系列方法, 虽然他们都是默认的,相比较而言,虚拟Dom 没有那么重,操作起来对比真实Dom 要简单跨界很多,性能也会更好。
虚拟Dom 大致工作流程
- 挂载阶段 React 结合 JSX, 构建出虚拟Dom 树,然 后通过其与Dom 的映射关系, 然后通过 render 触发渲染
- 更新阶段 页面发生变化,在作用到Dom 之前,会先映射生成新的虚拟dom 树,然后经过 diff 算法,对比新旧虚拟Dom 树,对比具体的改变,然后再将改变作用到真实Dom。
React 中 key 作用
key 是给每一个 vnode 的唯一 id,可以依靠 key,更准确,更快的拿到 oldVnode 中对应的 vnode 节点
循环中不建议使用index,当我们在操作更新数据的时候,会导致所有的dom 重新渲染,效率低下,还有就是有可能导致更新不符合预期 每次都是用不一样的key,比如时间戳或者随机数等等,会造成每次key不一样,导致许多组件实例和DOM节点被不必要地重新创建,这可能导致性能下降和子组件中的丢失状态
事件处理系统
React 的事件系统(Event System)是一种统一的事件处理机制,它允许开发者在 React 应用中处理原生浏览器事件,如点击、输入、滚动等。React 事件系统的主要目标是提供一种跨浏览器的、一致的事件处理方式,并实现性能优化。