Game Of life 的性能问题 (React.js + Redux)
Problems with performance on Game Of life (React.js + Redux)
当我的 Game Of Life 运行 单独运行时,我遇到了一些问题。为此,我尝试设置一个 setInterval 并触发现在每次有人单击“下一步”时都会触发的功能。但它给我带来了很多问题。
主要问题是,当我设置 setInterval( () => this.handleChange(), 100) 时,游戏的移动速度非常慢,最后在 codepen 中崩溃了。
class Board extends React.Component{
handleChange(){ [.........] //just to indicate that here is more code that is not showing and dont think it is important to the question.
nextMovement() [...........]
render(){
var createBoard = this.props.board.map((idx) => {
return <Cell
onClick={() => this.props.toggleAlive(idx.index)}
key = {idx.index}
index = {idx.index}
col = {idx.col}
row = {idx.row}
val = {idx.val}
/>
});
return(
<div className="board">
{createBoard}
<button className="btn btn-danger" onClick={()=>this.handleChange()}>Next</button>
{setInterval(() => this.handleChange(), 100)}
</div>
);
}
}
/* - - - Reducers - - - */
在这里你也可以找到我的 codePen 以及查看完整代码。
http://codepen.io/DiazPedroAbel/pen/bwNQAJ
我也在看,他好像和我有同样的问题,但最后为了解决问题他开始使用canvas。
我也想知道我的游戏性能低下是否是由于我创建下一个面板的方式造成的。我只有两个板,实际的一个和下一个包含所有新动作的板,当我最终填满这个新板时,我改变板的状态触发一个动作。或者也许问题是我在 setInterval 函数上做错了。
在此先致谢,如有任何帮助,我们将不胜感激。
您可以尝试解决以下两点:
1) setInterval 使用起来有点危险,如果你的步骤可能 运行 比你的间隔长。你会霸占浏览器。因此,在步骤完成后,使用 setTimeout 触发下一步。
2) 作为旁注,与 运行 计算相比,DOM 操作速度较慢。尽量减少 DOM 操作并更新现有组件然后重新创建元素(尽管我不确定您的应用程序在这方面如何工作,如果它完全丢弃以前的板)
要解决您的问题,您应该添加
shouldComponentUpdate(next) {
let props=this.props;
return props.col!==next.col || props.row !== next.row || props.val!==next. val;
}
给你的 Cell
class。这将确保只有更改的单元格才会重新呈现。
Redux 通常非常擅长优化这些东西,但您的设置有两个问题:
- 您的
Cell
class 未被 connect
编辑。这意味着 Redux 无法帮助控制其渲染。如果你想要那么传递 row
/col
作为道具,但让它从 Redux 在 mapStateToProps
. 中获得它的 val
- 您通过更换来更新电路板。只要新板中未更改的单元格引用与旧板相同的对象,这就可以工作。这就是 Redux 检查单元格是否已更改的方式。所以在复制旧板时确保它是浅拷贝,然后在更新单元格时,用一个全新的对象替换旧的单元格对象。请记住:您不能修改处于 Redux 状态的对象。但是您可以修改数组本身,因为它是一个副本,这意味着您可以在不修改原始单元格的情况下替换单元格。如果你在 Redux 中的单元格只包含数字,那么你不必担心它,因为
Number
s 的值 是 身份。这意味着如果您写入相同的值,Redux 将看到它是相同的。 Redux 无法检查两个不同的对象是否具有完全相同的属性,因为它花费的时间太长。
使用上面的 shouldComponentUpdate
可以不必执行这些操作,但您可能应该执行这些操作,因为这是 Redux 的方式。没有这些改变,你就不能很好地使用 Redux。事实上,你几乎失去了 Redux-React 的所有好处。
然而,任何一种方法都会使您的棋盘变快,前提是棋盘的有限部分实际上会发生变化。如果整个面板都在闪烁,那么除了使用不同的技术之外,您无能为力,例如 Canvas
或 React-Canvas
。 DOM 很慢。
当我的 Game Of Life 运行 单独运行时,我遇到了一些问题。为此,我尝试设置一个 setInterval 并触发现在每次有人单击“下一步”时都会触发的功能。但它给我带来了很多问题。
主要问题是,当我设置 setInterval( () => this.handleChange(), 100) 时,游戏的移动速度非常慢,最后在 codepen 中崩溃了。
class Board extends React.Component{
handleChange(){ [.........] //just to indicate that here is more code that is not showing and dont think it is important to the question.
nextMovement() [...........]
render(){
var createBoard = this.props.board.map((idx) => {
return <Cell
onClick={() => this.props.toggleAlive(idx.index)}
key = {idx.index}
index = {idx.index}
col = {idx.col}
row = {idx.row}
val = {idx.val}
/>
});
return(
<div className="board">
{createBoard}
<button className="btn btn-danger" onClick={()=>this.handleChange()}>Next</button>
{setInterval(() => this.handleChange(), 100)}
</div>
);
}
}
/* - - - Reducers - - - */
在这里你也可以找到我的 codePen 以及查看完整代码。
http://codepen.io/DiazPedroAbel/pen/bwNQAJ
我也在看
我也想知道我的游戏性能低下是否是由于我创建下一个面板的方式造成的。我只有两个板,实际的一个和下一个包含所有新动作的板,当我最终填满这个新板时,我改变板的状态触发一个动作。或者也许问题是我在 setInterval 函数上做错了。
在此先致谢,如有任何帮助,我们将不胜感激。
您可以尝试解决以下两点: 1) setInterval 使用起来有点危险,如果你的步骤可能 运行 比你的间隔长。你会霸占浏览器。因此,在步骤完成后,使用 setTimeout 触发下一步。
2) 作为旁注,与 运行 计算相比,DOM 操作速度较慢。尽量减少 DOM 操作并更新现有组件然后重新创建元素(尽管我不确定您的应用程序在这方面如何工作,如果它完全丢弃以前的板)
要解决您的问题,您应该添加
shouldComponentUpdate(next) {
let props=this.props;
return props.col!==next.col || props.row !== next.row || props.val!==next. val;
}
给你的 Cell
class。这将确保只有更改的单元格才会重新呈现。
Redux 通常非常擅长优化这些东西,但您的设置有两个问题:
- 您的
Cell
class 未被connect
编辑。这意味着 Redux 无法帮助控制其渲染。如果你想要那么传递row
/col
作为道具,但让它从 Redux 在mapStateToProps
. 中获得它的 - 您通过更换来更新电路板。只要新板中未更改的单元格引用与旧板相同的对象,这就可以工作。这就是 Redux 检查单元格是否已更改的方式。所以在复制旧板时确保它是浅拷贝,然后在更新单元格时,用一个全新的对象替换旧的单元格对象。请记住:您不能修改处于 Redux 状态的对象。但是您可以修改数组本身,因为它是一个副本,这意味着您可以在不修改原始单元格的情况下替换单元格。如果你在 Redux 中的单元格只包含数字,那么你不必担心它,因为
Number
s 的值 是 身份。这意味着如果您写入相同的值,Redux 将看到它是相同的。 Redux 无法检查两个不同的对象是否具有完全相同的属性,因为它花费的时间太长。
val
使用上面的 shouldComponentUpdate
可以不必执行这些操作,但您可能应该执行这些操作,因为这是 Redux 的方式。没有这些改变,你就不能很好地使用 Redux。事实上,你几乎失去了 Redux-React 的所有好处。
然而,任何一种方法都会使您的棋盘变快,前提是棋盘的有限部分实际上会发生变化。如果整个面板都在闪烁,那么除了使用不同的技术之外,您无能为力,例如 Canvas
或 React-Canvas
。 DOM 很慢。