queryspeed
QuerySpeed.js
( function (){ if (!String.prototype.trim){ String.prototype.trim = function (){ return this .replace(/^[\s\xa0]+|[\s\xa0]+$/g, '' ); } } var mix = function (target, source ,override) { var i, ride = (override === void 0) || override; for (i in source) { if (ride || !(i in target)) { target[i] = source[i]; } } return target; } var dom = {}; var metaObject = { '\b' : '\\b' , '\t' : '\\t' , '\n' : '\\n' , '\f' : '\\f' , '\r' : '\\r' , '\\' : '\\\\' }, _startOfHTML = "\t__views.push(" , _endOfHTML = ");\n" , _rAt = /(^|[^\w\u00c0-\uFFFF_])(@)(?=\w)/g; ( function (w,s){ //http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx s = [ "XMLHttpRequest" , "ActiveXObject('Msxml2.XMLHTTP.6.0')" , "ActiveXObject('Msxml2.XMLHTTP.3.0')" , "ActiveXObject('Msxml2.XMLHTTP')" , "ActiveXObject('Microsoft.XMLHTTP')" ]; if ( !-[1,] && w.ScriptEngineMinorVersion() === 7 && location.protocol === "file:" ){ s.shift(); } for ( var i = 0 ,el;el=s[i++];){ try { if (eval( "new " +el)){ dom.xhr = new Function( "return new " +el) break ; } } catch (e){} } })( this ); mix(dom,{ queryId : function (id, context) { var el = (context || document).getElementById(id); return el && [el] || [] }, queryTag : function (tag,context){ var flag_skip = tag !== "*" ,result = [],els = (context || document).getElementsByTagName(tag); if (-[1,]){ return Array.prototype.slice.call(els) } else { for ( var i = 0,ri = 0,el;el = els[i++];) if (flag_skip || el.nodeType === 1){ result[ri++] = el } } return result; }, each: function (array,fn,bind){ for ( var i = 0, n = array.length; i < n; i++){ if (i in array){ if (fn.call(bind, array[i], i, array) === false ){ break ; } } } }, numberOfWindow : 0, numberOfIframe : 0, hasReady : function (){ if (dom.numberOfWindow === dom.numberOfIframe ){ var el = dom.queryId( "hasReady" )[0] el.innerHTML = "已经准备就绪!" ; el.style.color = "#a9ea00" ; } }, addEvent: document.addEventListener ? function (el,type,fn){ el.addEventListener(type,fn, false ); } : function (el,type,fn){ el.attachEvent( "on" +type, function (){ return fn.call(el,window.event) }) }, quote: String.quote || function (str) { return '"' + str.replace(/[\\\"\x00-\x1f]/g, function (a) { var c = metaObject[a]; return typeof c === 'string' ? c : '\\u' + ( '0000' + a.charCodeAt(0).toString(16)).slice(-4); }) + '"' }, ejs_partial: function (url){ var xhr = dom.xhr(); xhr.open( "GET" ,url, false ); xhr.setRequestHeader( "If-Modified-Since" , "0" ); xhr.send( null ); return xhr.responseText|| "" }, ejs: function (obj,usePart){ if (!usePart){ //如果普通模板,则要整理配置文件 obj.left = obj.left || "<&" ; obj.right = obj.right || "&>" ; obj.rLeft = obj.rLeft || new RegExp( "\\s*" + obj.left+ "\\s*" ); obj.rRight = obj.rRight || new RegExp( "\\s*" + obj.right+ "\\s*" ); } //取得缓存索引 var key = obj.selector || obj.url, rAt = _rAt, startOfHTML = _startOfHTML, endOfHTML = _endOfHTML, self = arguments.callee, buff = [ "var __views = [];\n" ],str; if (obj.selector){ var el = dom.queryId(key); if (!el.length) throw "can not find the target element" ; str = el[0].text; } else { str = dom.ejs_partial(obj.url); if (!str) throw "the target file does not exist" ; } if (!self[key]){ var arr = str.trim().split(obj.rLeft),temp = [],url,selector,i=0,n=arr.length,els,segment,logic; while (i<n){ segment = arr[i++]; els = segment.split(obj.rRight); if (segment.indexOf(obj.right) !== -1){ //这里不使用el.length === 2是为了避开IE的split bug switch (els[0].charAt(0)) { case "~" : //include 局部模板 以URL方式引入 delete obj.selector; obj.url = els[0].substring(1).trim(); self[url] = self[url] || self(obj, true ); temp = temp.concat(self[url] ); break ; case ":" : //include 局部模板 以元素选择符方式引入 delete obj.url; selector = obj.selector = els[0].substring(1).trim(); self[selector] = self[selector] || self(obj, true ); alert(temp) temp = temp.concat(self[selector] ); break ; case "=" : //处理后台返回的变量(输出到页面的); logic = els[0].substring(1); if (logic.indexOf( "@" ) !== -1){ temp.push(startOfHTML, logic.replace(rAt, "$1data." ), endOfHTML); } else { temp.push(startOfHTML, logic, endOfHTML); } break ; case "#" : //处理注释 break ; default : logic = els[0]; if (logic.indexOf( "@" ) !== -1){ temp.push(logic.replace(rAt, "$1data." ), "\n" ); } else { temp.push(logic, "\n" ); } } els[1] && temp.push(startOfHTML, dom.quote.call( null ,els[1]), endOfHTML) } else { temp.push(startOfHTML, dom.quote.call( null ,els[0]), endOfHTML) } } if (usePart){ //局部模板 return (self[key] = temp); } else { //缓存模板函数 self[key] = new Function( "data" , buff.concat(temp).join( "" ) + ';return __views.join("");' ); } } return self[key](obj.data || {}); } }); window.dom = dom; //要测试的框架 var frameworks = { "Peppy 0.1" :{ disable:1, file: "peppy.js" , fun: "$" }, "uuQuery v1.01" :{ file: "uuQuery.js" , fun: "uuQuery" }, "DOMAssistant2.8" :{ disable:1, file: "DOMAssistantComplete-2.8.js" , fun: "$" }, "query v3.9" :{ file: "queryv39.js" , fun: "dom.query" }, "Fox" :{ disable:1, file: "Fox.js" , fun: "Fox.query" }, "jQuery1.4.4" :{ disable:1, file: "jquery1.4.4.js" , fun: "jQuery" }, "Sizzle" :{ file: "sizzle.js" , fun: "Sizzle" }, "Sly v1.0rc2" :{ disable:1, file: "Sly.js" , fun: "Sly.search" }, "inQuery" :{ disable:1, file: "inCore.js,inQuery.js" , fun: "$" }, "EXT 2.2" :{ disable:1, file: "ext-2.2.js" , fun: "Ext.query" }, "JQuery 1.2.6" :{ disable:1, file: "jquery-1.2.6.js" , fun: "jQuery" }, "MooTools 1.3" :{ disable:1, file: "mootools.js" , fun: "$$" }, "YUI 2.6.0" :{ disable:1, file: "YUI-2.6.0.selector-beta.js" , fun: "YAHOO.util.Selector.query" }, "myframework" :{ disable:1, file: "myFramework.js" , fun: "getElements" }, "Dojo 1.2.0" :{ disable:1, file: "dojo-1.2.0.js" , fun: "dojo.query" } } //要测试的选择器 var selectors = [ "div :only-of-type" , "th:first-of-type" , "th:last-of-type" , "td:nth-of-type(even)" , "td:nth-last-of-type(odd)" , "body :empty" , "div:not(.example)" , "p:contains(selectors)" , "div p a" , // "div, p, a", "div p" , "body div" , ".note" , "ul.toc li.tocline2" , "ul.toc > li.tocline2" , "tr .pattern" , "p" , "div" , "div ~ p" , "div > div" , "div ~ div" , "div > p" , "body" , "div + p" , "div ~ p" , "div[class^=exa][class$=mple]" , "div.example" , "ul .tocline2" , "div.example, div.note" , "#title" , "h1#title" , "div #title" , "h1#title + div > p" , "a[href][lang][class]" , "div[class]" , "div[class=example]" , "div[class^=exa]" , "div[class$=mple]" , "div[class*=e]" , "div[class|=dialog]" , "div[class!=made_up]" , "div[class~=example]" , "p:nth-child(even)" , "p:nth-child(2n)" , "p:nth-child(odd)" , "p:nth-child(2n+1)" , "p:nth-child(n)" , "p:only-child" , "p:last-child" , "p:first-child" , "div :only-child" , "td:odd" , "p:even" ] window.onload = function (){ dom.queryId( "iframes_tc" )[0].innerHTML = dom.ejs({ selector: "iframes_tmpl" , data:{ frameworks:frameworks } }); dom.queryId( "table_tc" )[0].innerHTML = dom.ejs({ selector: "table_tmpl" , data:{ frameworks:frameworks, selectors:selectors } }); var tbody = dom.queryTag( 'tbody' )[0]; var tfoot = dom.queryTag( 'tfoot' )[0]; var lastrow = dom.queryTag( 'tr' ,tfoot)[0]; var startTest = dom.queryId( "startTest" )[0]; var stopTest = dom.queryId( "stopTest" )[0]; var scoreNum= {}; //用于放置积分 var scoreTds = {}; //用于放置存在积分的TD元素 var cellIndex = 1; var framework; for ( var name in frameworks){ framework = frameworks[name]; if (!framework.disable){ framework.window = window.frames[name]; framework.selectors = selectors.concat(); scoreTds[name] = lastrow.cells[cellIndex++] dom.numberOfWindow++; scoreNum[name] = 0; } } var tests = [] ,rows = tbody.rows dom.each(selectors, function (selector, i){ //构建测试单元数组,个数为tbody的TD数 var cellIndex = 1,row = rows[i],framework; for ( var name in frameworks){ framework = frameworks[name]; if (!framework.disable){ tests.push({ 'window' : framework.window, //执行环境 'selector' : framework.selectors[i], 'name' : name, 'row' : row, 'cell' : row.cells[cellIndex++] }); } } }); var timeoutId; var testRunner = function (){ var test = tests.shift(); //取得测试单元 if (!test || !test.window.test) return ; //如果不存在选择器函数返回 var results = test.window.test(test.selector); test.cell.className = 'test' ; test.cell.innerHTML = results.time + ' ms | ' + results.found + ' found' ; //花了多少时间与发现了多少个节点 test.cell.speed = results.time; if (results.error){ test.cell.innerHTML = results.time + ' ms | <span class="exception" title="' + results.error + '">error returned</a>' ; test.cell.className += ' exception' ; test.cell.found = 0; test.cell.error = true ; } else { test.cell.found = results.found; test.cell.error = false ; } scoreNum[test.name] += test.cell.speed; scoreTds[test.name].innerHTML = ' ' + scoreNum[test.name] + ' ' ; if (test.cell == test.row.lastChild) colourRow(test.row); timeoutId = setTimeout(testRunner, 300); }; //为Tbody的行着色 var colourRow = function (row){ var cells = row.cells var speeds = []; //用于存在速度 dom.each(cells, function (cell,i){ speeds[i] = cell.error ? 9999999999 : ~~cell.speed; }); var min = Math.min.apply({}, speeds); var max = Math.max.apply({}, speeds); var consistency = true ; var found = []; dom.each(cells, function (cell, i){ if (!cell.error && "found" in cell ){ found.push(cell.found); var length = found.length; if (length > 2 && found[length-2] !== found[1-1] ){ return (consistency = false ); } } if (cell.speed == min) cell.className += ' good' ; else if (cell.speed == max) cell.className += ' bad' ; else cell.className += ' normal' ; }); if (!consistency){ //如果各个框架取得的结果不一致,则全部 dom.each(cells, function (cell){ if (cell.found != undefined) cell.className += ' mismatch' ; }); } }; dom.addEvent(startTest, "click" ,testRunner); dom.addEvent(stopTest, "click" , function (){ clearTimeout(timeoutId); timeoutId = null ; }); } }).call( this ); |
index.html
QuerySpeed~选择器测试速工具 QuerySpeed 正在准备中……………… 终止测试 开始测试 QuerySpeed为著名的选择器测速工具SlickSpeed的javascript版本。 测试页面为 此页面的拷贝。 <& var time= new Date - 0,file,fun,src,framework; for(var k in @frameworks){ framework = @frameworks[k]; if (framework.disable) continue; file = framework.file; fun = framework.fun; src='template.html?include='+file+'&function='+fun+'&nocache='+time; &> < iframe name='<&= k &>' src='<&= src &>'></ iframe > <& } &> < table > < thead id="thead"> < tr > < th class="selectors-title">selectors</ th > <& for(var k in @frameworks) &> <& if (!@frameworks[k].disable){ &> < th class='framework'><&= k &></ th > <& } &> </ tr > </ thead > < tbody id="tbody"> <& for(var i=0, selector ; selector = @selectors[i++];){&> < tr > < th class='selector'><&= selector &></ th > <& for(var k in @frameworks) &> <& if (!@frameworks[k].disable){ &> < td class='empty'></ td > <& } &> </ tr > <& } &> </ tbody > < tfoot id="tfoot"> < tr > < th class="score-title">< strong >final time (less is better)</ strong ></ th > <& for(var k in @frameworks) &> <& if (!@frameworks[k].disable){ &> < td class='score'>0</ td > <& } &> </ tr > </ tfoot > </ table > 注释 快 慢 发生异常 结果不一致 Original SlickSpeed: copyright © 2007 http://mootools.net | MIT License | download from googlecode 用法 打开QuerySpeed.js,编辑framework数组,添加或删除你要测试的框架,你也可以用disable属性,禁止它加入测试 编辑selectors数组,添加或删除你要测试的CSS选择器 点击“开始测试”按钮进行测试 |
template.html的javascript部分
var params = document.location.search.slice(1).split( '&' ), i = 0,pair, queryFnStr while ((pair = params[i++])){ if (pair.indexOf( "include" )!==-1){ document.write( '<script type="text/javascript" src="frameworks/' +pair.replace("include= "," ")+'" ></sc'+ 'ript>' ) } if (pair.indexOf( "function" )!==-1){ queryFnStr = pair.replace( "function=" , "" ) } } window.test = function (selector){ try { var start = new Date() - 0 var queryFn = arguments.callee.queryFn; var nodes = queryFn(selector); var time = new Date - start; return { 'time' : time, 'found' : nodes.length}; } catch (err){ return { 'time' : time||1, 'found' : -1, 'error' : err}; } }; ( function (){ try { var queryFn = eval( "window." +queryFnStr); // window.console.log(queryFnStr+"准备好了") queryFn( "body" ) test.queryFn = queryFn; } catch (e){ setTimeout(arguments.callee,64) } })(); window.onload = function (){ window.parent.dom.numberOfIframe++; window.parent.dom.hasReady(); } |
如果您觉得此文有帮助,可以打赏点钱给我支付宝1669866773@qq.com ,或扫描二维码


机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
2010-01-04 rails与jsonp