介绍了一些刚开始学习React,或者从其他框架转入React的开发者,一开始可能不太关注性能。因为需要一定的时间才能发现新学的框架的性能不足。后来,由于经验不足,这些开发人员在编写代码时犯了一些小错误,最终累积起来导致性能不佳。此外,他们将很难解决问题。在这里,我们将探索7个技巧,帮助您在构建任何类型的应用程序时避免大多数React性能问题。1.解决重复渲染问题我们大多数人都知道虚拟DOM是如何工作的,但最重要的是检测何时触发树比较。当我们可以跟踪它时,我们可以控制组件的重新渲染并最终防止意外的性能流。令人惊讶的是,它并不难捕捉。首先,将ReactDevtool扩展添加到浏览器。然后打开浏览器开发者工具(Chrome中的Option+?+J(在macOS上),或Shift+CTRL+J(在Windows/Linux上)。选择组件单击设置图标并选中“HighlightwhencomponentrendersUpdate”,这就是现在,当我们与UI交互时,它会在当前重新渲染的元素上显示一个绿色边框。了解这一点后,我们可以分析我们的任何React组件并重构它们以避免不必要的重新渲染。2.减少重新渲染通过拆分组件进行渲染如果我们能够减少意外重新渲染元素的数量,它将解决React中的大多数性能问题。但是我们必须首先回答这个问题:“什么触发了重新渲染?”。答案很简单,状态变化。每次组件状态变化时,它都会唤醒树比较,也称为协调,并重新呈现状态上下文的元素。状态上下文,是初始化这种状态的组件。意思是,如果我们有一个有很多状态的巨大组件(不需要o相互依赖)其中一个状态发生变化,它会重新渲染整个组件元素,这肯定不是我们想要的。那么,解决方案是什么?解决方案是通过将组件的一部分和它的一些状态移动到它自己的子组件中来分离状态上下文,现在,让我们看一下这个例子:假设我们有一个带有搜索过滤器的表组件。搜索过滤器过滤器是一种受控输入,其状态在输入文本更改后更新。它看起来是这样的:当我们开始在搜索输入字段中输入时会发生什么?是的,它重新呈现整个表单元素。发生这种情况是因为输入状态上下文与表组件共享相同的上下文。现在,让我们通过将输入元素及其状态移动到一个单独的组件并将其注入表组件来尝试我们的解决方案。奇迹发生了,表格组件不再重新渲染。我们稍后可以通过从输入中发出事件来增强功能,以准确控制我们希望输入何时影响表单元素。好的做法是将组件拆分为单独的状态上下文,以避免冗余的重新渲染。3.什么是实例重创建,如何避免?我们已经看到状态更改会触发组件重新渲染,但我们需要考虑另一个重要的副作用。当状态发生变化和协调时,它会重新初始化整个组件实例并保留新的状态值。这对我们来说意味着在协调期间将重新创建所有函数实例以能够考虑新的状态值,我们不需要它,在大多数情况下一个函数可以只依赖于几个状态而我们不需要'想要重新创建不依赖于已更改状态的创建函数实例。这是一个提高性能的机会,我们有几个解决方案:useCallback和useRef。我们来看一个例子:const{someState,setSomeState}=useState('')const{otherState,setOtherState}=useState('')constfoo=()=>{console.log(someState)}这是最常见的例子。我们有依赖于状态someState的foo。当someState发生变化时,它将重新创建一个新的foo实例。这段代码的问题在于,即使其他一些状态发生变化,比如otherState,foo也会被重新创建,而这实际上并不是我们想要的。我们可以使用useCallback来告诉React我们函数的状态依赖关系在重新创建实例时要更明确:const{someState,setSomeState}=useState('')const{otherState,setOtherState}=useState('')constfoo=useCallback(()=>{console.log(someState)},[someState])在此示例中,我们将一组依赖项传递给useCallback挂钩。更好的是,foo将避免其他状态更改。另一种选择是使用useRef。useRef-你可以把它想象成useState,但不会触发组件重新渲染(UI不会更新)。useRef没有依赖列表,所以我们需要将someState作为foo属性传递:const{someState,setSomeState}=useState('')const{otherState,setOtherState}=useState('')constfoo=useRef((currentSomeState)=>{console.log(currentSomeState)}).current;在这种情况下,我们根本不会重新创建foo实例。结论:使用useCallback和useRef来控制函数实例的重新创建。4、不要偷懒去加载React默认的同步渲染组件。这意味着该组件将等到其子项被渲染后再渲染自己。无需等待,尤其是在某些子组件未耦合的情况下。它可能会导致页面挂起。假设我们单击某个导航链接,将我们重定向到另一个页面。导航将等待所有页面组件呈现以完成重定向。它会影响用户体验,人们不会等待而离开您的网站。我们需要让页面内容异步呈现,以免影响导航。解决方案是将页面组件包装在React.lazy(()中并告诉React完成导航,然后等待页面组件完成渲染:constPageComponent=React.lazy(()=>import('./PageComponent'));稍后我们可以使用
