性能与无限滚动或许多DOM元素?
我有一个很大的问题和性能问题。
比方说,我在页面上有6000个DOM元素,当用户与页面交互(用户滚动来创build一个新的DOM元素)像Twitter一样,元素的数量可以增加。
为了提高页面的性能,我只能想到两件事情。
- 将显示设置为不显示项目以避免重排
- 从DOM中删除不可见的项目,然后根据需要重新添加它们。
他们有没有其他的方式来改善一个有很多dom元素的页面?
没有经验我自己,但这里有一些很棒的提示: http : //engineering.linkedin.com/linkedin-ipad-5-techniques-smooth-infinite-scrolling-html5
我看了一下Facebook,他们似乎没有做任何特别的事情在Firefox上。 向下滚动时,页面顶部的DOM元素不会更改。 在Facebook不允许你进一步滚动之前,Firefox的内存使用量将攀升至500兆左右。
Twitter似乎和Facebook一样。
谷歌地图是一个不同的故事 – 从DOM中删除地图瓷砖(虽然不是立即)。
我们不得不在FoldingText上处理类似的问题。 随着文档变大,更多的线元素和相关的span元素被创build。 浏览器引擎似乎窒息,所以需要find更好的解决scheme。
以下是我们所做的,可能会或可能不会有用于您的目的:
将整个页面可视化为长文档,浏览器视口作为长文档特定部分的镜头。 你真的只需要显示镜头内的部分。
所以第一部分是计算可见的视图端口。 (这取决于你的元素如何放置,绝对/固定/默认)
var top = document.scrollTop; var width = window.innerWidth; var height = window.innerHeight;
还有一些资源可以find更多基于跨浏览器的视口:
使用JavaScript获取浏览器视口尺寸
用于检测浏览器窗口的scrollTop的跨浏览器方法
其次,您需要一个数据结构来了解哪些元素在该区域中可见
我们已经有了一个用于文本编辑的平衡二叉search树,所以我们扩展它来pipe理线高度,所以这部分对我们来说相对容易一些。 我不认为你需要一个复杂的数据结构来pipe理你的元素高度; 一个简单的数组或对象可能会很好。 只要确保您可以轻松地查询高度和尺寸。 现在,你将如何获得所有元素的高度数据。 一个非常简单的(但是对于大量的元素来说,计算量很大!)
var boundingRect = element.getBoundingClientRect()
我用纯JavaScript来说话,但如果你使用jQuery $.offset
, $.position
和这里列出的方法将是相当有帮助的。
同样,使用数据结构仅仅作为一个caching很重要,但是如果你愿意的话,你可以随时做(尽pipe我已经说过这些操作是昂贵的)。 另外,要小心改变CSS样式并调用这些方法。 这些function强制重绘,所以你会看到一个性能问题。
最后,只需用一个单独的元素(例如具有计算高度的元素)replace屏幕外的元素即可
-
现在,对于存储在数据结构中的所有元素,都有高度查询位于可见视口之前的所有元素。
-
用css高度设置(以像素为单位)创build一个
<div>
为元素高度的总和 - 用类名标记,以便知道它的填充格
- 删除这个div覆盖的dom中的所有元素
- 插入这个新创build的div
对可见视口之后的元素重复。
寻找滚动和resize的事件。 在每个滚动中,您将需要返回到您的数据结构,删除填充div,创build以前从屏幕上删除的元素,并相应地添加新的填充div。
:)这是一个漫长而复杂的方法,但是对于大型文档,它大大提高了我们的性能。
TL;博士
我不确定是否正确解释,但是这个方法的要点是:
- 知道你的元素的垂直维度
- 知道滚动的视图端口
- 用一个div(高度等于它所覆盖的所有元素高度的总和)表示所有离屏元素,
- 在任何给定的时间,您总共需要两个div,一个用于可见视口之上的元素,另一个用于下面的元素。
- 通过监听滚动和调整事件大小来跟踪视图端口。 重新创build相应的div和可见元素
希望这可以帮助。