【问题标题】:Game of Life in React/Redux, help in increasing performanceReact/Redux 中的生命游戏,有助于提高性能
【发布时间】:2016-07-26 09:31:20
【问题描述】:

我正在用 react/redux/javascript 开发生命游戏的一个版本,而我让它工作的时候性能很糟糕。

Here is a link to the running game Here's the source on githhub

目前,我在每个滴答声(用户可更改 250,500,750 毫秒)更新每个单元格的状态。为此,我正在遍历代表每个单元格的对象数组。在每个对象中都有一个称为 status 的参数,它可以是一个整数,1 表示存活,0 表示死亡。

然后我拉入三行,每行三个单元格,对于相关单元格周围的上述中间行和底部行,然后我对这些值求和(不包括中心的单元格本身)。

然后我通过 if/then 流程运行该数字以确定该单元格的新状态。

然后对应用程序中的每个单元格重复此过程。完成后,每个单元格的新状态将使用 redux 进行分派,并且组件会根据需要进行更新。

在实际视图中,每个单元格都是一个反应组件,它从网格容器接收它的状态作为道具。我已将 shoulComponentRender() 设置为仅在其生命状态发生变化时重新渲染单元格。

我认为从分析应用程序(我不是很清楚/不擅长)来看,计算所有值的过程会减慢速度,但我可能是错的,它可能是 React 组件导致问题。

感谢任何帮助/帮助!

【问题讨论】:

  • 我现在已经将更新的代码上传到 Github,似乎是导致问题的 GUI 渲染,但我无法锻炼如何改进它?

标签: javascript reactjs redux


【解决方案1】:

我认为这可能是问题所在。通过分析我们看到:

你有规律的工作间隔,每次大约需要 85 毫秒,这是非常不正常的。向下看调用堆栈,有一个 triggerTimer 和随后的 startTimer 函数调用。

查看这些的源代码: https://github.com/gazzer82/fcc-game-of-life/blob/a4a000a6cafa5877a4a15e59cec5184076905cc4/src/containers/lower_buttons.jsx#L12

你需要在条件下从startTimer返回。否则triggerTimerstartTimer 会以尽可能快的速度一遍又一遍地互相调用,每次都会产生新的超时。

之前

  startTimer(){
    var that = this;
    if(this.props.controls.game === 'running'){
      this.props.stepState();
    }
    setTimeout(() => this.triggerTimer(), this.props.controls.speed);
  }

  triggerTimer(){
    this.startTimer();
  }

之后

startTimer(){
  var that = this;
  if(this.props.controls.game === 'running'){
    this.props.stepState();
    // Return here
    return;
  }
  setTimeout(() => this.triggerTimer(), this.props.controls.speed);
}

triggerTimer(){
  this.startTimer();
}

【讨论】:

  • 您好,Red,感谢您的回复。但它认为你误解了我对这些功能所做的事情。它基本上是一个循环函数,用于计算细胞的下一个状态。所以每 x 毫秒(this.props.controls.speed)它有效地调用自己。如果此时游戏正在运行,它会触发对单元状态的更新。无论哪种方式,它都会为再次调用自身设置超时。基本上,这是一个 setInterval() 以这种方式完成的,以允许用户调整计时器的速度。然而,如果我将 return 放在你拥有它的地方,那么它将不会继续循环。
  • 啊,我明白了,对不起!至少通过分析,可以看出 startTimer 以及随后的所有计算每次执行都需要 >80ms 的时间,因此问题出在 js 计算的某个地方,而不是页面布局或合成中。我会尝试分叉并启动它。
  • 完全不用担心,非常感谢您的帮助!我认为问题可能在于我如何计算单元格操作创建器中每个单元格的状态。
  • 这些调度似乎占用了大部分时间。 imgur.com/a/ph22k newState 执行有点重,但与调度相比没有什么。 imgur.com/a/jUc3R。我认为这可能意味着大部分 JS 执行是由于组件对新状态的反应。如果您打印出单元格shouldComponentUpdate 中的每个条件,它们中的任何一个总是正确的吗?这将导致每次有新状态时都渲染所有单元格
  • 是的,这些花费最多的时间是有道理的。这基本上是生成细胞新状态的调度,以及生成完成和更新状态的通知。但是是的,你是对的,最后一个总是正确的,让我现在做一个重构,看看是否改进了。
【解决方案2】:

所以最终使用 DOM 和 html 组件的性能从未达到令人满意的水平。所以我重新编写了网格代码以使用 HTM5 Canvas 渲染所有单元格,性能不再是问题,事实上它现在在 iPhone 上渲染得非常愉快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-04
    • 2014-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 2017-04-29
    相关资源
    最近更新 更多