2016-12-23 7 views
0

Dies ist, was ich in Reaktion schrieb. es nannte Spiel des Lebens.Wie verbessert man die Leistung mit großem Status in Reactjs?

ich eine Zelle als div machen, und speichern alle Zelle in einem state Objekt hat jede Zelle Zellennamen aussehen wie „0_0“, „0_1“, „0_2“ .... und hat am Leben Status und Nachbarn besitzen . so die Appstate sieht wie folgt aus:

enter image description here

und ich mache eine Zeitschleife für Prüfstatus jeder Zelle.

aber wie Sie sehen, es mit sehr schlechter Leistung, obwohl es nicht so viele Zellen in diesem Fall gibt.

Ich dachte, es wird eine gute Leistung durch das virtuelle Dom erhalten.

So, wie die Leistung in diesem Fall zu verbessern?


 
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); 
 
     } 
 

 
\t \t 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']}/>) } 
 
\t \t \t 
 
\t \t \t </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>

+0

Ich stimme ab, diese Frage als off- Thema, weil Frage nach * Verbesserungen/Optimierungen * sucht und zu [Code Reviews] (http://codereview.stackexchange.com/) gehört. – Rajesh

+0

Sie missbrauchen Zustand, reagieren hat aus einem Grund gesetzt, so dass Sie es nicht hart manipulieren sollten. Im übrigen haben alle Frameworks ihre beabsichtigte Verwendung, vielleicht ist ein Spiel nicht das, was für – Icepickle

+2

gedacht wäre. Ich würde in die Schlüsseleigenschaft von Cell schauen. In dem Moment, in dem Sie das ganze Objekt passieren, versuchen Sie, einen eindeutigen Bezeichner als String anzugeben und sehen Sie, ob das hilft. Ich vermute, dass das Übergeben eines Objekts als Schlüssel dazu führt, dass Sie alle DOM-Neuanordnungsvorteile verlieren, die Sie möglicherweise erhalten (oder möglicherweise nicht). Wenn Sie außerdem Cell erhalten, um React.PureComponent zu erweitern, können Sie die Funktion sollteComponentUpdate() loswerden. (Sollte in diesem Fall nicht Ihre Leistung verbessern, aber es ist gut zu wissen) –

Antwort

2

Sie rufen für jede Zelle this.setState.

Bei jedem Aufruf von this.setState wird render aufgerufen. Sie sollten diesen Anruf verzögern.

Etwas wie folgt aus:

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

zu Diogo Antwort Accoding ich eine bessere Leistung bekam jetzt

obwohl die Zellen erhöhen und mit schneller Zeitschleife:

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;  
 
\t } 
 

 

 
    tick() { 
 
     //console.log(this.runTime,stopTime); 
 
     if (this.runTime >= stopTime) { 
 
      clearInterval(this.timer); 
 
     } 
 
    
 
\t let newState = {}; 
 
     for (let cellName in this.state) { 
 
\t  newState = this.checkAlive(newState,cellName); 
 
     } 
 
\t this.setState(newState); 
 
\t 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']}/>) } 
 
\t \t \t 
 
\t \t \t </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>

Verwandte Themen