diff --git a/app/node_views/results.html b/app/node_views/results.html index 9ceef45..646185f 100644 --- a/app/node_views/results.html +++ b/app/node_views/results.html @@ -35,6 +35,24 @@

Summary

+ +
+
+
{{notations.domComplexity}}
+
DOM size
+
+
+
{{notations.domManipulations}}
+
DOM read and write Requests
+
+
+
{{notations.duplicatedDomQueries}}
+
Duplicated DOM queries
+
+
+ + +
Javascript manipulation time: {{totalJSTime}} ms
Javascript onDOMReady time: {{phantomasResults.metrics.domContentLoadedEnd - phantomasResults.metrics.domContentLoaded}} ms
Scripts count: {{phantomasResults.metrics.jsCount}}
@@ -42,6 +60,7 @@
DOM max depth: {{phantomasResults.metrics.DOMelementMaxDepth}}
DOM queries: {{phantomasResults.metrics.DOMqueries}}
DOM inserts: {{phantomasResults.metrics.DOMinserts}}
+
Duplicated DOM queries: {{phantomasResults.metrics.DOMqueriesDuplicated}}
Events bound: {{phantomasResults.metrics.eventsBound}}
document.write() calls: {{phantomasResults.metrics.documentWriteCalls}}
eval calls: {{phantomasResults.metrics.evalCalls}}
@@ -74,6 +93,7 @@
Params
Duration
+
Start time
slowRequestsLimit" class="warningIcon" title="Slower than {{slowRequestsLimit}} ms">
+
{{node.data.timestamp}}

Metrics from Phantomas report

-

Phantomas is a web performance metrics collector. You can it find here.

+

Phantomas is a web performance metrics collector. You can find here the (almost) entire list of metrics from Phantomas.

{{moduleName}}

