2015-08-16 46 views
2

几天前我在考虑在我的情况下使用反应。案件很简单:我有对象的列表,它处理像上面例子中的快速更新:反应CPU使用率(快速更新)

var ListItem = React.createClass({ 
    render: function() { 
     return (
      <tr> 
       <td>{this.props.data.sign}</td> 
       <td>{this.props.data.a}</td> 
       <td>{this.props.data.b}</td> 
       <td>{this.props.data.time}</td> 
      </tr> 
     ); 
    } 
}); 

var List = React.createClass({ 
    getInitialState: function() { 
     return { items: list }; 
    }, 
    tick: function() { 
     var index = Math.floor(Math.random() * 100); 
     var randItem = getRandomItem(); 
     var item = this.state.items[index]; 

     item.sign = randItem.sign; 
     item.a = randItem.a; 
     item.b = randItem.b; 
     item.time = randItem.time; 

     this.setState({items: tick(this.state.items)}); 
    }, 
    componentDidMount: function() { 
     this.interval = setInterval(this.tick, 0); 
    }, 
    render: function() { 
     return (
      <table> 
       {this.state.items.map(function(item){ 
        return <ListItem key={item.i} data={item} />  
       })} 
      </table> 
     ); 
    } 
}); 

这是一个完整链接例子,我已经准备了:

https://jsfiddle.net/zsjmp3ph/

的问题是我的CPU占用了大约25-30%的使用量。我已经在其他机器上测试过,它是一样的。 React很正常吗?在我看来,这很奇怪,但我在图书馆是全新的,所以我想问更多有经验的人。告诉我,如果我做错了什么。提前致谢。

回答

4

通过使用setInterval设置状态,可以强制React经常重新渲染组件。它不会是0毫秒,而是由浏览器定义的一些下限。请参阅setInterval() behaviour with 0 milliseconds in JavaScript

如果您的应用程序已被人类使用,则在16ms内渲染UI的频率不会超过一次。所以你需要对它进行批处理。

一个可能的解决办法是https://github.com/petehunt/react-raf-batching

这将使整个反应批DOM变为requestAnimationFrame。如果他们假定渲染最多不需要16ms,那么这可能会制动其他组件。

更好的解决方案是从requestAnimationFrame回调中调用你的tick,实质上只是为你的List使用这个优化,而不是为你的整个应用。

+0

Good point Capaj! 0ms(10ms)的间隔会产生页面更新不切实际的情况。 requestAnimationFrame()会有所帮助,但是如果频率为**,那么我建议将它与setTimeout()结合使用,以便将100ms周期内的所有更新推迟到单页重绘。 – NicolaeS

0

感谢您的回复:)对不起,但我没有指定setInterval只是示例,但如果我将它改为例如100,这与CPU的情况相同。在我的应用程序中,我通过websockets获取数据,有时候我在很短的时间内(10-20毫秒)就获得了大量的数据,所以它会产生问题。应用程序是基于角度的,我的ng-repeat会因此而疯狂。

+0

在这种情况下,您应该尝试使用Angular。当您在ng-repeat表达式中使用'track by'时,ng-repeat的性能与React相当。您可以节省用户下载另一个大型JS文件的开销。请记住,最好是批量更改 - 当数据通过websocket从服务器返回时,不要执行作用域。$立即应用,而是执行RAF并执行scope。$在其回调中应用。这应该会更好。 – Capaj