New DOMaccess agregated form + new score category JS complexity
This commit is contained in:
@@ -93,6 +93,13 @@
|
||||
};
|
||||
});
|
||||
|
||||
offendersDirectives.filter('lastDOMNode', function() {
|
||||
return function(str) {
|
||||
var splited = str.split(' > ');
|
||||
return splited[splited.length - 1];
|
||||
};
|
||||
});
|
||||
|
||||
function getBacktraceHTML(backtrace) {
|
||||
var html = '';
|
||||
var parsedBacktrace = parseBacktrace(backtrace);
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<p>This rule reached the abnormality threshold, which means there is a real problem you should care about.</p>
|
||||
</div>
|
||||
<div class="offenders" ng-if="rule.policy.hasOffenders">
|
||||
<h3 ng-if="rule.offendersObj.count >= 0"><ng-pluralize count="rule.offendersObj.count" when="{'0': 'No offenders', 'one': '1 offender', 'other': '{} offenders'}"></ng-pluralize></h3>
|
||||
<h3 ng-if="rule.offendersObj.count >= 0"><ng-pluralize count="rule.offendersObj.count" when="{'0': 'No offender', 'one': '1 offender', 'other': '{} offenders'}"></ng-pluralize></h3>
|
||||
|
||||
<div ng-if="rule.offendersObj.list" class="offendersTable">
|
||||
<div ng-repeat="offender in rule.offendersObj.list track by $index">
|
||||
@@ -264,6 +264,36 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="policyName === 'DOMaccesses'">
|
||||
<div ng-repeat="(type, list) in rule.offendersObj.list.byType">
|
||||
<h3>
|
||||
<ng-pluralize count="list.length" when="{'0': 'No offender', 'one': '1 offender', 'other': '{} offenders'}"></ng-pluralize> from
|
||||
<span ng-if="type === 'DOMqueriesById'">getElementById()</span>
|
||||
<span ng-if="type === 'DOMqueriesByTagName'">getElementsByTagName()</span>
|
||||
<span ng-if="type === 'DOMqueriesByClassName'">getElementsByClassName()</span>
|
||||
<span ng-if="type === 'DOMqueriesByQuerySelectorAll'">querySelector() or querySelectorAll()</span>
|
||||
<span ng-if="type === 'DOMinserts'">appendChild() or insertBefore()</span>
|
||||
<span ng-if="type === 'DOMmutationsInserts'">added nodes</span>
|
||||
<span ng-if="type === 'DOMmutationsRemoves'">removed nodes</span>
|
||||
<span ng-if="type === 'DOMmutationsAttributes'">attribute changes</span>
|
||||
<span ng-if="type === 'eventsBound'">addEventListener()</span>
|
||||
</h3>
|
||||
<div class="offendersTable">
|
||||
<div ng-repeat="access in list">
|
||||
<div ng-if="type === 'DOMqueriesById'">#{{access.id}}</div>
|
||||
<div ng-if="type === 'DOMqueriesByTagName'">{{access.tag}} <b>on</b> <span title="{{access.node}}">{{access.node | lastDOMNode}}</span></div>
|
||||
<div ng-if="type === 'DOMqueriesByClassName'">.{{access.class}} <b>on</b> <span title="{{access.node}}">{{access.node | lastDOMNode}}</span></div>
|
||||
<div ng-if="type === 'DOMqueriesByQuerySelectorAll'">{{access.selector}} <b>on</b> <span title="{{access.node}}">{{access.node | lastDOMNode}}</span></div>
|
||||
<div ng-if="type === 'DOMinserts'"><span title="{{access.append}}">{{access.append | lastDOMNode}}</span> <b>added to</b> <span title="{{access.node}}">{{access.node | lastDOMNode}}</span></div>
|
||||
<div ng-if="type === 'DOMmutationsInserts'">{{access.node}} <b>added to</b> {{access.target}}</div>
|
||||
<div ng-if="type === 'DOMmutationsRemoves'">{{access.node}} <b>removed from</b> {{access.target}}</div>
|
||||
<div ng-if="type === 'DOMmutationsAttributes'">{{access.attribute}} <b>changed on</b> {{access.node}}</div>
|
||||
<div ng-if="type === 'eventsBound'">{{access.eventType}} <b>on</b> <span title="{{access.path}}">{{access.path | lastDOMNode}}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="policyName === 'imageOptimization'">
|
||||
<h3 ng-if="rule.value > 0">{{rule.value | bytes}} could be saved on <ng-pluralize count="rule.offendersObj.list.images.length" when="{'one': '1 image', 'other': '{} images'}"></ng-pluralize></h3>
|
||||
<div class="imageOffenders">
|
||||
|
||||
@@ -46,37 +46,14 @@ var policies = {
|
||||
"isAbnormalThreshold": 50,
|
||||
"hasOffenders": true
|
||||
},
|
||||
"DOMqueriesAvoidable": {
|
||||
"tool": "phantomas",
|
||||
"label": "Duplicated DOM queries",
|
||||
"message": "<p>This is the number of queries that could be avoided by removing all duplicated queries.</p><p>Simply save the result of a query in a variable. Ok it is not always simple, especially with third-party scripts, but at least do it with your own code.</p>",
|
||||
"isOkThreshold": 0,
|
||||
"isBadThreshold": 300,
|
||||
"isAbnormalThreshold": 600,
|
||||
"hasOffenders": true,
|
||||
"takeOffendersFrom": "DOMqueriesDuplicated",
|
||||
"offendersTransformFn": function(offenders) {
|
||||
return {
|
||||
count: offenders.length,
|
||||
list: offenders.map(function(offender) {
|
||||
var parts = /^[^"]* ?"(.*)" ?with ?(.*) ?\(in ?context ?(.*)\): ?(.*)\s?queries$/.exec(offender);
|
||||
|
||||
if (!parts) {
|
||||
debug('DOMqueriesAvoidable offenders transform function error with "%s"', offender);
|
||||
return {
|
||||
parseError: offender
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
query: parts[1],
|
||||
context: offendersHelpers.domPathToDomElementObj(parts[3]),
|
||||
fn: parts[2],
|
||||
count: parseInt(parts[4], 10)
|
||||
};
|
||||
})
|
||||
};
|
||||
}
|
||||
"DOMaccesses": {
|
||||
"tool": "domAccessAgregator",
|
||||
"label": "DOM access",
|
||||
"message": "<p>This metric estimates the number of times the JavaScript reads, changes or binds the DOM.</p><p>The more your JavaScript code accesses the DOM, the slower the page will load.</p><p>Try, as much as possible, to have an HTML page fully generated by the server instead of making changes with JS.</p><p>Try to reduce the number of queries by refactoring your JavaScript code.</p><p>Binding too many events also has a cost.</p>",
|
||||
"isOkThreshold": 500,
|
||||
"isBadThreshold": 2500,
|
||||
"isAbnormalThreshold": 5000,
|
||||
"hasOffenders": true
|
||||
},
|
||||
"eventsScrollBound": {
|
||||
"tool": "phantomas",
|
||||
|
||||
@@ -32,8 +32,15 @@
|
||||
"DOMidDuplicated": 1
|
||||
}
|
||||
},
|
||||
"javascriptComplexity": {
|
||||
"label": "JS complexity",
|
||||
"policies": {
|
||||
"DOMaccesses": 4,
|
||||
"eventsScrollBound": 1
|
||||
}
|
||||
},
|
||||
"badJavascript": {
|
||||
"label": "Bad JavaScript",
|
||||
"label": "Bad JS",
|
||||
"policies": {
|
||||
"jsErrors": 1,
|
||||
"documentWriteCalls": 2,
|
||||
@@ -100,6 +107,7 @@
|
||||
"pageWeight": 3,
|
||||
"requests": 3,
|
||||
"domComplexity": 2,
|
||||
"javascriptComplexity": 2,
|
||||
"badJavascript": 2,
|
||||
"jQuery": 1,
|
||||
"cssSyntaxError": 1,
|
||||
|
||||
@@ -3,6 +3,7 @@ var debug = require('debug')('ylt:runner');
|
||||
|
||||
var phantomasWrapper = require('./tools/phantomas/phantomasWrapper');
|
||||
var colorDiff = require('./tools/colorDiff');
|
||||
var domAccessAgregator = require('./tools/domAccessAgregator');
|
||||
var mediaQueriesChecker = require('./tools/mediaQueriesChecker');
|
||||
var isHttp2 = require('./tools/isHttp2');
|
||||
var redownload = require('./tools/redownload/redownload');
|
||||
@@ -27,6 +28,9 @@ var Runner = function(params) {
|
||||
.then(function(phantomasResults) {
|
||||
data.toolsResults.phantomas = phantomasResults;
|
||||
|
||||
// Mix all DOM Access metrics together
|
||||
data = domAccessAgregator.agregate(data);
|
||||
|
||||
// Compare colors
|
||||
data = colorDiff.compareAllColors(data);
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
var debug = require('debug')('ylt:domAccessAgregator');
|
||||
|
||||
var domAccessAgregator = function() {
|
||||
'use strict';
|
||||
|
||||
this.agregate = function(data) {
|
||||
debug('Starting to agregate DOM Accesses...');
|
||||
|
||||
let count = 0;
|
||||
let offenders = {
|
||||
byType: {}
|
||||
};
|
||||
|
||||
const metricsToGather = [
|
||||
'DOMqueriesById',
|
||||
'DOMqueriesByTagName',
|
||||
'DOMqueriesByClassName',
|
||||
'DOMqueriesByQuerySelectorAll',
|
||||
'DOMinserts',
|
||||
'DOMmutationsInserts',
|
||||
'DOMmutationsRemoves',
|
||||
'DOMmutationsAttributes',
|
||||
'eventsBound'
|
||||
];
|
||||
|
||||
metricsToGather.forEach(key => {
|
||||
|
||||
if (data.toolsResults.phantomas.metrics[key]) {
|
||||
count += data.toolsResults.phantomas.metrics[key];
|
||||
}
|
||||
|
||||
offenders.byType[key] = [];
|
||||
if (data.toolsResults.phantomas.offenders[key]) {
|
||||
offenders.byType[key] = data.toolsResults.phantomas.offenders[key];
|
||||
}
|
||||
});
|
||||
|
||||
data.toolsResults.domAccessAgregator = {
|
||||
metrics: {
|
||||
DOMaccesses: count
|
||||
},
|
||||
offenders: {
|
||||
DOMaccesses: offenders
|
||||
}
|
||||
};
|
||||
|
||||
debug('Done agregating DOM Accesses.');
|
||||
|
||||
return data;
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = new domAccessAgregator();
|
||||
Reference in New Issue
Block a user