我需要绘制一张大表,不是很大,大约400x400的单元格。但React渲染速度太慢,并且每次单击该单元格时,都应该更新单元格并且此更新需要相同的时间。有什么建议如何加快它?或者React不适合这样的任务?
以下是示例(表的大小略有缩小): https://jsfiddle.net/69z2wepo/15731/
var ROWSC = 400;
var COLSC = 100;
var Hello = React.createClass({
getInitialState: function () {
return {
t: { "1-1": 'c' }
};
},
clicked: function (k) {
var t = this.state.t;
t[k] = t[k] ? 0 : 'c';
this.setState({ t: t });
},
render: function() {
var items = [];
for (var r = 0; r < ROWSC; r++) {
var cols = [];
for (var c = 0; c < COLSC; c++) {
var k = ''+r+'-'+c;
cols.push(<td key={c} onClick={this.clicked.bind(this,k)} className={this.state.t[k]}> </td>);
}
items.push(<tr key={r}>{cols}</tr>);
}
return <table>
{items}
</table>
</div>;
}
});
React.render(<Hello name="World" />, document.getElementById('container'));
答案 0 :(得分:2)
默认情况下,React会重新呈现所有内容,但在出现性能问题时,
可以使用shouldComponentUpdate
函数来确定哪些部分
要在更新时排除的组件树。
在您的示例中,只有一行可以一次更新,所以 如果我们开始跟踪更新发生的行,我们只能确定 此行已更新。首先,我们必须引入一个新的组件来包装 表格行我们可以放置我们的钩子。
var Row = React.createClass({
shouldComponentUpdate: function(nextProps) {
return nextProps.mustUpdate;
},
render: function() {
return <tr>{this.props.children}</tr>;
}
});
然后我们可以像
一样使用它items.push(
<Row key={r}
mustUpdate={this.state.lastUpdatedRow === r}>
{cols}
</Row>);
此外,重新渲染所有这些细胞似乎也是浪费,所以我们可以介绍一下 另一个包装表格单元格的组件。
var Cell = React.createClass({
shouldComponentUpdate: function(nextProps) {
return this.props.selected !== nextProps.selected;
},
render: function() {
var props = this.props;
return (
<td onClick={props.onClick.bind(null, props.col, props.row)}
className={props.selected ? 'c' : ''}>
</td>
);
}
});
这可以让您在更新时获得显着的性能提升。如果还没有 对于您的特定问题已经足够好了,可能是React不适合您的用例。 无论如何,这是优化React程序的本质,您将组件拆分为更小 组件并确保只有实际更改的部分更新。
答案 1 :(得分:0)
当我在控制台中查看您的结果时,我注意到每个jsfiddle运行时都会弹出以下内容:
You are using the in-browser JSX transformer. Be sure to precompile your JSX for production - http://facebook.github.io/react/docs/tooling-integration.html#jsx
我按照链接看到文档在使用浏览器内JSX转换器时警告性能影响:
The in-browser JSX transformer is fairly large and results in extraneous computation client-side that can be avoided. Do not use it in production
也许用JSX预编译进行另一个测试会让你更好地了解这是否是React的一个很好的用例。
答案 2 :(得分:0)
两件事:
确保预编译JSX以避免这种缓慢。 (在jsfiddle中,您将看到一个控制台警告“您正在使用浏览器内的JSX转换器。请务必预编译您的JSX以进行生产”。
作为单个组件实现,其自身具有单击设置状态,导致组件必须重新处理整个表(因为setState
触发重建表DOM的render
。您可以通过创建表示每个表格单元格的组件来避免这种情况。然后在clicked
函数中,不要在Hello
上调用setState,只需在单击的单元格上调用setState
即可。这样只有改变的单元格才会重新渲染。
这对初始渲染没有帮助,但它会显着加快因点击而导致的UI更新。