【发布时间】:2016-09-09 17:52:58
【问题描述】:
考虑下面的代码。 <GridBody Rows={rows} /> 并想象 rows.length 将等于 2000 或更多的任何值,在此示例中每个数组大约有 8 列。我使用此代码的更扩展版本来呈现表格的一部分,该表格一直在限制我的 Web 应用程序。
var GridBody = React.createClass({
render: function () {
return <tbody>
{this.props.Rows.map((row, rowKey) => {
return this.renderRow(row, rowKey);
})}
</tbody>;
},
renderRow: function (row, rowKey) {
return <tr key={rowKey}>
{row.map((col, colKey) => {
return this.renderColumn(col, colKey);
})}
</tr>;
},
renderColumn: function (col, colKey) {
return <td key={colKey} dangerouslySetInnerHTML={{ __html: col } }></td>;
}
});
现在进入实际问题。看起来计算(即使使用我自己的代码)似乎快得惊人,甚至 ReactJS 与 virtualDOM 的工作也没有问题。
但是reactJS中有这两个事件。
componentWillUpdate 直到一切正常。
然后是componentDidUpdate,这似乎很好,而且都在 chrome 上。
问题
但是 IE11/Edge 的速度比任何其他浏览器都慢大约 4-6 秒,而使用 F12-Inspector 这似乎要慢到 8 秒比 Chrome。
我已尝试解决此问题的步骤:
去除不必要的代码。
将计算时间缩短几毫秒。
将网格拆分为松散的组件,这样 virtualDOM 就不会尝试 一次更新整个组件。
尝试将所有内容连接为字符串并允许对 只设置一次innerhtml。这实际上似乎是 IE 中的一个错误 大字符串在 IE11 上大约需要 25-30 秒。而且只有 30 毫秒 铬。
我还没有找到合适的解决方案。我在上面所做的操作似乎使 IE 中的情况变得不那么糟糕,但问题仍然存在,即“现代”或“最新”浏览器仍然慢 3-4 秒。
更糟糕的是,这似乎几乎冻结了整个浏览器并且正在渲染。
tl;dr 如何提高 IE 和其他浏览器(如果可能)的整体性能?
如果我的问题不清楚,我深表歉意,我在这件事上筋疲力尽。
edit:特别是 IE 上的 DOM 访问速度很慢,因为设置的 innerHTML 被调用超过 10.000 次。这可以在 ReactJS 中防止吗?
【问题讨论】:
-
如果可以覆盖渲染。你可以做的是大幅提高性能,重用行。我的意思是,如果您一次显示 10 行,则在 dom 中创建 20 行(不是整个 2000+),然后当用户滚动时,显示下一组,清除前 10 行数据并放入下一组里面的数据。详细说明该想法的参考:(尽管针对不同的库)elements.polymer-project.org/elements/iron-list。请参阅“为什么要使用
部分。希望这会有所帮助! -
我们正在考虑实现类似的东西,但问题是我们希望用户能够使用 CTRL+F 在如此大的列表中进行搜索,因为这是必需的。
-
在这种情况下,您是否可以不只是在网格顶部或下方或列上添加搜索字段,然后在 javascript 中搜索您的数据集,而不是遍历 dom,如果在您的数据集(在 JS 中的内存中),将该项目以及周围的 10 个项目加载到 dom 中。我确实同意它会感觉不那么无缝..也许一些动画可以帮助解决这个问题。
-
这需要我加载整个数据集(可以超过 100 万行)才能实现相同的功能。我们目前将其限制为 2000 并使用分页。应用程序中已经存在搜索功能,但并不能真正解决 2000 个结果的性能问题。
-
有些疯狂;我不知道您是否可以在 Javascript 中覆盖 cntrl+f 搜索。如果是这样,您可以捕获关键事件,搜索您在内存中(但不是在 dom 中!)中保存的 2000 条记录,对吗?然后你仍然可以回收可能 100-200 个 dom 元素,同时在内存中一次保留 2k 条记录。我认为结合我的第一个和第二个答案 + 您当前如何处理加载的 2k 记录之外的搜索应该能够解决您的问题。
标签: javascript reactjs internet-explorer large-data