簡體   English   中英

如何在Reactjs中使用大狀態來提高性能?

[英]How to improve the performance with big state in Reactjs?

這就是我寫的react。 這叫做生活游戲。

我將一個單元格設為div ,並將所有單元格存儲在一個state對象中,每個單元格的單元格名稱看起來都像“ 0_0”,“ 0_1”,“ 0_2” ....,並且具有自己的活動狀態和鄰居。 因此, App state如下所示:

在此處輸入圖片說明

我建立了一個時間循環來檢查每個單元的狀態。

但是如您所見,盡管在這種情況下沒有太多的單元,但它的性能非常差。

我認為虛擬dom會獲得良好的性能。

那么在這種情況下如何提高性能呢?

 class Cell extends React.Component { constructor(props) { super(props); } shouldComponentUpdate(nextProps, nextState) { return nextProps.alive !== this.props.alive; } render() { let className = ['life']; if (this.props.alive) { className.push('alive'); } return ( <div className={className.join(' ')}></div> ); } } let lifeSize = 5; let w = 150; let h = 150; let chance = 0.75; let stopTime = 333; class App extends React.Component { constructor(props) { super(props); this.state = {}; //this.cellsDiv=[]; //console.log(store); this.checkAlive = this.checkAlive.bind(this); this.tick = this.tick.bind(this); this.runTime = 1; //per_width = per_width < 5 ? 10 : per_width; for (let i = 0; i < parseInt(h / lifeSize); i++) { for (let j = 0; j < parseInt(w / lifeSize); j++) { let neighborCells = []; neighborCells.push((i - 1) + '_' + (j - 1)); neighborCells.push((i - 1) + '_' + (j + 1)); neighborCells.push((i + 1) + '_' + (j - 1)); neighborCells.push((i + 1) + '_' + (j + 1)); neighborCells.push(i + '_' + (j - 1)); neighborCells.push(i + '_' + (j + 1)); neighborCells.push((i + 1) + '_' + j); neighborCells.push((i - 1) + '_' + j); this.state[i + '_' + j] = {}; this.state[i + '_' + j]['alive'] = (Math.random() > chance); this.state[i + '_' + j]['neighbor'] = neighborCells; } } } checkAlive(cellName) { //console.log(neighborCells); let o = this.state[cellName]; //console.log(i,j); let neighborCells = o['neighbor']; let alivecount = 0; for (let cell in neighborCells) { //console.log(neighborCells[cell],this.state[neighborCells[cell]]); if (this.state[neighborCells[cell]]) { if (this.state[neighborCells[cell]]['alive']) { alivecount++; } } } //let alive = this.state[i + '_' + j]['alive']; //console.log(alive,alivecount); if (o['alive']) { if (alivecount < 2 || alivecount > 3) { o['alive'] = false; } } else { if (alivecount == 3) { o['alive'] = true; } } //console.log(o); let cells = {}; cells[cellName] = {}; cells[cellName]['alive'] = o['alive']; cells[cellName]['neighbor'] = o['neighbor']; this.setState(cells); } tick() { //console.log(this.runTime,stopTime); if (this.runTime >= stopTime) { clearInterval(this.timer); } //console.log(this.state); for (let cellName in this.state) { this.checkAlive(cellName); } this.runTime++; //console.log(this.state); //this.setState({alive:alive}); } componentDidMount() { this.timer = setInterval(this.tick, 1000); } componentWillUnmount() { clearInterval(this.timer); } render() { return ( <div id="show"> { Object.keys(this.state).map((k, index) => <Cell key={k} alive={this.state[k]['alive']}/>) } </div> ); } } ReactDOM.render( <App/>, document.getElementById('app') ); 
 #show { width: 150px; height: 150px; border: 1px solid black; xbackground: #f0f0f0; margin: 0; padding: 0; } .life { width: 5px; height: 5px; xborder: 1px solid black; background: white; float: left; xmargin: 1px; } .alive { background: black; } body { margin: 0; padding: 0; xbackground: black; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="app"></div> 

您正在為每個單元格調用this.setState。

每次調用this.setState時,都會調用render。 您應該延遲此通話。

像這樣:

let newState = {};
for (let cellName in this.state) {
    newState = {...newState, this.checkAlive(cellName)}; //remember removing the setState from checkAlive
}
this.setState(newState);

根據Diogo的回答,我現在獲得了更好的性能

盡管增加了單元並具有更快的時間循環:

 class Cell extends React.Component { constructor(props) { super(props); } shouldComponentUpdate(nextProps, nextState) { return nextProps.alive !== this.props.alive; } render() { let className = ['life']; if (this.props.alive) { className.push('alive'); } return ( <div className={className.join(' ')}></div> ); } } let cellSize = 5; let w = 400; let h = 400; let chance = 0.85; let stopTime = 200; class App extends React.Component { constructor(props) { super(props); this.state = {}; //this.cellsDiv=[]; //console.log(store); this.checkAlive = this.checkAlive.bind(this); this.tick = this.tick.bind(this); this.runTime = 1; //per_width = per_width < 5 ? 10 : per_width; for (let i = 0; i < parseInt(h / cellSize); i++) { for (let j = 0; j < parseInt(w / cellSize); j++) { let neighborCells = []; neighborCells.push((i - 1) + '_' + (j - 1)); neighborCells.push((i - 1) + '_' + (j + 1)); neighborCells.push((i + 1) + '_' + (j - 1)); neighborCells.push((i + 1) + '_' + (j + 1)); neighborCells.push(i + '_' + (j - 1)); neighborCells.push(i + '_' + (j + 1)); neighborCells.push((i + 1) + '_' + j); neighborCells.push((i - 1) + '_' + j); this.state[i + '_' + j] = {}; this.state[i + '_' + j]['alive'] = (Math.random() > chance); this.state[i + '_' + j]['neighbor'] = neighborCells; } } } checkAlive(cells,cellName) { //console.log(neighborCells); let o = this.state[cellName]; //console.log(i,j); let neighborCells = o['neighbor']; let alivecount = 0; for (let cell in neighborCells) { //console.log(neighborCells[cell],this.state[neighborCells[cell]]); if (this.state[neighborCells[cell]]) { if (this.state[neighborCells[cell]]['alive']) { alivecount++; } } } //let alive = this.state[i + '_' + j]['alive']; //console.log(alive,alivecount); if (o['alive']) { if (alivecount < 2 || alivecount > 3) { o['alive'] = false; } } else { if (alivecount == 3) { o['alive'] = true; } } //console.log(o); //let cells = {}; cells[cellName] = {}; cells[cellName]['alive'] = o['alive']; cells[cellName]['neighbor'] = o['neighbor']; return cells; } tick() { //console.log(this.runTime,stopTime); if (this.runTime >= stopTime) { clearInterval(this.timer); } let newState = {}; for (let cellName in this.state) { newState = this.checkAlive(newState,cellName); } this.setState(newState); this.runTime++; } componentDidMount() { this.timer = setInterval(this.tick, 500); } componentWillUnmount() { clearInterval(this.timer); } render() { return ( <div id="show"> { Object.keys(this.state).map((k, index) => <Cell key={k} alive={this.state[k]['alive']}/>) } </div> ); } } ReactDOM.render( <App/>, document.getElementById('app') ); 
 #show { width: 400px; height: 400px; border: 1px solid black; xbackground: #f0f0f0; margin: 0; padding: 0; } .life { width: 5px; height: 5px; xborder: 1px solid black; background: white; float: left; xmargin: 1px; } .alive { background: black; } body { margin: 0; padding: 0; xbackground: black; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="app"></div> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM