动态更改DOM元素,因为它们被滚动到视图中(性能)

我正在尝试找到一种有效的算法来为一堆

  • 动态加载背景图像,并且存在一些效率问题。 我当前的代码如下所示:

     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:not(.bgset)' ,但这根本没有任何影响。

    (该列表包含动态生成的背景图像(不会被缓存并且得到很多改变),并且加载大约1500个它们确实减慢了所有内容,这就是我尝试这种方法的原因)

    编辑:忘了提,我已经考虑过编写一个自定义的jQuery选择器,它匹配为elementInView返回true的元素,这会是一个更好的方法吗?

    DOM很慢。 要获得原始速度,您需要使用innerHTML。
    为了避免字符串操作,您可以考虑使用JS模板引擎,其中有很多。
    我们已经构建了模板引擎PURE ,因为它小巧而快速,它可以很好地为移动设备制作页面。

    另一种选择可能是考虑上游问题。 您确定要为您的用户提供数百/数千个项目的列表吗?

    听起来你的应用程序做了大量的回流和重绘,这是一个主要的性能打击以及对用户体验不好,从来没有发现大量的HTTP流量。

    你有没有想过可能会在同时生成相关的CSS的同时进行spriting。 这样,您可以希望减少HTTP请求并减少重绘/重排的数量。

    首先,我建议使用分析器来了解减慢代码速度的真正原因。 firefox(firebug),chrome和explorer中都有个人资料。 但我现在可以想到一些问题。

    我想所有LI都是同一个UL的子firstChild ,因此您可以直接访问它们( firstChild / nextSibling )而无需调用$() 。 即使有多个UL,直接访问仍然比$()更快。

    另一个可能的原因是复杂的CSS。 我见过一个案例,因为太多浮动和定位单一访问元素的offsetTop花了半秒钟。 这可能会影响.height().position()

    但首先是个人资料