【问题标题】:Is using a Canvas element in a React component inherently inefficient?在 React 组件中使用 Canvas 元素本质上是低效的吗?
【发布时间】:2018-08-05 10:16:28
【问题描述】:

问题上下文:我正在使用 React 和 Redux 创建一个像素艺术应用程序,编辑器部分是一个 HTML 画布。包含像素的网格被绘制在画布上,并且意味着每当包含每个像素颜色的状态片段更新时都会更新。 State 还管理编辑器中当前使用的工具以及画布的大小。

问题

对画布的正常更新只是将像素推送到位图上。但是,在 React 中,每当状态更改影响组件时,它都会默认重新渲染。因此,如果您使用componentDidUpdate() 以正常的 React 方式更新画布,您不只是清除然后重新绘制位图 - 您每次都重新渲染整个画布 DOM 元素。这对我来说似乎非常浪费。

画布元素的重新渲染是否会成为潜在的性能瓶颈?

如果是这样,您在野外使用或看到过哪些好的解决方案?

我的一些想法:我知道您可以将shouldComponentUpdate() 设置为返回false,这样它就不会重新渲染,但是您将无法使用componentDidUpdate() 来触发状态改变时的updateCanvas() 函数。我认为该解决方案可能需要与 React-Redux 和 Redux 源进行一些角力,以使画布直接订阅商店而不使用 React。这不是我以前尝试过的东西,但我可以看到它是如何工作的。

更新:所以根据我在另一个论坛上交谈过的其他人所说,只要状态更新不改变 JSX 的结果,react 就足够聪明,不会重新渲染 DOM元素。将 ref 抓取到画布并以这种方式更新它不应该重新渲染 DOM 元素。任何人都可以确认/提供更深入的解释吗?

【问题讨论】:

  • 我无法回答,因为我从未使用过 React,但你不能在这部分代码中不使用 React,因为它有这些问题吗?
  • 我很难说重新渲染画布会成为性能瓶颈,我自己也想不出任何其他方法来处理这个问题。
  • 嗨!我也在尝试找出高性能的 canvas/react/redux 集成。到目前为止,我的实验至少表明了一个潜在的瓶颈:通过反应条件渲染显示和隐藏大型画布元素。这样做会导致浏览器出现明显的延迟。使用宽度/高度属性调整大小的行为更像普通的图像调整大小。
  • @RikkuBölske 条件渲染很有趣,尽管我认为我不会为我的用例这样做。根据我交谈过的其他人的说法,只要状态更新不改变 JSX 的结果,react 就足够聪明,不会重新渲染 DOM 元素。将 ref 抓取到画布并以这种方式更新它不应该重新渲染 DOM 元素。这是任何人都可以确认/提供更深入解释的事情吗?

标签: javascript reactjs canvas redux html5-canvas


【解决方案1】:

我认为没有解决办法。你做得很好。 React 有一个不同的算法,它可以让你的朋友告诉你 React 很聪明。您可以在https://reactjs.org/docs/reconciliation.html 上阅读更多信息。

由于您正在重绘画布,因此我唯一能做的解决方案是延迟下一次渲染,以防出现拖拽。

【讨论】:

    【解决方案2】:

    在使用 pixi.js 和 three.js 时对我有用的解决方案是通过在 shouldComponentUpdate() 函数中返回 false 并使用普通 js 和事件更新画布(在 componentWillUnmount 上清理侦听器)来避免反应渲染和协调。使用画布时,反应并没有真正的好处。我建议您阅读有关主题的有趣读物:https://medium.com/@tibotiber/react-d3-js-balancing-performance-developer-experience-4da35f912484

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-15
      • 1970-01-01
      • 2016-03-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多