|
@@ -6,18 +6,19 @@ var jsExecutionTransformer = function() {
|
|
|
|
|
|
this.transform = function(data) {
|
|
|
var javascriptExecutionTree = {};
|
|
|
+ var scrollExecutionTree = {};
|
|
|
|
|
|
var metrics = {
|
|
|
- domManipulations: 0,
|
|
|
+ DOMaccesses: 0,
|
|
|
queriesWithoutResults: 0,
|
|
|
jQueryCalls: 0,
|
|
|
- jQueryCallsOnEmptyObject: 0
|
|
|
-
|
|
|
+ jQueryCallsOnEmptyObject: 0,
|
|
|
+ DOMaccessesOnScroll: 0
|
|
|
};
|
|
|
|
|
|
- debug('Starting JS execution transformation');
|
|
|
-
|
|
|
try {
|
|
|
+
|
|
|
+ debug('Starting JS execution transformation');
|
|
|
javascriptExecutionTree = JSON.parse(data.toolsResults.phantomas.offenders.javascriptExecutionTree[0]);
|
|
|
|
|
|
if (javascriptExecutionTree.children) {
|
|
@@ -57,33 +58,46 @@ var jsExecutionTransformer = function() {
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- // Change the list of dom paths into a tree
|
|
|
- treeRecursiveParser(node, function(node) {
|
|
|
-
|
|
|
- if (node.data.callDetails && node.data.callDetails.context && node.data.callDetails.context.length > 0) {
|
|
|
- node.data.callDetails.context.elements = node.data.callDetails.context.elements.map(offendersHelpers.domPathToDomElementObj, offendersHelpers);
|
|
|
- }
|
|
|
-
|
|
|
- if (node.data.type === 'appendChild' || node.data.type === 'insertBefore' || node.data.type === 'getComputedStyle') {
|
|
|
- node.data.callDetails.arguments[0] = offendersHelpers.domPathToDomElementObj(node.data.callDetails.arguments[0]);
|
|
|
- }
|
|
|
-
|
|
|
- if (node.data.type === 'insertBefore') {
|
|
|
- node.data.callDetails.arguments[1] = offendersHelpers.domPathToDomElementObj(node.data.callDetails.arguments[1]);
|
|
|
- }
|
|
|
- });
|
|
|
+ // Transform domPaths into objects
|
|
|
+ changeListOfDomPaths(node);
|
|
|
+
|
|
|
+ // Count the number of DOM accesses, by counting the tree leafs
|
|
|
+ metrics.DOMaccesses += countTreeLeafs(node);
|
|
|
});
|
|
|
}
|
|
|
-
|
|
|
debug('JS execution transformation complete');
|
|
|
|
|
|
+
|
|
|
+ debug('Starting scroll execution transformation');
|
|
|
+ scrollExecutionTree = JSON.parse(data.toolsResults.phantomas.offenders.scrollExecutionTree[0]);
|
|
|
+ if (scrollExecutionTree.children) {
|
|
|
+ scrollExecutionTree.children.forEach(function(node) {
|
|
|
+
|
|
|
+ // Mark a event flag
|
|
|
+ if (['documentScroll', 'windowScroll', 'window.onscroll'].indexOf(node.data.type) >= 0) {
|
|
|
+ node.windowPerformance = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Transform domPaths into objects
|
|
|
+ changeListOfDomPaths(node);
|
|
|
+
|
|
|
+ // Count the number of DOM accesses, by counting the tree leafs
|
|
|
+ metrics.DOMaccessesOnScroll += countTreeLeafs(node);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ debug('Scroll execution transformation complete');
|
|
|
+
|
|
|
} catch(err) {
|
|
|
throw err;
|
|
|
}
|
|
|
|
|
|
data.javascriptExecutionTree = javascriptExecutionTree;
|
|
|
+
|
|
|
data.toolsResults.jsExecutionTransformer = {
|
|
|
- metrics: metrics
|
|
|
+ metrics: metrics,
|
|
|
+ offenders: {
|
|
|
+ DOMaccessesOnScroll: scrollExecutionTree
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
return data;
|
|
@@ -97,6 +111,39 @@ var jsExecutionTransformer = function() {
|
|
|
}
|
|
|
fn(node);
|
|
|
}
|
|
|
+
|
|
|
+ function changeListOfDomPaths(rootNode) {
|
|
|
+ treeRecursiveParser(rootNode, function(node) {
|
|
|
+
|
|
|
+ if (node.data.callDetails && node.data.callDetails.context && node.data.callDetails.context.length > 0) {
|
|
|
+ node.data.callDetails.context.elements = node.data.callDetails.context.elements.map(offendersHelpers.domPathToDomElementObj, offendersHelpers);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (node.data.type === 'appendChild' || node.data.type === 'insertBefore' || node.data.type === 'getComputedStyle') {
|
|
|
+ node.data.callDetails.arguments[0] = offendersHelpers.domPathToDomElementObj(node.data.callDetails.arguments[0]);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (node.data.type === 'insertBefore') {
|
|
|
+ node.data.callDetails.arguments[1] = offendersHelpers.domPathToDomElementObj(node.data.callDetails.arguments[1]);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // Returns the number of leafs (nodes without children)
|
|
|
+ function countTreeLeafs(rootNode) {
|
|
|
+ var count = 0;
|
|
|
+
|
|
|
+ treeRecursiveParser(rootNode, function(node) {
|
|
|
+ if (!node.children &&
|
|
|
+ !node.error &&
|
|
|
+ !node.windowPerformance &&
|
|
|
+ node.data.type !== 'jQuery loaded') {
|
|
|
+ count ++;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ return count;
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
module.exports = new jsExecutionTransformer();
|