在过去的Web开发中,我总是试图在javascript中构建选择器时从id下载,之前在jQuery中,最近使用document.querySelector()/。querySelectorAll()。这是出于性能原因。我在这样的帖子(http://www.artzstudio.com/2009/04/jquery-performance-rules/#descend-from-id)中遵循建议。
例如:
$('#new-address-form input.address')
可能明显快于
$('.address')
即使页面上只有一个带有一类地址的元素。如果DOM中有很多不同的类,在某些浏览器中这可能会更快很多(我正在看你IE< 8)。
但是,从经验来看,今天似乎不再是这种情况了。任何人都可以向我指出一些文档或代码,对于开源浏览器,可以确认现代浏览器按类索引元素吗?
答案 0 :(得分:1)
性能上存在差异,但除非您使用非常大的标记,否则它可能并不重要。
我设置了一个基准JS小提琴,它创建了20,000个div标签,每个标签嵌套10层深。然后尝试基于类随机选择一个,并再次基于具有后代类的ID。
我在这里对它进行了基准测试:https://jsfiddle.net/0wyLfnz8/14/
<强>结果
按ID选择,然后后代类在Chrome中平均为.018ms
按ID选择,然后后代类在IE中平均为39.33ms
仅按课程选择Chrome平均为12.178ms 在IE中,仅按类别选择平均为51.386ms
同样,这些结果以毫秒为单位,500次测试超过20,000个HTML元素
基准测试代码
$(document).ready(function() {
var d = new Date();
var st = d.getTime();
var start = st;
var et;
var max = 20000;
var numberOfTests = 500;
var elementDepth = 10;
for(var i = 1; i < max; i++) {
//lets make a random class too
r = Math.floor((Math.random() * 10) + 1);
var depth = "";
for(var j = 1; j<elementDepth;j++) {
depth += '<div class="depth' + j + '"></div>'
}
$('body').append('<div id="d'+i+'">'+depth+'<div class="depth'+elementDepth+'"><div class="c'+i+' r'+r+'">Hello, I am div number '+i+'</div></div></div>');
}
d = new Date();
var duration = d.getTime() - st;
console.log('Generating divs took ' + (duration/1000) + ' seconds');
idDuration = 0;
idTests = 0;
for(var i = 0; i < numberOfTests; i++) {
//choose a random div to select
r = Math.floor((Math.random() * max) + 1);
d = new Date();
st = d.getTime();
var tagbyID = $('#d'+r+ '.c'+r);
d = new Date();
et = d.getTime();
duration = et - st;
//console.log('Selecting by ID took ' + duration + ' milliseconds');
idDuration += duration;
idTests++;
}
console.log('---');
classDuration = 0;
classTests = 0;
for(var i = 0; i < numberOfTests; i++) {
//choose a random div to select
r = Math.floor((Math.random() * max) + 1);
d = new Date();
st = d.getTime();
var tagbyClass = $('.c'+r);
d = new Date();
et = et;
duration = d.getTime() - st;
//console.log('Selecting by class took ' + duration + ' milliseconds');
classDuration += duration;
classTests++;
}
console.log('---');
d = new Date();
console.log('total duration: ' + ((d.getTime() - start)/1000) + " seconds");
console.log('---');
console.log('Selecting by ID took '+idDuration+' milliseconds total over '+idTests+' tests.');
console.log('Selecting by class took '+classDuration+' milliseconds total over '+classTests+' tests.');
console.log('---');
console.log('Average time for ID selection using $(\'#parentID .childClassName\') was: ' + (idDuration / idTests)+" milliseconds")
console.log('Average time for class selection using $(\'.className\') was: ' + (classDuration / classTests)+" milliseconds")
})
答案 1 :(得分:0)
我可能已经回答了我自己的问题。我创建了一个jsperf,但我会重视更多的测试数据或改进。
http://jsperf.com/should-we-always-descend-by-an-id/6
编辑:在我的测试用例中,当你不从id下降时,jQuery实际上更快,但是明显的性能获胜者(跨浏览器)是 document.getElementsByClassName()。