Reg*_*ser 2 javascript jquery dom
我已经编写了这段代码来对jQuery和DOM性能进行基准测试.性能在每个浏览器中都是不同的,表现最差的Firefox X25运行jQuery的速度较慢.这是预期的行为吗?我并不期望看到jQuery会产生这样的影响.
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script>
<script language="JavaScript" type="text/javascript">
$(function () {
var i=0;
var dtb = new Date();
while(i < 1000000)
{
var index = Math.floor(Math.random()*30);
i++;
var elem = document.getElementById('d'+index);
}
var dte = new Date();
alert(dte-dtb);
i=0;
var dtb2 = new Date();
var body = document.getElementById('cog');
while(i < 1000000)
{
var index = Math.floor(Math.random()*30);
i++;
var elem = body.childNodes[index];
}
var dte2 = new Date();
alert(dte2-dtb2);
i=0;
var dtb3 = new Date();
while(i < 1000000)
{
var index = Math.floor(Math.random()*30);
i++;
var $elem = $("#d"+index);
}
var dte3 = new Date();
alert(dte3-dtb3);
/////EDIT//////
///// Implemented an Array as suggested by Erik Reppen ////////
i = 0;
var idNames=new Array(30);
while(i<30){
idNames[i] = $("#d"+i);
i++;
}
i=0;
var dtb4 = new Date();
while(i < 1000000)
{
var index = Math.floor(Math.random()*30);
i++;
var $elem = idNames[index];
}
var dte4 = new Date();
alert(dte4-dtb4);
/////EDIT//////////////////////////////////////////////
});
</script>
</head>
<body id="cog">
<div id="d0">sdfkjjfgdfd@@@</div><div id="d1">sdffgdfd@@@</div><div id="d2">sddfgfd</div><div id="d3">sdasfd</div><div id="d4">swqedfd</div><div id="d5">sddfdsfd</div><div id="d6">sdfd</div><div id="d7">sdsdffd</div><div id="d8">sdfsdfd</div><div id="d9">sdfkjlkjd</div><div id="d10">sdm ,nfd</div><div id="d11">sdcxvfd</div><div id="d12">sdxzcmfd</div><div id="d13">shgjmdfd</div><div id="d14">sdfvcbd</div><div id="d15">sdf;k;d</div><div id="d16">sdjklfd</div><div id="d17">sd412fd</div><div id="d18">sdfkyhkd</div><div id="d19">sdasdfd</div><div id="d20">sdhdfgsfd</div><div id="d21">sdfdsad</div><div id="d22">sdasdfd</div><div id="d23">sddfgdffd</div><div id="d24">sdklugiffd</div><div id="d25">sddfsafd</div><div id="d26">sdfq21fd</div><div id="d27">42324sdfd</div><div id="d28">sdnhmjkgufksfd</div><div id="d29">sdqwefdLAST</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
这个:
$('#someId');
Run Code Online (Sandbox Code Playgroud)
最终归结为JQuery函数说
document.getElementId('someId'); // and then wrap it in a JQuery object and return it
Run Code Online (Sandbox Code Playgroud)
但首先,它必须做一堆逻辑来根据你发送的arg弄清楚你的意图是什么.像(我知道还有更多):
它是一个字符串?是.有空格吗?不是.它是以'#','.'还是一些有效的tagName开头的?它以'#'开头.太棒了,只需抓住身份证,打包并退货.
现在尝试对此进行测试:
$('#someId.active > .someClass:visible')
Run Code Online (Sandbox Code Playgroud)
比.无论你在IE7中为DOM编写什么不敬虔的混乱,你都会看到JQuery的重点.
一般来说,重复DOM选择一遍又一遍是种愚蠢的事情不管你使用核心DOM方法或特别的JQuery做.这就像在循环中没有使用函数时紧紧抓住函数调用开销.尝试在缓存初始元素之后比较一些DOM方法和JQ等价物.JQ可能仍然会变慢,但我怀疑任何事情都要慢25倍.
var $_someId = $('#someId');
dom_someId = document.getElementById('someId');
//now try looping a JQuery method vs an equivalent set of DOM methods for each
Run Code Online (Sandbox Code Playgroud)
===无关,但帮助原始测试===
以下是每条评论的一些示例,并根据您的问题备份到循环之前要做的事情.
//caching ID names before loop
var i = 30,
idNames = [];
while(i--){ //confusing but tests as i, then inside i is i-=1
idNames[i] = 'd'+(i+1);
}
Run Code Online (Sandbox Code Playgroud)
注意:您将数组索引0-30,因此在循环中的随机索引构建语句之后终止+1.事实上我不确定为什么1-31不会炸毁你的childNodes循环,因为它永远不会击中第一个元素并且应该尝试访问两个不存在的东西.移除+1并且它正在挑选0-30 .上面的循环假设您想要1-31,但我只是看到HTML只上升到30并从1开始.
//caching object/property lookup and DOM Access/HTMLCollection/obj instantiation
var bodyChildren = body.childNodes; //DOM object lookups cost performance
//caching JQ so you can use the exact same loop afterwards
var bodyChildren = $('body').children();
//inside loops
bodyChildren[index];
Run Code Online (Sandbox Code Playgroud)
jQuery 是一个包装器,它以在每个主要浏览器中一致工作的方式标准化 DOM 操作。它的执行速度比直接 DOM 操作慢 25 倍是完全合理的。性能损失是简洁代码的权衡。
一般来说,JavaScript 是一种高度异步的语言。它的大部分用法涉及等待用户触发的回调或计时器。因为时间充足,所以性能几乎不成问题。用户不会注意到运行时间为 1 毫秒的进程与运行时间为 25 毫秒的进程之间的差异。
如果您的某个脚本的性能受到严重影响,请使用工具来分析代码在何处花费了最多时间。
毕竟,过早的优化是万恶之源。