我正在尝试寻找一种高效的算法来为一堆<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)',但这并没有任何影响。
(该列表包含动态生成的背景图像(不会被缓存,get的变化很大),加载大约1500个图像确实会降低速度,这就是我尝试这种方法的原因)
编辑:忘了提了,我想过写一个自定义的jQuery-selector来匹配elementInView返回true的元素,这是不是一个更好的方法?
发布于 2010-01-26 18:24:43
DOM很慢。要获得原始速度,您需要使用innerHTML。
为了避免字符串操作,您可以考虑JS模板引擎,有很多这样的引擎。
我们已经构建了模板引擎PURE,因为它很小而且速度很快,它可以很好地为手机构建页面。
另一种选择是考虑上游的问题。您确定要为用户提供数百项/数千项的列表吗?
发布于 2010-01-26 17:18:19
听起来你的应用程序做了大量的回流和重绘,这是一个主要的性能打击,也不利于用户体验,更不用说巨大的HTTP流量了。
你有没有想过在生成相关CSS的同时,可以在运行时进行spriting。这样,您就有希望减少HTTP请求,并减少重绘/回流的数量。
发布于 2010-01-26 18:29:33
首先,我建议使用分析器来真正了解是什么降低了您的代码速度。firefox (firebug)、chrome和explorer中都有分析器。但我现在能想到几个问题。
我假设所有LI都是同一个UL的子级,所以您可以直接访问它们(firstChild/nextSibling),而不需要调用$()。即使有多个UL,直接访问仍然比$()更快。
另一个可能的原因是复杂的CSS。我见过这样的情况,由于浮点数太多,对element的offsetTop进行单次访问只需要半秒。这可能会影响.height()和.position()的速度。
但是首先要有个人资料!
https://stackoverflow.com/questions/2138307
复制相似问题