【问题标题】:How can I most easily identify bottlenecks in React render performance?我怎样才能最容易地识别 React 渲染性能的瓶颈?
【发布时间】:2020-12-04 22:47:19
【问题描述】:

我在使用 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/

要重现此问题,请使用 Expand All 功能(过滤器输入旁边的加号)和一些过滤器输入。

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

我注意到了什么

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

问题

虽然我希望为这个特定案例朝着正确的方向轻推,但我最好奇的是如何最好地确定导致这些性能问题的原因。

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

感谢您抽出宝贵时间,并提前感谢您提供的任何提示!

【问题讨论】:

    标签: javascript json reactjs performance


    【解决方案1】:

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

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

    我会将这些步骤留给遇到此问题的其他人。


    在(太长时间)在性能分析器中四处挖掘之后,我注意到每次最小化或扩展元素时,都会再次安装每个子元素。在通过更具体的查询咨询 Google 后,我找到了 this blog post 并意识到我犯了这个公然的性能错误。

    一旦找到问题的根源,我foundmanyotherreferences就到了。

    修复关键道具后,最小化/展开全部的交互时间缩短了约 60%。

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

    感谢在此期间查看此内容的任何人,我希望它对任何可能遇到此问题的人有所帮助。

    【讨论】:

      猜你喜欢
      • 2015-11-22
      • 2017-02-02
      • 2022-01-06
      • 2016-07-04
      • 1970-01-01
      • 1970-01-01
      • 2011-10-15
      • 2022-01-12
      • 2017-04-13
      相关资源
      最近更新 更多