{{metricName}}: {{phantomasResults.metrics[metricName]}} - {{metric.unit}} + {{metric.unit}}
{{metric.desc}} diff --git a/app/public/scripts/resultsCtrl.js b/app/public/scripts/resultsCtrl.js index f7dcef6..731e4d4 100644 --- a/app/public/scripts/resultsCtrl.js +++ b/app/public/scripts/resultsCtrl.js @@ -6,39 +6,15 @@ app.controller('ResultsCtrl', function ($scope) { $scope.phantomasMetadata = window._phantomas_metadata.metrics; $scope.view = 'summary'; - $scope.slowRequestsOn = false; - $scope.slowRequestsLimit = 5; - if ($scope.phantomasResults.offenders && $scope.phantomasResults.offenders.javascriptExecutionTree) { - + if ($scope.phantomasResults.metrics && $scope.phantomasResults.offenders && $scope.phantomasResults.offenders.javascriptExecutionTree) { + // Get the execution tree from the offenders $scope.javascript = JSON.parse($scope.phantomasResults.offenders.javascriptExecutionTree); - - // Read the main elements of the tree and sum the total time - $scope.totalJSTime = 0; - treeRunner($scope.javascript, function(node) { - if (node.data.time) { - $scope.totalJSTime += node.data.time; - } - - if (node.data.type !== 'main') { - // Don't check the children - return false; - } - }); - } - if ($scope.phantomasResults.metrics && $scope.phantomasResults.offenders) { - - // Get the Phantomas modules from metadata - $scope.metricsModule = {}; - for (var metricName in $scope.phantomasMetadata) { - var metric = $scope.phantomasMetadata[metricName]; - if (!$scope.metricsModule[metric.module]) { - $scope.metricsModule[metric.module] = {}; - } - $scope.metricsModule[metric.module][metricName] = metric; - } + initSummaryView(); + initExecutionView(); + initMetricsView(); } @@ -63,6 +39,96 @@ app.controller('ResultsCtrl', function ($scope) { node.data.showDetails = !isOpen; }; + function initSummaryView() { + + // Read the main elements of the tree and sum the total time + $scope.totalJSTime = 0; + treeRunner($scope.javascript, function(node) { + if (node.data.time) { + $scope.totalJSTime += node.data.time; + } + + if (node.data.type !== 'main') { + // Don't check the children + return false; + } + }); + + $scope.notations = { + domComplexity: 'A', + domManipulations: 'A', + duplicatedDomQueries: 'A' + }; + + var domComplexityScore = $scope.phantomasResults.metrics.DOMelementsCount; + if (domComplexityScore > 500) { + $scope.notations.domComplexity = 'B'; + } + if (domComplexityScore > 1000) { + $scope.notations.domComplexity = 'C'; + } + if (domComplexityScore > 1500) { + $scope.notations.domComplexity = 'D'; + } + if (domComplexityScore > 2000) { + $scope.notations.domComplexity = 'E'; + } + if (domComplexityScore > 3000) { + $scope.notations.domComplexity = 'F'; + } + + var domManipulationsScore = $scope.phantomasResults.metrics.DOMinserts + $scope.phantomasResults.metrics.DOMqueries * 0.5 + $scope.totalJSTime; + if (domManipulationsScore > 50) { + $scope.notations.domManipulations = 'B'; + } + if (domManipulationsScore > 100) { + $scope.notations.domManipulations = 'C'; + } + if (domManipulationsScore > 200) { + $scope.notations.domManipulations = 'D'; + } + if (domManipulationsScore > 500) { + $scope.notations.domManipulations = 'E'; + } + if (domManipulationsScore > 1000) { + $scope.notations.domManipulations = 'F'; + } + + var duplicatedDomQueries = $scope.phantomasResults.metrics.DOMqueriesDuplicated; + if (duplicatedDomQueries > 5) { + $scope.notations.duplicatedDomQueries = 'B'; + } + if (duplicatedDomQueries > 10) { + $scope.notations.duplicatedDomQueries = 'C'; + } + if (duplicatedDomQueries > 20) { + $scope.notations.duplicatedDomQueries = 'D'; + } + if (duplicatedDomQueries > 50) { + $scope.notations.duplicatedDomQueries = 'E'; + } + if (duplicatedDomQueries > 100) { + $scope.notations.duplicatedDomQueries = 'F'; + } + } + + function initExecutionView() { + $scope.slowRequestsOn = false; + $scope.slowRequestsLimit = 5; + } + + function initMetricsView() { + // Get the Phantomas modules from metadata + $scope.metricsModule = {}; + for (var metricName in $scope.phantomasMetadata) { + var metric = $scope.phantomasMetadata[metricName]; + if (!$scope.metricsModule[metric.module]) { + $scope.metricsModule[metric.module] = {}; + } + $scope.metricsModule[metric.module][metricName] = metric; + } + } + function parseBacktrace(str) { if (!str) { return null; diff --git a/app/public/styles/results.css b/app/public/styles/results.css index b1d6e39..53232c8 100644 --- a/app/public/styles/results.css +++ b/app/public/styles/results.css @@ -40,6 +40,56 @@ h4 { text-align: left; } +.notations { + display: table; + width: 25em; + margin: 0 auto; + border-spacing: 0.5em; +} +.notations > div { + display: table-row; +} +.notations > div > div { + display: table-cell; + height: 2.5em; + vertical-align: middle; + font-weight: bold; +} +.notations .A, .notations .B, .notations .C, .notations .D, .notations .E, .notations .F, .notations .NA { + width: 2.5em; + font-size: 2em; + text-align: center; + border-radius: 0.5em; +} +.notations .A { + /* green */ + background: #00DB61; +} +.notations .B { + /* green */ + background: #CAD63D; +} +.notations .C { + /* yellow */ + background: #FFD119; +} +.notations .D { + /* orange */ + background: #FFA319; +} +.notations .E { + /* red */ + background: #FF6600; +} +.notations .F { + /* red */ + background: #FF1919; +} +.notations .NA { + /* Non applicable */ + background: #CCC; +} + .metrics h4 { padding-left: 2em; @@ -155,6 +205,7 @@ input.textFilter { right: 3em; top: -3em; width: 45em; + min-height: 1em; padding: 0 1em 1em; background: #fff; border: 2px solid #f1c40f;