如何最轻松地识别 React 渲染性能的瓶颈?

Har*_*eve 5 javascript performance json reactjs

我在处理 JSON 查看器时遇到了识别渲染性能瓶颈的问题。由于元素很少,它表现良好,但在某些时候它会变得非常缓慢。

检查分析器,似乎元素渲染得足够快,但我注意到一些我不确定如何解决的问题。

概述

  • 该应用程序是一个 JSON 查看器,允许您一次扩展/最小化所有元素以及单个元素。
  • 元素很少时性能很好,但随着元素数量的增加似乎会急剧下降。
  • 在分析我的对象过滤器方法performance.now()以及检查 React DevTools 中的渲染时间时,这些数字似乎没问题。我可能解释错了。
  • 我已经尝试React.memo()在无状态元素上使用(特别是最常呈现的组件的键/值),但它似乎并没有显着提高性能。诚然,我不确定我是否理解记忆 React 组件背后的推理以有效地实现这一点。

执行

  • 目前,我的应用程序将数据加载到父组件中,该父组件馈入使用递归元素加载 JSON 树的组件。
  • 从 URL 加载 JSON 提要会更改父组件的状态,该状态使用辅助方法进行过滤,该方法使用输入字段中输入的值。

问题

有两个功能可以使用(不是很大)JSON 文档重现缓慢的响应时间:

  • 展开全部按钮
  • 过滤器查询的前几个按键

在当前的实现中,过滤和扩展都触发了display: none子元素的变化,这种行为让我相信我正在做一些低效的事情来处理这个用例。

繁殖步骤

该代码可在此处获得:https : //codesandbox.io/s/react-json-view-4z348

在这里进行生产构建(没有表现得更好):https : //csb-4z348.vercel.app/

要重现该问题,请使用“全部展开”功能(过滤器输入旁边的加号)和一些过滤器输入。

然后,尝试加载包含更多元素的 JSON 提要(您可以在我的GitHub API 提要上进行测试)并尝试过滤/扩展所有元素。注意主要的性能损失。

我注意到的

  • 在记录 useEffect 时,最小化似乎会导致大约 2 倍的重新渲染次数。
  • 随着过滤器输入变得更加具体,性能(逻辑上)随着渲染元素的减少而提高。

虽然我很感激在这种特定情况下朝着正确的方向推动,但我最好奇的是如何最好地确定导致这些性能问题的原因。

我已经研究过窗口化输出,但这不是我的第一选择,而且我很确定我做错了什么,而不是因为渲染了太多元素。

感谢您的时间,并提前感谢您提供的任何提示!

Har*_*eve 3

看来我已经回答了我自己的问题。该问题是由于在我的子组件中使用 UUID 作为关键道具而导致的协调问题,这导致它们在每次最小化状态更改时都重新渲染。来自文档:

密钥应该稳定、可预测且唯一。不稳定的键(例如由 Math.random() 生成的键)将导致许多组件实例和 DOM 节点不必要地重新创建,这可能会导致子组件的性能下降和状态丢失。

我将在这里为遇到此问题的其他人留下这些步骤。


在性能分析器中(太长时间)挖掘之后,我注意到每次最小化或扩展元素时,每个子元素都会被再次安装。在向 Google 咨询了更具体的查询后,我发现了这篇博文,并意识到我犯了这个公然的性能错误。

当我找到问题的根源后,我发现了 许多 其他的 参考资料

修复关键属性后,最小化/展开全部的交互时间加快了约 60%。

最后,我记住了一些与即时过滤器相关的其他组件,最后它似乎暂时表现得和我想要的一样好。

感谢同时查看此内容的任何人,我希望这对可能遇到此问题的任何人有所帮助。