9

我有一个可以超过 1K 行和十几列的 HTML 表。

我希望列是固定大小(可由用户控制),并且不会垂直或水平增长/收缩。因此,在视觉上,特定表格单元格的内容将在一行上,并且溢出在单元格末尾被切断。

在 Chrome 中对大表进行性能分析,主要的性能杀手是overflow:hidden

我尝试将每个单元格的内容放在输入中,因为这会复制相同的视觉行为,但会产生类似的性能影响。

人们推荐什么来提高性能?

如有必要,我不必使用表格标签,但如果可以实现良好的性能,我宁愿坚持使用表格标签。

更新 1:我在这里包含了一个演示性能问题的文件。警告该文件非常庞大 (25MB),会降低您的计算机速度。默认情况下,该表没有将溢出设置为隐藏,并且一旦加载了表(可能需要一段时间),浏览器的性能相对平稳。

但是,如果您编辑文件并取消注释第 12-15 行,然后打开它。在桌子周围加载浏览器后,您会看到响应速度明显降低。

4

4 回答 4

3

仅供参考:我在 iPad/iOS 上遇到了这个问题,导致一个页面在 table-layout:fixed 的表格中有大约一百行的页面出现性能问题。

一旦一个单元格或单元格中的一个 div 获得一个强制它单独绘制该单元格的属性,则绘制大约需要 300 毫秒而不是 100 毫秒(这导致 UI 在我的情况下感觉非常缓慢)。

两个属性(position:relativeoverflow:hidden)中的任何一个都对我造成了问题,删除它们优化了速度,但如果单元格文本对于固定宽度的列来说太宽,则会导致文本溢出。

即使在绘制表格之后,速度也会放缓,因为我在表格上动态弹出一个绝对 div。分析 javascript(使用(new Date).getTime())时,在 javascript 中与表格无关的地方测量减速。

[编辑:添加以下作为部分解决方案]

  1. 将所有单元格内容放在一个span元素内(因此可以测量内容的 offsetWidth 而不是包含块元素的宽度)。
  2. 将行附加到文档后,测试每个 span.offsetWidth 是否大于列宽,如果是,则将“overflow:hidden”添加到包含块的样式(或通过类)。
  3. 对于某些列,可以跳过上面的 1 和 2(如果知道单元格内容永远不需要剪辑)。

注意事项:

  1. 仅针对 iOS5 Safari 进行了测量(我没有分析任何其他浏览器)。
  2. 对我们有用,因为我们动态创建表行(使用 javascript 处理您的示例会很慢?)。
  3. 我们数据的大多数单元格不会溢出(只需要少量裁剪 - 只需要有限数量的单元格)。
  4. 初始页面加载受损(页面中表格的生成时间从 80 毫秒变为 800 毫秒)。
  5. 但是加快了动态组合弹出窗口(340 毫秒到 130 毫秒)的速度,从而提供了更好的键盘响应能力。

对于您的情况,可能很快首先使用可变宽度列,测量所有列的 offsetWidth,将列宽设置为像素宽度并设置溢出:仅在列的 offsetWidth 大于您将用于的像素宽度的列上隐藏柱子。

于 2012-06-28T01:38:43.080 回答
2

您可以尝试使用平铺方法。这是一种非常典型的高效制作无限横向滚动游戏的方法。

将所有数据放入 Javascript 数组中,然后在有 N 行可见的表中包含 N + 1 行。当您向下滚动时,最后一个项目将进入视图。在您滚动到足够远以至于第一个项目移出视图的那一刻,您将所有数据向上移动一行并将滚动位置重置回它开始的位置。如果操作正确,这种转变对用户来说是完全透明的。您只能在 N 行可见表中使用 N + 1 行。

我以前做过,但是在非常具体的 UI 限制下。一想到使用内置的浏览器滚动条等使这一点保持一致,我就有点犹豫了。

于 2012-05-16T00:03:26.730 回答
1

首先,拥有一个表格所需的标记量比仅使用带有 clear:both css 的 div 用于新行要大得多。所以这是第一个性能命中。

另外,您将溢出设置为一个类(?)

 <style type="text/css"> .ovfl { overflow:hidden; }</style>

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

顺便说一句,1000 行是交付的重量。

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

在这项工作中最有可能猫的皮肤很少,

希望有一些好的想法。

于 2012-05-15T23:22:14.343 回答
1

Webkit 错误 75001与此问题有关,它涵盖了为解决该问题所做的工作(有关信息,另请参阅 bugzilla 依赖项)。

于 2012-06-29T04:12:02.823 回答