我对大量的dom elmenets和性能有疑问。
假设我在一个页面上有6000个dom元素,并且随着用户与该页面进行交互(用户滚动创建一个新的dom元素)(例如twitter),可以增加元素的数量。
为了提高页面的性能,我只能想到两件事。
- 将不显示的项目设置为“无”,以避免回流
- 从dom中删除不可见的项目,然后根据需要重新添加。
他们是否还有其他方法可以改善包含许多dom元素的页面?
我对大量的dom elmenets和性能有疑问。
假设我在一个页面上有6000个dom元素,并且随着用户与该页面进行交互(用户滚动创建一个新的dom元素)(例如twitter),可以增加元素的数量。
为了提高页面的性能,我只能想到两件事。
他们是否还有其他方法可以改善包含许多dom元素的页面?
Answers:
我自己没有经验,但是这里有一些很棒的提示:http : //engineering.linkedin.com/linkedin-ipad-5-techniques-smooth-infinite-scrolling-html5
我看了一下Facebook,他们似乎并没有做什么特别是在Firefox上。向下滚动时,页面顶部的DOM元素不变。在Facebook不允许您进一步滚动之前,Firefox的内存使用量已攀升至约500兆。
Twitter似乎与Facebook相同。
Google地图是另一回事-看不见的地图图块已从DOM中删除(尽管不是立即删除)。
我们必须在FoldingText上处理类似的问题。随着文档的增大,创建了更多的线元素和关联的跨度元素。浏览器引擎似乎令人窒息,因此需要找到更好的解决方案。
这是我们所做的事情,可能对您有用或可能不有用:
将整个页面可视化为长文档,将浏览器视口可视为长文档特定部分的镜头。您实际上只需要显示镜头内的零件即可。
var top = document.scrollTop;
var width = window.innerWidth;
var height = window.innerHeight;
一些更多的资源来查找更多基于跨浏览器的视口:
我们已经有一个平衡的二进制搜索树用于文本编辑,因此我们也对其进行了扩展以管理行高,因此对于我们来说,这部分相对容易。我认为您不需要复杂的数据结构来管理元素高度。一个简单的数组或对象可能会很好。只要确保您可以轻松查询高度和尺寸即可。现在,您将如何获取所有元素的高度数据。非常简单(但是对于大量元素而言,计算量很大!)
var boundingRect = element.getBoundingClientRect()
我说的是纯JavaScript,但是如果您使用的是jQuery $.offset
,那么此处$.position
列出的方法将非常有帮助。
同样,使用数据结构仅作为缓存很重要,但是,如果需要,您可以即时进行(尽管正如我所说的,这些操作非常昂贵)。另外,请注意更改css样式并调用这些方法。这些功能会强制重绘,因此您会看到性能问题。
<div>
具有已计算高度的元素现在,您已经拥有存储在Data结构中的所有元素的高度,可以查询可见视口之前的所有元素。
创建一个<div>
css高度设置为元素高度之和的像素(以像素为单位)
对可见视口之后的元素重复上述步骤。
查找滚动和调整大小事件。在每个滚动上,您将需要返回到数据结构,删除填充器div,创建以前从屏幕上删除的元素,并相应地添加新的填充器div。
:)这是一个漫长而复杂的方法,但是对于大型文档,它大大提高了我们的性能。
我不确定我是否解释正确,但是此方法的要点是:
希望这可以帮助。
现在是2019年。这个问题确实很老,但是我认为它仍然是相关且有趣的,并且可能从今天起有所改变,因为我们现在都倾向于使用React JS。
我注意到,Facebook的时间轴似乎使用了内容簇,这些簇display: none !important
一旦消失就被隐藏了,因此DOM的所有先前呈现的元素都保留在DOM中,只是那些看不见的部分被隐藏了。display: none !important
。同样,隐藏群集的整体高度设置为隐藏群集的父级div
。
这是我制作的一些屏幕截图:
截至2019年,您如何看待这种方法?另外,对于那些使用React的人,如何在React中实现它?收到您对这个棘手主题的意见和想法,将是很棒的。
感谢您的关注!