8

在一个网页上,我有一个相当大的项目列表(例如,产品卡,每个都包含图像和文本) - 其中大约 1000 个。我想在客户端过滤这个列表(只显示那些没有被过滤掉的项目),但是存在渲染性能问题。我应用了一个非常窄的过滤器,只剩下 10-20 个项目,然后取消它(因此必须再次显示所有项目),浏览器(非常好的机器上的 Chrome)挂断一两秒钟。

我使用以下例程重新渲染列表:

for (var i = 0, l = this.entries.length; i < l; i++) {
    $(this.cls_prefix + this.entries[i].id).css("display", this.entries[i].id in dict ? "block" : "none")
}

dict 是允许项目的 id 的哈希值

这个函数本身立即运行,它的渲染挂了。是否有比更改 DOM 元素的“显示”属性更优化的重新渲染方法?

提前感谢您的回答。

4

3 回答 3

7

为什么要加载 1000 个项目?首先,您应该考虑分页之类的东西。每页显示大约 30 个项目。这样,您就不会加载那么多。

然后,如果您真的很喜欢“循环很多项目”,请考虑使用超时。这是我曾经做过的一个演示,它说明了循环的后果。它会阻塞 UI 并导致浏览器滞后,尤其是在长循环时。但是当使用定时器时,你会延迟每次迭代,让浏览器偶尔呼吸,并在下一次迭代开始之前做一些其他的事情。

另一件需要注意的事情是你应该避免重绘和重排,这意味着避免在不必要的时候经常移动元素和改变样式。另外,另一个技巧是从 DOM 中删除实际上不可见的节点。如果您不需要显示某些内容,请将其删除。为什么要浪费内存放一些实际上没有看到的东西?

于 2012-04-14T05:53:52.447 回答
1

伙计 - 处理“大量 DOM 元素”的最佳方法是不在客户端上执行此操作,和/或如果可以避免,请不要使用 Javascript。

如果没有更好的解决方案(我相信可能有!),那么至少将您的工作集划分为您当时实际需要显示的内容(而不是整个,大,honkin' enchilada!)

于 2012-04-14T05:49:51.203 回答
0

您可以使用setTimeout从主线程卸载循环调用并避免客户端冻结的技巧。我怀疑整个处理过程——从开始到结束——会持续相同的时间,但至少这样界面仍然可以使用,结果是更好的用户体验:

for (var i = 0, l = this.entries.length; i < l; i++) {
  setTimeout(function(){
    $(this.cls_prefix + this.entries[i].id).css("display", this.entries[i].id in dict ? "block" : "none")
  }, 0);
}
于 2016-08-21T10:08:44.483 回答