如何避免使用overflow:hidden带来的性能损耗?

9
我有一个HTML表格,可能超过1K行和十几列。
我希望列的大小是固定的(由用户控制),不会在垂直或水平方向上增长/缩小。因此,特定表格单元格的内容在视觉上将在一行上,并且溢出将在单元格末尾被截断。
在Chrome中对大型表格进行性能分析,主要性能杀手是overflow:hidden
我尝试将每个单元格的内容放在输入框中,因为这会复制相同的视觉行为,但这会产生类似的性能影响。
人们推荐什么来提高性能?
如果必要,我不必使用table标记,但如果可以实现良好的性能,我更愿意坚持使用table标记。 更新1:我已经包含了一个文件,演示了性能问题here。警告文件非常庞大(25MB),会使您的计算机变慢。默认情况下,表格没有设置为hidden,一旦加载了表格(可能需要一段时间),浏览器性能就相对平稳。
然而,如果您编辑该文件并取消注释第12-15行,然后打开它。您会发现在加载浏览器后,表格的响应速度明显降低。

3
你为什么不使用分页功能呢? - Michael Christensen
有很多原因。主要是从用户体验的角度考虑。但是你可能会遇到这样一种情况,即只有100行数据而使用者的电脑速度较慢。提高性能不仅有益于拥有大量数据的用户,也有利于所有人。 - Omar Ismail
另外,您可以更具体地说明您所关注的性能方面吗?初始呈现时间、滚动、搜索、DOM 操作等等... - Ben Hull
表格加载后的一般浏览器性能。滚动、点击等。 - Omar Ismail
这里有什么新闻吗?我也遇到了同样的问题。 - JGoodgive
显示剩余2条评论
4个回答

3
FYI:我在iPad / iOS上遇到了这个问题,导致在表格中有大约一百行时出现性能问题,其中包含table-layout:fixed属性。只要单元格或单元格中的div获得强制绘制单元格的属性,它就需要大约300毫秒而不是100毫秒来绘制(这会使UI在我的情况下感觉非常缓慢)。两个属性之一(position:relative或overflow:hidden)对我造成了问题,删除它们可以优化速度,但如果单元格文本对于固定宽度列来说太宽,则会导致文本溢出。即使在绘制表格后,也会发生减速,因为我正在动态地在表格上方弹出绝对div。当通过(new Date).getTime()分析JavaScript时,在与表格无关的JavaScript位置测量减速。
[编辑:添加以下部分解决方案]
1. 将所有单元格内容放入span元素中(因此可以测量内容的offsetWidth而不是包含块元素的width)。 2. 将行附加到文档后,测试每个span.offsetWidth是否大于列宽度,如果是,请将"overflow:hidden"添加到包含块的样式(或通过类)。 3. 对于某些列(如果已知单元格内容永远不需要剪辑),可以跳过上述步骤1和2。
警告:
1. 仅针对iOS5 Safari进行测量(我没有分析任何其他浏览器)。 2. 对我们有用,因为我们动态创建表格行(使用JavaScript处理您的示例会很慢?)。 3. 我们的大多数数据单元格不会溢出(只需要少量剪辑 - 仅限于有限数量的单元格)。 4. 牺牲了初始页面加载(在页面中生成表格从80ms到800ms)。 5. 但是加快了动态组合弹出(从340ms降至130ms),提高了键盘响应速度。
对于您的情况,可能最快的方法是首先使用可变宽度列,测量所有列的offsetWidth,将列宽设置为像素宽度,并仅在列的offsetWidth大于用于列的像素宽度时在列上设置overflow:hidden。

2
您可以尝试使用平铺式方法。这是一种制作无限水平滚动游戏等内容的常见方法。
将所有数据放入JavaScript数组中,然后在具有N行可见的表格中拥有N + 1行。当您向下滚动时,最后一个项目会移动到视图中。在第一个项目移出视图的那一刻,您会将所有数据向上移动一行,并将滚动位置重置回起始位置。如果正确执行,该移位对用户来说将是完全透明的。您只会在N-行可见表中使用N + 1行。
我以前做过这个,但是在特定的UI约束条件下。我对使用内置浏览器滚动条等使其保持一致的想法感到有些不安。

1

Webkit bug 75001与此问题有关,它涵盖了解决该问题所做的工作(还请参阅bugzilla依赖项以获取更多信息)。


1
首先,使用表格所需的标记量比仅使用带有clear:both CSS的div来创建新行要大得多。这是第一个性能问题。
另外,您正在将溢出设置为类(?)
 <style type="text/css"> .ovfl { overflow:hidden; }</style>

  <td class="ovfl"></td>

顺便说一下,1000行是一个需要处理的重量。

使用div,您至少有更容易的机会将它们扔到一个带有display:none的div中(超出滚动条),直到访问者滚动到它们。

这项工作可能需要一些技巧。

希望有一些好的想法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接