chatGPT:React 的双缓存是这样的

879 阅读5分钟

对话 chatGPT

React 中有个叫双缓存的东西,下面我们来问问 GPT, 看看他是怎么说的。(因为水印的原因就不给大家截图了,把文案贴出来)

  • 我:
    双缓存技术是什么?

  • chatGPT:

双缓存技术是一种计算机图形显示技术,在图形渲染过程中使用两个缓存区,一个用于显示当前的图像,另一个用于下一帧图像的渲染,从而避免了图像刷新时的闪烁和卡顿问题,提高了图形显示的效果和性能。

在使用双缓存技术时,通常有两个缓存区,一个是前缓存区,一个是后缓存区。前缓存区用于显示当前场景的图像,后缓存区则用于渲染下一帧场景的图像。当渲染下一帧的图像数据处理完毕后,将后缓存区的图像数据直接覆盖前缓存区,从而实现平滑地显示下一帧场景。这样,就避免了图像刷新时的闪烁和卡顿现象。

双缓存技术在图形游戏开发、视频制作、工程设计等领域都有广泛的应用,可以提高图形显示的效果和性能,给用户带来更加流畅的视觉体验。

  • 我:
    那这个技术在 React 中怎么应用的?

  • chatGPT:

在 React 中,双缓存技术被应用于 React 的渲染机制中。React使用虚拟DOM(Virtual DOM)作为中间层来实现页面的渲染。在组件状态或属性更新时,React会在内存中创建一个新的虚拟DOM树并将其与旧的虚拟DOM树进行比较,找出它们之间的差异,在找到差异后,React会将这些差异应用到真正的DOM上,更新页面的显示。

在这个过程中,React采用的就是双缓存技术。具体来说,React使用两个缓存区,分别存储当前正在显示的虚拟DOM树和下一个将要显示的虚拟DOM树。当更新操作开始时,React会先将下一个将要显示的虚拟DOM树存储在未使用的缓存区中,然后在对比过程中,会将更新后的结果存储在另一个未使用的缓存区中,最后将两个缓存区的指针交换,使得下一次更新可以继续使用刚刚更新完的缓存区。

这个双缓存机制可以有效地减少页面的重绘次数,提高页面的性能和流畅度。在React中,这个机制被称为“Reconciliation(协调)”或“Diffing(差异化)”,是React的核心算法之一。

  • 我:
    React 为什么要用双缓存技术?

  • chatGPT:

React使用双缓存技术的原因是为了提高性能和减少DOM更新次数。

在React中,每次状态变化都会引发组件的重新渲染,这通常涉及到计算虚拟DOM树、比较新旧DOM树、生成更新操作等一系列复杂的操作。如果每次都直接更新DOM,这种操作还会带来显著的性能问题。

通过使用双缓存技术,React可以在内存中维护两个DOM树,一个是当前的DOM树,另一个是待更新的DOM树。当组件需要更新时,React会首先在待更新的DOM树中计算新的DOM树,然后将其与当前DOM树进行比较,找出差异并生成更新操作,最后将待更新的DOM树作为当前DOM树,进入下一次更新周期。

由于React使用了双缓存技术,它能够以最小的代价实现组件的更新,减少了DOM操作的次数和计算量,从而提高了性能和用户体验。

评价

从上面的回答来看,对双缓存技术的描述还是到位的,在对 React 的两个问题的回答还是差点意思的可能是训练的数据比较老的原因吧。 不过总体来说, 回答的还是不错的。

React 为什么要用双缓存技术

基于目前对 React 的理解,我觉得有以下几个原因:

  • 避免页面出现类型闪屏的问题
  • 为并发特性服务(高优先级任务更新打断低优先级任务)

GPT 提到的可以提升性能,我觉得这个还是有点问题的,毕竟 dom 操作是根据 Fiber 树的内容来的,双缓存只是单指树。也欢迎对这块有别的观点的评论,大家一块交流交流。

React 的双缓存应用

上一篇讲了 Fiber 架构,对 Fiber 有了一定的了解,双缓存技术的应用也是和 Fiber 相关的。在 React 运行时,内部会维护最多两棵 Fiber 树,一棵对应当前屏幕上显示的内容被叫做 current Fiber 树,对应双缓存中的前缓存区,另一棵树对应下一帧要更新的内容被叫做 workInProgress Fiber 树(简称 wip Fiber 树),对应双缓存树中的后缓存区。当 wip Fiber 上描述的内容更新到屏幕上之后,wip 会被交换到前缓存区作为 current Fiber 树,遇到下一个更新时,React 又会构建新的 wip Fiber 作为后缓存区。如此反复。

下面我们以一个例子来看看具体的情况。

demo

import { useState } from 'react'

function App() {
    const [text, setText] = useState('前缓冲区内容');
        
    const clickHandle = () => {
        setText('后缓冲区内容')
    }
    return (
        <div onClick={clickHandle} >{text}</div>
    )
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />)

挂载时

当执行完 const root = ReactDOM.createRoot(document.getElementById('root')); 时 会生成一个 Fiber 树(前缓存区),对应屏幕上的 id 为 app 的 div,屏幕上还没有内容。此时对应如下:

image.png 当执行到 root.render()时,通过 Reconciler 会构建后缓存区的内容,也就是 wip Fiber 树,具体表现如下:

image.png

当 React 将内容渲染到页面之后,后缓存区替换前缓存,情况如下:

image.png

更新时

当点击文本触发 setText 时,通过 Reconciler 会构建 wip Fiber 树(后缓存区),情况如下:

image.png

当 React 将更新的内容渲染到页面之后,后缓存区替换前缓存,情况如下:

image.png

总结

以上就是双缓存技术以及双缓存技术在 React 中的应用了,理解起来也是很容易的。

最后,感谢大家的阅读,有不对的地方也欢迎大家指出来。

参考

React 设计原理——卡颂
chatGPT
React 18.2.0 源码