Skip to content

Instantly share code, notes, and snippets.

@vmysla
Created May 16, 2015 01:42
Show Gist options
  • Save vmysla/2052f3846a6b6fbec1cd to your computer and use it in GitHub Desktop.
Save vmysla/2052f3846a6b6fbec1cd to your computer and use it in GitHub Desktop.
jquery selector performance reports
var jqspm={
searchedObjects: {},
currentSelector: '',
finalSelector: '',
_utils: {
makeNewSelector: function(id, selector, finSelector) {
jqspm.currentSelector=selector;
jqspm.finalSelector=finSelector;
jqspm.searchedObjects[id]={
selectors: jqspm.finalSelector,
totalCount: 0,
counts: [],
totalTime: 0,
timings: []
};
}
},
start: function() {
jQuery.fn.initSelectorPerfMonitorOrig=jQuery.fn.init;
jQuery.fn.init=function(selector, context, rootjQuery) {
// Return new Func without logging if no selector or context
if(!selector && !context) return new jQuery.fn.initSelectorPerfMonitorOrig(selector, context, rootjQuery);
var jqspmId=this.jqspmId || selector +'-'+ new Date() +'-'+ Math.random();
rootjQuery.jqspmId=jqspmId;
return new jQuery.fn.initSelectorPerfMonitorOrig(selector, context, rootjQuery);
}
// Save old find func for when we stop monitoring
jQuery.fn.findSelectorPerfMonitorOrig=jQuery.fn.find;
// Add our wrapper func
jQuery.fn.find=function(selector) {
// Log start time and call original jQuery.find
var start=new Date(),
ret=jQuery.fn.findSelectorPerfMonitorOrig.apply(this, arguments),
time=new Date()-start;
if(this.jqspmId) ret.jqspmId=this.jqspmId;
if(!jqspm.searchedObjects[ret.jqspmId]) {
jqspm._utils.makeNewSelector(ret.jqspmId, selector, this.selector);
}
// Log details of this find operation
jqspm.searchedObjects[ret.jqspmId].selectors+= (jqspm.searchedObjects[ret.jqspmId].selectors ? ' => ': '') + selector;
jqspm.searchedObjects[ret.jqspmId].timings.push(time);
jqspm.searchedObjects[ret.jqspmId].totalCount+=ret.length;
jqspm.searchedObjects[ret.jqspmId].counts.push(ret.length);
jqspm.searchedObjects[ret.jqspmId].totalTime+=time;
return ret;
}
},
stop: function() {
// Replace our wrapper funcs with originals, then delete our original copies
jQuery.fn.init=jQuery.fn.initSelectorPerfMonitorOrig;
jQuery.fn.find=jQuery.fn.findSelectorPerfMonitorOrig;
delete(jQuery.fn.initSelectorPerfMonitorOrig);
delete(jQuery.fn.findSelectorPerfMonitorOrig);
},
// Quick func to simply print out results if console.table isn't supported
// Adds this table to bottom of the page, or to selector if you pass it.
printReport: function(selector) {
// Use browser to escape HTML
function escapeString(str) {
var cont=document.createElement('DIV');
cont.appendChild(document.createTextNode(str));
return cont.innerHTML;
}
function stringifyDOMElement(elm) {
var str=elm.tagName;
if(elm.id) str+='#'+ elm.id;
if(elm.className) str+='.'+ elm.className;
return str;
}
if(!selector && window.console && console.table) {
console.table(jqspm.searchedObjects);
return;
}
if(!selector) selector='BODY';
var tableHeadings=['Selectors', 'Total Count', 'Counts', 'Total Time', 'Timings'],
html='<table cellpadding="5" cellspacing="5" border="1"><tr><td>'+ tableHeadings.join('</td><td>') + '</td></tr>',
tmp, item;
for(var pResult in jqspm.searchedObjects) {
item=jqspm.searchedObjects[pResult];
// Skip lines where there is only 1 item, and it's HTML
if(item.htmlSelector && !item.counts.length) continue;
// Expand out Object selectors
if(typeof item.selectors!=='string' && item.selectors.nodeType==1) item.selectors='*'+ stringifyDOMElement(item.selectors) +'*';
//if(typeof item.selectors )
tmp=[escapeString(item.selectors), // Print escaped selector, including HTML
item.totalCount,
item.counts.join(', '),
item.totalTime,
item.timings.join(', ')
];
html+='<tr><td>'+ tmp.join('</td><td>') +'</td></tr>';
}
html+='</table>';
$(selector).append($(html));
}
}
/* Bit of code to handle auto-starting the monitor */
jqspm.start();
console.log('jqspm.stop();jqspm.searchedObjects;jqspm.printReport()');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment