我试图找到一种有效的算法来动态加载一堆<li>
的背景图像,并且存在一些效率问题。我当前的代码如下所示:
function elementInView($elem, vps, vpe) {
var elempos = $elem.position();
var pagestart = elempos.top + vps;
var pageend = elempos.top + vps + $elem.height();
var offset = 78 - Math.max(0,vps-pagestart) - Math.max(0,pageend-vpe);
// I want to update all items that are within 200 pixels of
// the current viewport
return (vpe > 0 && offset > -200);
}
$('#container').bind('scroll', function() {
var $container = $(this);
var vps = $container.scrollTop();
var vpe = vps + $container.height();
$('li:not(.bgset)', '#container').each(function() {
var $this = $(this);
if (elementInView($this,vps,vpe)) {
$this.addClass('.bgset');
// Set the background-image (doesn't affect performance noticably.)
}
});
});
对于包含约250个项目的列表,此过程花费200-600毫秒;对于包含约1500个项目的列表,此过程花费约1500毫秒,这使其几乎无法使用。
谁能看到任何问题,或者这基本上是最好的方法吗?我尝试使用所有
<li>
而不是$('li:not(.bgset)'
,但这实际上并没有任何影响。(该列表包含动态生成的背景图片(不会被缓存并且获取的内容已发生很大变化),并且加载约1500个图片确实会减慢一切,这就是我尝试这种方法的原因)
编辑:忘了提一下,我已经考虑过编写一个自定义jQuery选择器,该选择器匹配为
elementInView
返回true的元素,这会是更好的方法吗? 最佳答案
DOM很慢。为了获得原始速度,您需要使用innerHTML。
为了避免字符串操作,您可以考虑使用JS模板引擎,其中有很多。我们已经构建了模板引擎PURE,因为它很小且速度很快,因此可以很好地构建用于移动设备的页面。
另一个选择是在上游考虑问题。您确定要向用户提供成百上千项的列表吗?
关于javascript - 在滚动到 View 中时动态更改DOM元素(性能),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2138307/