Warn when a query returns 0 results in timeline

This commit is contained in:
Gaël Métais
2014-11-03 16:00:13 +01:00
parent 5e6a7fc6b6
commit ddb95b2653
7 changed files with 88 additions and 29 deletions
+6 -2
View File
@@ -767,8 +767,8 @@
<div class="details">
<div ng-class="{
'icon-question': !(node.data.type == 'jQuery - bind' && node.data.callDetails.context.length > 5),
'icon-warning': node.data.type == 'jQuery - bind' && node.data.callDetails.context.length > 5
'icon-question': !(node.data.type == 'jQuery - bind' && node.data.callDetails.context.length > 5) && node.data.resultsNumber !== 0,
'icon-warning': node.data.type == 'jQuery - bind' && node.data.callDetails.context.length > 5 || node.data.resultsNumber === 0
}"
ng-click="onNodeDetailsClick(node)"
ng-if="node.data.type != 'jQuery loaded'
@@ -798,6 +798,10 @@
<p ng-if="node.data.callDetails.context.firstElementPath"><b>First one is:</b> {{node.data.callDetails.context.firstElementPath}}</p>
</div>
<p class="advice" ng-if="node.data.resultsNumber === 0">
The query returned 0 results. It looks like unused or dead code!
</p>
<div ng-if="node.data.parsedBacktrace">
<h4>Backtrace</h4>
<div class="table">
+3
View File
@@ -371,6 +371,9 @@ input.textFilter {
color: #f1c40f;
cursor: pointer;
}
.table .details .icon-warning {
cursor: pointer;
}
.detailsOverlay {
position: absolute;
+3
View File
@@ -343,6 +343,9 @@ input.textFilter {
color: #f1c40f;
cursor: pointer;
}
.table .details .icon-warning {
cursor: pointer;
}
.detailsOverlay {
position: absolute;
right: 3em;
+10 -2
View File
@@ -62,7 +62,7 @@ exports.module = function(phantomas) {
// After
if (enabled && callbackAfter) {
callbackAfter.apply(this, arguments);
callbackAfter.call(this, result);
}
}
@@ -115,9 +115,17 @@ exports.module = function(phantomas) {
}
// Save given data in the current context and jump change current context to its parent
function leaveContext() {
function leaveContext(moreData) {
if (depth === 1 || deepAnalysis) {
currentContext.data.time = Date.now() - currentContext.data.timestamp - responseEndTime;
// Merge previous data with moreData (ovewrites if exists)
if (moreData) {
for (var key in moreData) {
currentContext.data[key] = moreData[key];
}
}
var parent = currentContext.parent;
if (parent === null) {
console.error('Error: trying to close root context in ContextTree');
+48 -11
View File
@@ -39,7 +39,12 @@ exports.module = function(phantomas) {
backtrace: phantomas.getBacktrace()
});
}, phantomas.leaveContext);
}, function(result) {
var moreData = {
resultsNumber : result ? 1 : 0
};
phantomas.leaveContext(moreData);
});
// selectors by class name
function selectorClassNameSpyBefore(className) {
@@ -63,8 +68,15 @@ exports.module = function(phantomas) {
});
}
phantomas.spy(Document.prototype, 'getElementsByClassName', selectorClassNameSpyBefore, phantomas.leaveContext);
phantomas.spy(Element.prototype, 'getElementsByClassName', selectorClassNameSpyBefore, phantomas.leaveContext);
function selectorClassNameAfter(result) {
var moreData = {
resultsNumber : (result && result.length > 0) ? result.length : 0
};
phantomas.leaveContext(moreData);
}
phantomas.spy(Document.prototype, 'getElementsByClassName', selectorClassNameSpyBefore, selectorClassNameAfter);
phantomas.spy(Element.prototype, 'getElementsByClassName', selectorClassNameSpyBefore, selectorClassNameAfter);
// selectors by tag name
function selectorTagNameSpyBefore(tagName) {
@@ -88,8 +100,15 @@ exports.module = function(phantomas) {
});
}
phantomas.spy(Document.prototype, 'getElementsByTagName', selectorTagNameSpyBefore, phantomas.leaveContext);
phantomas.spy(Element.prototype, 'getElementsByTagName', selectorTagNameSpyBefore, phantomas.leaveContext);
function selectorTagNameSpyAfter(result) {
var moreData = {
resultsNumber : (result && result.length > 0) ? result.length : 0
};
phantomas.leaveContext(moreData);
}
phantomas.spy(Document.prototype, 'getElementsByTagName', selectorTagNameSpyBefore, selectorTagNameSpyAfter);
phantomas.spy(Element.prototype, 'getElementsByTagName', selectorTagNameSpyBefore, selectorTagNameSpyAfter);
// selector queries
function selectorQuerySpy(selector, context) {
@@ -116,6 +135,13 @@ exports.module = function(phantomas) {
});
}
function selectorQuerySpyAfter(result) {
var moreData = {
resultsNumber : result ? 1 : 0
};
phantomas.leaveContext(moreData);
}
function selectorAllQuerySpyBefore(selector) {
/*jshint validthis: true */
@@ -134,10 +160,17 @@ exports.module = function(phantomas) {
});
}
phantomas.spy(Document.prototype, 'querySelector', selectorQuerySpyBefore, phantomas.leaveContext);
phantomas.spy(Document.prototype, 'querySelectorAll', selectorAllQuerySpyBefore, phantomas.leaveContext);
phantomas.spy(Element.prototype, 'querySelector', selectorQuerySpyBefore, phantomas.leaveContext);
phantomas.spy(Element.prototype, 'querySelectorAll', selectorAllQuerySpyBefore, phantomas.leaveContext);
function selectorAllQuerySpryAfter(result) {
var moreData = {
resultsNumber : (result && result.length > 0) ? result.length : 0
};
phantomas.leaveContext(moreData);
}
phantomas.spy(Document.prototype, 'querySelector', selectorQuerySpyBefore, selectorQuerySpyAfter);
phantomas.spy(Document.prototype, 'querySelectorAll', selectorAllQuerySpyBefore, selectorAllQuerySpryAfter);
phantomas.spy(Element.prototype, 'querySelector', selectorQuerySpyBefore, selectorQuerySpyAfter);
phantomas.spy(Element.prototype, 'querySelectorAll', selectorAllQuerySpyBefore, selectorAllQuerySpryAfter);
// count DOM inserts
@@ -199,8 +232,12 @@ exports.module = function(phantomas) {
});
}
phantomas.spy(Node.prototype, 'appendChild', appendChildSpyBefore, phantomas.leaveContext);
phantomas.spy(Node.prototype, 'insertBefore', insertBeforeSpyBefore, phantomas.leaveContext);
phantomas.spy(Node.prototype, 'appendChild', appendChildSpyBefore, function(result) {
phantomas.leaveContext();
});
phantomas.spy(Node.prototype, 'insertBefore', insertBeforeSpyBefore, function(result) {
phantomas.leaveContext();
});
})(window.__phantomas);
});
});
@@ -35,9 +35,13 @@ exports.module = function(phantomas) {
});
}
phantomas.spy(Element.prototype, 'addEventListener', eventSpyBefore, phantomas.leaveContext);
phantomas.spy(Document.prototype, 'addEventListener', eventSpyBefore, phantomas.leaveContext);
phantomas.spy(window, 'addEventListener', eventSpyBefore, phantomas.leaveContext);
function eventSpyAfter(result) {
phantomas.leaveContext();
}
phantomas.spy(Element.prototype, 'addEventListener', eventSpyBefore, eventSpyAfter);
phantomas.spy(Document.prototype, 'addEventListener', eventSpyBefore, eventSpyAfter);
phantomas.spy(window, 'addEventListener', eventSpyBefore, eventSpyAfter);
})(window.__phantomas);
});
});
+11 -11
View File
@@ -16,7 +16,6 @@ exports.module = function(phantomas) {
phantomas.setMetric('jQueryOnDOMReadyFunctions'); // @desc number of functions bound to onDOMReady event
phantomas.setMetric('jQuerySizzleCalls'); // @desc number of calls to Sizzle (including those that will be resolved using querySelectorAll)
phantomas.setMetric('jQuerySizzleCallsDuplicated'); // @desc number of calls on the same Sizzle request
phantomas.setMetric('jQueryBindOnMultipleElements'); //@desc number of calls to jQuery bind function on 2 or more elements
phantomas.setMetric('jQueryDifferentVersions'); //@desc number of different jQuery versions loaded on the page (not counting iframes)
var jQueryFunctions = [
@@ -176,7 +175,12 @@ exports.module = function(phantomas) {
backtrace: phantomas.getBacktrace()
});
}, phantomas.leaveContext) || phantomas.log('jQuery: can not measure jQuerySizzleCalls (jQuery used on the page is too old)!');
}, function(result) {
var moreData = {
resultsNumber : (result && result.length) ? result.length : 0
};
phantomas.leaveContext(moreData);
}) || phantomas.log('jQuery: can not measure jQuerySizzleCalls (jQuery used on the page is too old)!');
// $().bind - jQuery.bind
@@ -196,14 +200,8 @@ exports.module = function(phantomas) {
backtrace: phantomas.getBacktrace()
});
}, function(eventTypes, func) {
phantomas.leaveContext();
if (this.length > 1) {
phantomas.incrMetric('jQueryBindOnMultipleElements');
phantomas.addOffender('jQueryBindOnMultipleElements', '%s (%s on %d elements)', this.selector, eventTypes, this.length);
}
}, function(result) {
phantomas.leaveContext();
}) || phantomas.log('jQuery: can not measure jQueryBindCalls (jQuery used on the page is too old)!');
@@ -283,7 +281,9 @@ exports.module = function(phantomas) {
backtrace: phantomas.getBacktrace()
});
}, phantomas.leaveContext) || phantomas.log('jQuery: can not track jQuery - ' + capitalizedName + ' (this version of jQuery doesn\'t support it)');
}, function(result) {
phantomas.leaveContext();
}) || phantomas.log('jQuery: can not track jQuery - ' + capitalizedName + ' (this version of jQuery doesn\'t support it)');
});