我在常见 CSS元素上重复使用document.getElementById
。
如果我创建global array
来存储我的所有document.getElementById
元素而不是每次都重新获取元素,会不会有显着的性能提升?
示例,而不是:
document.getElementById("desc").setAttribute("href", "#");
document.getElementById("desc").onclick = function() {...};
document.getElementById("desc").style.textDecoration = "none"
document.getElementById("asc").setAttribute("href", "#");
document.getElementById("asc").onclick = function() {...};
document.getElementById("asc").style.textDecoration = "none"
...
简单地做:
var GlobalElementId = [];
GlobalElementId ["desc"] = document.getElementById("desc");
GlobalElementId ["asc"] = document.getElementById("asc");
GlobalElementId [...] = document.getElementById(...);
GlobalElementId ["desc"].setAttribute("href", "#");
GlobalElementId ["desc"].onclick = function() {...};
GlobalElementId ["desc"].style.textDecoration = "none"
...
答案 0 :(得分:21)
所以所有“是”的答案都在困扰我,所以我实际上计时了,看看getElementById是否很慢!
以下是结果(表示包含10,000个元素的页面):
IE8 getElementById:0.4844 ms
IE8 id数组查找:0.0062 ms
Chrome getElementById:0.0039 ms
Chrome ID阵列查找:0.0006 ms
Firefox 3.5与chrome相当。
每个函数调用半毫秒不会让我使用数组;) 但也许它在IE6上更糟糕,我还没有安装。
这是我的剧本:
<html>
<head>
<script type="text/javascript">
var numEles = 10000;
var idx = {};
function test(){
generateElements();
var t0 = (new Date()).getTime();
var x = selectElementsById();
var t1 = (new Date()).getTime();
var time = t1 - t0;
generateIndex();
var t2 = (new Date()).getTime();
var x = selectElementsWithIndex();
var t3 = (new Date()).getTime();
var idxTime = t3 - t2;
var msg = "getElementById time = " + (time / numEles) + " ms (for one call)\n"
+ "Index Time = " + (idxTime/ numEles) + " ms (for one call)";
alert(msg);
}
function generateElements(){
var d = document.getElementById("mainDiv");
var str = [];
for(var i=0;i<numEles;i++){
str.push("<div id='d_" + i + "' >" + i + "</div>");
}
d.innerHTML = str.join('');
}
function selectElementsById(){
var eles = [];
for(var i=0;i<numEles;i++){
var id = ((i * 99) % numEles);
eles.push(document.getElementById("d_" + id));
}
return eles;
}
function generateIndex(){
for(var i=0;i<numEles;i++){
var id = "d_" + i;
idx[id] = document.getElementById(id);
}
}
function selectElementsWithIndex(){
var eles = [];
for(var i=0;i<numEles;i++){
var id = ((i * 99) % numEles);
eles.push(idx["d_" + id]);
}
return eles;
}
</script>
</head>
<body onload="javascript:test();" >
<div id="mainDiv" />
</body>
</html>
答案 1 :(得分:7)
既然你说“CSS元素”我怀疑你的很多性能不是因为重复使用document.getElementById()
(你应该避免使用),而是你修改{{1}的次数对象为给定节点。
每次更改style
上的属性时,都会强制浏览器重新绘制该元素,可能还会重新绘制页面上的其他元素。
style
这里,更好的解决方案是使用CSS类并从节点切换或添加/删除类名。这样,您只需一次重新绘制即可打包所需的样式更改。
var elem = document.getElementById( 'desc' );
elem.style.textDecoration = "none"; // browser re-draw
elem.style.borderWidth = "2px"; // browser re-draw
elem.style.paddingBottom = "5px"; // browser re-draw
答案 2 :(得分:3)
对我来说,这样做更合适,更有利于表现:
var desc = document.getElementById("desc");
var asc = document.getElementById("asc");
desc.setAttribute("href","#");
asc.onclick = function() { ... }
...
在重新考虑ChaosPandion所说的话之后,我认为有一种方法可以做到:
var elements = ["desc", "asc", ...];
for(var i = 0; i < elements.length; i++) {
GlobalElementId[elements[i]] = document.getElementById(elements[i]);
}
答案 3 :(得分:2)
是!
不久前有一种情况我在修改元素时表现不佳。 解决方案是像你的例子一样建立一个字典。我的性能提升了1000倍(至少在IE6中)。
var elementCache = {};
function buildElementCache() {
elementCache[id] = {
element1: document.getElementById(id + "1"),
element2: document.getElementById(id + "2")
}
// Etc...
}
答案 4 :(得分:1)
取决于'重要'的定义。 GlobalElementId.asc
数组访问比getElementById()
调用的速度快得多。但是,与你的脚本可能正在进行的大多数其他DOM操作相比,getElementById
仍然非常快,并且很可能只是脚本执行时间的一小部分。
我首先为可读性而写,Soufiane的答案看起来最好。只有在实践中脚本部分被证明太慢才会开始考虑查找缓存,这会增加额外的复杂性(特别是如果你在运行时开始更改这些元素)。
附注:不要使用setAttribute
,它在IE中被窃听,并且不如仅使用像element.href= '...';
这样的DOM Level 1 HTML属性。
答案 5 :(得分:1)
简短的回答是肯定的,任何时候你可以将Javascript变量或对象引用到本地,这将有助于提高性能。
如果您希望更深入地了解范围管理及其对Javascript的性能影响,Speed Up Your Javascript技术讲座有一些非常好的信息。强烈推荐观看。
答案 6 :(得分:0)
是的,但是使用数组会使它过度。
请参阅Soufiane Hassou关于如何做到的答案。
答案 7 :(得分:0)
它被称为对象缓存,它将提升你的脚本性能 有关详细信息,请参阅http://www.javascriptkit.com/javatutors/efficientjs.shtml 此外,如果您经常更改CSS,我建议使用@Fahad建议的jQuery。
答案 8 :(得分:0)
不,不会有显着的性能提升。你的表现问题在别处。浏览器在元素id上有自己的索引 - &gt;元素对象。
如果你想知道为什么你的代码很慢,那么定时它是非常重要的,因为缓慢的部分可能不是你所期望的(我发现这很难)。你可以这样做:
var t0 = (new Date()).getTime();
var t1 = (new Date()).getTime();
var time = t1 - t0;
虽然重要的是要注意这里的准确度是15ms,这意味着如果某些东西花了14ms,它可能会在某些浏览器中显示为0ms。
这是你的代码在jQuery中的样子:
$("#desc").attr("href", "#")
.click(function(){})
.css("text-decoration", "none");
答案 9 :(得分:0)
在IE浏览器中,答案是肯定的!
我做了一个基准测试(类似于Mike Blandford)并发现了这一点 当您在IE浏览器中调用document.getElementById()时,它会遍历DOM,直到找到具有所需id的元素,而不是保留id-to-element map / hashtable。 (可怕,我知道)。
因此,如您所提供的那样,创建一个数组将是一个非常好的性能提升。