|
@@ -241,6 +241,15 @@ var policies = {
|
|
};
|
|
};
|
|
}
|
|
}
|
|
},
|
|
},
|
|
|
|
+ "synchronousXHR": {
|
|
|
|
+ "tool": "phantomas",
|
|
|
|
+ "label": "Synchronous Ajax requests",
|
|
|
|
+ "message": "<p>Making an XMLHttpRequest with the <i>async</i> option set to <i>false</i> is deprecated due to the negative effect to performances. The browser's main thread needs to stop everything until the response is received.</p>",
|
|
|
|
+ "isOkThreshold": 0,
|
|
|
|
+ "isBadThreshold": 1,
|
|
|
|
+ "isAbnormalThreshold": 1,
|
|
|
|
+ "hasOffenders": true
|
|
|
|
+ },
|
|
"consoleMessages": {
|
|
"consoleMessages": {
|
|
"tool": "phantomas",
|
|
"tool": "phantomas",
|
|
"label": "Console messages",
|
|
"label": "Console messages",
|
|
@@ -267,7 +276,7 @@ var policies = {
|
|
},
|
|
},
|
|
"jQueryVersion": {
|
|
"jQueryVersion": {
|
|
"label": "jQuery version",
|
|
"label": "jQuery version",
|
|
- "message": "<p>Current latest versions of jQuery are 1.12 (with support for old IE versions) and 2.2 (without).</p><p>Each new version of jQuery optimizes performances. Do not keep an old version of jQuery. Updating can sometimes break a few things, but it is generally quite easy to fix them up. So don't hesitate.</p>",
|
|
|
|
|
|
+ "message": "<p>The current latest version of jQuery is 3.0</p><p>Each new version of jQuery optimizes performances. Do not keep an old version of jQuery. Updating can sometimes break a few things, but it is generally quite easy to fix them up. So don't hesitate.</p>",
|
|
"hasOffenders": false,
|
|
"hasOffenders": false,
|
|
"scoreFn": function(data) {
|
|
"scoreFn": function(data) {
|
|
var differentVersions = data.toolsResults.phantomas.metrics.jQueryVersionsLoaded;
|
|
var differentVersions = data.toolsResults.phantomas.metrics.jQueryVersionsLoaded;
|
|
@@ -279,34 +288,31 @@ var policies = {
|
|
var value = data.toolsResults.phantomas.metrics.jQueryVersion;
|
|
var value = data.toolsResults.phantomas.metrics.jQueryVersion;
|
|
var score;
|
|
var score;
|
|
|
|
|
|
- if (value.indexOf('1.12.') === 0 ||
|
|
|
|
- value.indexOf('2.2.') === 0 ||
|
|
|
|
- value.indexOf('1.13.') === 0 ||
|
|
|
|
- value.indexOf('2.3.') === 0 ||
|
|
|
|
- value.indexOf('3.0.') === 0 ||
|
|
|
|
- value.indexOf('3.1.') === 0) {
|
|
|
|
|
|
+ if (value.indexOf('3.0.') === 0 ||
|
|
|
|
+ value.indexOf('3.1.') === 0 ||
|
|
|
|
+ value.indexOf('3.2.') === 0) {
|
|
score = 100;
|
|
score = 100;
|
|
|
|
+ } else if (value.indexOf('1.12.') === 0 ||
|
|
|
|
+ value.indexOf('2.2.') === 0) {
|
|
|
|
+ score = 90;
|
|
} else if (value.indexOf('1.11.') === 0 ||
|
|
} else if (value.indexOf('1.11.') === 0 ||
|
|
value.indexOf('2.1.') === 0) {
|
|
value.indexOf('2.1.') === 0) {
|
|
- score = 90;
|
|
|
|
|
|
+ score = 70;
|
|
} else if (value.indexOf('1.10.') === 0 ||
|
|
} else if (value.indexOf('1.10.') === 0 ||
|
|
value.indexOf('2.0.') === 0) {
|
|
value.indexOf('2.0.') === 0) {
|
|
- score = 70;
|
|
|
|
- } else if (value.indexOf('1.9.') === 0) {
|
|
|
|
score = 50;
|
|
score = 50;
|
|
- } else if (value.indexOf('1.8.') === 0) {
|
|
|
|
|
|
+ } else if (value.indexOf('1.9.') === 0) {
|
|
score = 40;
|
|
score = 40;
|
|
- } else if (value.indexOf('1.7') === 0) {
|
|
|
|
|
|
+ } else if (value.indexOf('1.8.') === 0) {
|
|
score = 30;
|
|
score = 30;
|
|
- } else if (value.indexOf('1.6') === 0) {
|
|
|
|
|
|
+ } else if (value.indexOf('1.7') === 0) {
|
|
score = 20;
|
|
score = 20;
|
|
- } else if (value.indexOf('1.5') === 0) {
|
|
|
|
|
|
+ } else if (value.indexOf('1.6') === 0) {
|
|
score = 10;
|
|
score = 10;
|
|
- } else if (value.indexOf('1.4') === 0) {
|
|
|
|
- score = 0;
|
|
|
|
- } else if (value.indexOf('1.3') === 0) {
|
|
|
|
- score = 0;
|
|
|
|
- } else if (value.indexOf('1.2') === 0) {
|
|
|
|
|
|
+ } else if (value.indexOf('1.5') === 0 ||
|
|
|
|
+ value.indexOf('1.4') === 0 ||
|
|
|
|
+ value.indexOf('1.3') === 0 ||
|
|
|
|
+ value.indexOf('1.2') === 0) {
|
|
score = 0;
|
|
score = 0;
|
|
} else {
|
|
} else {
|
|
debug('Unknown jQuery version "%s"', value);
|
|
debug('Unknown jQuery version "%s"', value);
|
|
@@ -462,40 +468,18 @@ var policies = {
|
|
"cssComplexSelectors": {
|
|
"cssComplexSelectors": {
|
|
"tool": "phantomas",
|
|
"tool": "phantomas",
|
|
"label": "Complex selectors",
|
|
"label": "Complex selectors",
|
|
- "message": "<p>Complex selectors are CSS selectors with 4 or more expressions, like \"#header ul li .foo\".</p><p>They are adding more work for the browser, and this could be avoided by simplifying selectors.</p>",
|
|
|
|
|
|
+ "message": "<p>Complex selectors are CSS selectors with 4 or more expressions, like \"#header ul li .foo\".</p><p>They are adding more work for the browser, and this could be avoided by simplifying selectors. The <a href=\"http://getbem.com\" target=\"_blank\">B.E.M. methodology</a> is an useful way to simplify your CSS.</p>",
|
|
"isOkThreshold": 0,
|
|
"isOkThreshold": 0,
|
|
"isBadThreshold": 600,
|
|
"isBadThreshold": 600,
|
|
"isAbnormalThreshold": 2000,
|
|
"isAbnormalThreshold": 2000,
|
|
"hasOffenders": true,
|
|
"hasOffenders": true,
|
|
"offendersTransformFn": function(offenders) {
|
|
"offendersTransformFn": function(offenders) {
|
|
- return {
|
|
|
|
- count: offenders.length,
|
|
|
|
- list: offenders.map(function(offender) {
|
|
|
|
- var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
- return splittedOffender;
|
|
|
|
- })
|
|
|
|
- };
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- "cssComplexSelectorsByAttribute": {
|
|
|
|
- "tool": "phantomas",
|
|
|
|
- "label": "Complex attributes selector",
|
|
|
|
- "message": "<p>Complex attributes selectors are one of these:<ul><li>.foo[type*=bar] (contains bar)</li><li>.foo[type^=bar] (starts with bar)</li><li>.foo[type|=bar] (starts with bar or bar-)</li><li>.foo[type$=bar] (ends with bar)</li><li>.foo[type~=bar baz] (bar or baz)</li></ul></p><p>Their matching process needs more CPU and it has a cost on performances.</p>",
|
|
|
|
- "isOkThreshold": 0,
|
|
|
|
- "isBadThreshold": 75,
|
|
|
|
- "isAbnormalThreshold": 150,
|
|
|
|
- "hasOffenders": true,
|
|
|
|
- "offendersTransformFn": function(offenders) {
|
|
|
|
- return {
|
|
|
|
- count: offenders.length,
|
|
|
|
- list: offenders.map(function(offender) {
|
|
|
|
- var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
-
|
|
|
|
- splittedOffender.bolded = splittedOffender.css.replace(/(\[[^ ]+[~\|\^\$\*]="[^"]+"\])/g, '<b>$1</b>');
|
|
|
|
|
|
+ var parsedOffenders = offenders.map(function(offender) {
|
|
|
|
+ var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
+ return splittedOffender;
|
|
|
|
+ });
|
|
|
|
|
|
- return splittedOffender;
|
|
|
|
- })
|
|
|
|
- };
|
|
|
|
|
|
+ return offendersHelpers.orderByFile(parsedOffenders);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
"cssColors": {
|
|
"cssColors": {
|
|
@@ -590,10 +574,7 @@ var policies = {
|
|
"isAbnormalThreshold": 1000,
|
|
"isAbnormalThreshold": 1000,
|
|
"hasOffenders": true,
|
|
"hasOffenders": true,
|
|
"offendersTransformFn": function(offenders) {
|
|
"offendersTransformFn": function(offenders) {
|
|
- return {
|
|
|
|
- count: offenders.length,
|
|
|
|
- list: offenders
|
|
|
|
- };
|
|
|
|
|
|
+ return offendersHelpers.orderByFile(offenders);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
"cssImports": {
|
|
"cssImports": {
|
|
@@ -652,29 +633,28 @@ var policies = {
|
|
"isAbnormalThreshold": 120,
|
|
"isAbnormalThreshold": 120,
|
|
"hasOffenders": true,
|
|
"hasOffenders": true,
|
|
"offendersTransformFn": function(offenders) {
|
|
"offendersTransformFn": function(offenders) {
|
|
- return {
|
|
|
|
- count: offenders.length,
|
|
|
|
- list: offenders.map(function(offender) {
|
|
|
|
- var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
|
|
+ var parsedOffenders = offenders.map(function(offender) {
|
|
|
|
+ var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
|
|
- var parts = /^([^{]+) {([^ ]+): (.+)}$/.exec(splittedOffender.css);
|
|
|
|
-
|
|
|
|
- if (!parts) {
|
|
|
|
- debug('cssDuplicatedProperties offenders transform function error with "%s"', offender);
|
|
|
|
- return {
|
|
|
|
- parseError: offender
|
|
|
|
- };
|
|
|
|
- }
|
|
|
|
|
|
+ var parts = /^([^{]+) {([^ ]+): (.+)}$/.exec(splittedOffender.css);
|
|
|
|
|
|
|
|
+ if (!parts) {
|
|
|
|
+ debug('cssDuplicatedProperties offenders transform function error with "%s"', offender);
|
|
return {
|
|
return {
|
|
- property: parts[2],
|
|
|
|
- rule: parts[1],
|
|
|
|
- file: splittedOffender.file,
|
|
|
|
- line: splittedOffender.line,
|
|
|
|
- column: splittedOffender.column
|
|
|
|
|
|
+ parseError: offender
|
|
};
|
|
};
|
|
- })
|
|
|
|
- };
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return {
|
|
|
|
+ property: parts[2],
|
|
|
|
+ rule: parts[1],
|
|
|
|
+ file: splittedOffender.file,
|
|
|
|
+ line: splittedOffender.line,
|
|
|
|
+ column: splittedOffender.column
|
|
|
|
+ };
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ return offendersHelpers.orderByFile(parsedOffenders);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
"cssEmptyRules": {
|
|
"cssEmptyRules": {
|
|
@@ -686,14 +666,8 @@ var policies = {
|
|
"isAbnormalThreshold": 100,
|
|
"isAbnormalThreshold": 100,
|
|
"hasOffenders": true,
|
|
"hasOffenders": true,
|
|
"offendersTransformFn": function(offenders) {
|
|
"offendersTransformFn": function(offenders) {
|
|
- return {
|
|
|
|
- count: offenders.length,
|
|
|
|
- list: offenders.map(function(offender) {
|
|
|
|
- var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
-
|
|
|
|
- return splittedOffender;
|
|
|
|
- })
|
|
|
|
- };
|
|
|
|
|
|
+ var parsedOffenders = offenders.map(offendersHelpers.cssOffenderPattern);
|
|
|
|
+ return offendersHelpers.orderByFile(parsedOffenders);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
"cssExpressions": {
|
|
"cssExpressions": {
|
|
@@ -705,30 +679,29 @@ var policies = {
|
|
"isAbnormalThreshold": 20,
|
|
"isAbnormalThreshold": 20,
|
|
"hasOffenders": true,
|
|
"hasOffenders": true,
|
|
"offendersTransformFn": function(offenders) {
|
|
"offendersTransformFn": function(offenders) {
|
|
- return {
|
|
|
|
- count: offenders.length,
|
|
|
|
- list: offenders.map(function(offender) {
|
|
|
|
- var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
|
|
+ var parsedOffenders = offenders.map(function(offender) {
|
|
|
|
+ var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
|
|
- var parts = /^(.*) {([^ ]+): expression\((.*)\)}$/.exec(splittedOffender.css);
|
|
|
|
-
|
|
|
|
- if (!parts) {
|
|
|
|
- debug('cssExpressions offenders transform function error with "%s"', offender);
|
|
|
|
- return {
|
|
|
|
- parseError: offender
|
|
|
|
- };
|
|
|
|
- }
|
|
|
|
|
|
+ var parts = /^(.*) {([^ ]+): expression\((.*)\)}$/.exec(splittedOffender.css);
|
|
|
|
|
|
|
|
+ if (!parts) {
|
|
|
|
+ debug('cssExpressions offenders transform function error with "%s"', offender);
|
|
return {
|
|
return {
|
|
- rule: parts[1],
|
|
|
|
- property: parts[2],
|
|
|
|
- expression: parts[3],
|
|
|
|
- file: splittedOffender.file,
|
|
|
|
- line: splittedOffender.line,
|
|
|
|
- column: splittedOffender.column
|
|
|
|
|
|
+ parseError: offender
|
|
};
|
|
};
|
|
- })
|
|
|
|
- };
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return {
|
|
|
|
+ rule: parts[1],
|
|
|
|
+ property: parts[2],
|
|
|
|
+ expression: parts[3],
|
|
|
|
+ file: splittedOffender.file,
|
|
|
|
+ line: splittedOffender.line,
|
|
|
|
+ column: splittedOffender.column
|
|
|
|
+ };
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ return offendersHelpers.orderByFile(parsedOffenders);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
"cssImportants": {
|
|
"cssImportants": {
|
|
@@ -740,30 +713,29 @@ var policies = {
|
|
"isAbnormalThreshold": 200,
|
|
"isAbnormalThreshold": 200,
|
|
"hasOffenders": true,
|
|
"hasOffenders": true,
|
|
"offendersTransformFn": function(offenders) {
|
|
"offendersTransformFn": function(offenders) {
|
|
- return {
|
|
|
|
- count: offenders.length,
|
|
|
|
- list: offenders.map(function(offender) {
|
|
|
|
- var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
-
|
|
|
|
- var parts = /^(.*) {([^ ]+): (.*) ?\!important}$/.exec(splittedOffender.css);
|
|
|
|
|
|
+ var parsedOffenders = offenders.map(function(offender) {
|
|
|
|
+ var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
|
|
- if (!parts) {
|
|
|
|
- debug('cssImportants offenders transform function error with "%s"', offender);
|
|
|
|
- return {
|
|
|
|
- parseError: offender
|
|
|
|
- };
|
|
|
|
- }
|
|
|
|
|
|
+ var parts = /^(.*) {([^ ]+): (.*) ?\!important}$/.exec(splittedOffender.css);
|
|
|
|
|
|
|
|
+ if (!parts) {
|
|
|
|
+ debug('cssImportants offenders transform function error with "%s"', offender);
|
|
return {
|
|
return {
|
|
- rule: parts[1],
|
|
|
|
- property: parts[2],
|
|
|
|
- value: parts[3],
|
|
|
|
- file: splittedOffender.file,
|
|
|
|
- line: splittedOffender.line,
|
|
|
|
- column: splittedOffender.column
|
|
|
|
|
|
+ parseError: offender
|
|
};
|
|
};
|
|
- })
|
|
|
|
- };
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return {
|
|
|
|
+ rule: parts[1],
|
|
|
|
+ property: parts[2],
|
|
|
|
+ value: parts[3],
|
|
|
|
+ file: splittedOffender.file,
|
|
|
|
+ line: splittedOffender.line,
|
|
|
|
+ column: splittedOffender.column
|
|
|
|
+ };
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ return offendersHelpers.orderByFile(parsedOffenders);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
"cssOldIEFixes": {
|
|
"cssOldIEFixes": {
|
|
@@ -775,52 +747,51 @@ var policies = {
|
|
"isAbnormalThreshold": 300,
|
|
"isAbnormalThreshold": 300,
|
|
"hasOffenders": true,
|
|
"hasOffenders": true,
|
|
"offendersTransformFn": function(offenders) {
|
|
"offendersTransformFn": function(offenders) {
|
|
- return {
|
|
|
|
- count: offenders.length,
|
|
|
|
- list: offenders.map(function(offender) {
|
|
|
|
- var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
|
|
+ var parsedOffenders = offenders.map(function(offender) {
|
|
|
|
+ var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
|
|
- var parts = /^([^{]*)( {([^ ]+): (.*)})?$/.exec(splittedOffender.css);
|
|
|
|
|
|
+ var parts = /^([^{]*)( {([^ ]+): (.*)})?$/.exec(splittedOffender.css);
|
|
|
|
|
|
- if (!parts) {
|
|
|
|
- debug('cssOldIEFixes offenders transform function error with "%s"', offender);
|
|
|
|
- return {
|
|
|
|
- parseError: offender
|
|
|
|
- };
|
|
|
|
- }
|
|
|
|
|
|
+ if (!parts) {
|
|
|
|
+ debug('cssOldIEFixes offenders transform function error with "%s"', offender);
|
|
|
|
+ return {
|
|
|
|
+ parseError: offender
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
|
|
- var rule = parts[1];
|
|
|
|
- var property = parts[3];
|
|
|
|
- var value = parts[4];
|
|
|
|
- var browser = null;
|
|
|
|
-
|
|
|
|
- if (rule.indexOf('* html') === 0) {
|
|
|
|
- rule = rule.replace(/^\* html/, '<b>* html</b>');
|
|
|
|
- browser = 'IE6';
|
|
|
|
- } else if (rule.indexOf('html>body') === 0) {
|
|
|
|
- rule = rule.replace(/^html>body/, '<b>html>body</b>');
|
|
|
|
- browser = 'IE6';
|
|
|
|
- } else if (property.indexOf('*') === 0) {
|
|
|
|
- property = '<b>' + property + '</b>';
|
|
|
|
- browser = 'IE7';
|
|
|
|
- } else if (value.match(/\!ie$/)) {
|
|
|
|
- value = value.replace(/\!ie$/, '<b>!ie</b>');
|
|
|
|
- browser = 'IE7';
|
|
|
|
- } else if (property === '-ms-filter') {
|
|
|
|
- property = '<b>-ms-filter</b>';
|
|
|
|
- browser = 'IE9';
|
|
|
|
- } else if (value.indexOf('progid:DXImageTransform.Microsoft') >= 0) {
|
|
|
|
- value = value.replace(/progid:DXImageTransform\.Microsoft/, '<b>progid:DXImageTransform.Microsoft</b>');
|
|
|
|
- browser = 'IE9';
|
|
|
|
- }
|
|
|
|
|
|
+ var rule = parts[1];
|
|
|
|
+ var property = parts[3];
|
|
|
|
+ var value = parts[4];
|
|
|
|
+ var browser = null;
|
|
|
|
+
|
|
|
|
+ if (rule.indexOf('* html') === 0) {
|
|
|
|
+ rule = rule.replace(/^\* html/, '<b>* html</b>');
|
|
|
|
+ browser = 'IE6';
|
|
|
|
+ } else if (rule.indexOf('html>body') === 0) {
|
|
|
|
+ rule = rule.replace(/^html>body/, '<b>html>body</b>');
|
|
|
|
+ browser = 'IE6';
|
|
|
|
+ } else if (property.indexOf('*') === 0) {
|
|
|
|
+ property = '<b>' + property + '</b>';
|
|
|
|
+ browser = 'IE7';
|
|
|
|
+ } else if (value.match(/\!ie$/)) {
|
|
|
|
+ value = value.replace(/\!ie$/, '<b>!ie</b>');
|
|
|
|
+ browser = 'IE7';
|
|
|
|
+ } else if (property === '-ms-filter') {
|
|
|
|
+ property = '<b>-ms-filter</b>';
|
|
|
|
+ browser = 'IE9';
|
|
|
|
+ } else if (value.indexOf('progid:DXImageTransform.Microsoft') >= 0) {
|
|
|
|
+ value = value.replace(/progid:DXImageTransform\.Microsoft/, '<b>progid:DXImageTransform.Microsoft</b>');
|
|
|
|
+ browser = 'IE9';
|
|
|
|
+ }
|
|
|
|
|
|
- var propertyAndValue = (property && value) ? ' {' + property + ': ' + value + '}' : '';
|
|
|
|
- splittedOffender.bolded = rule + propertyAndValue;
|
|
|
|
- splittedOffender.browser = browser;
|
|
|
|
|
|
+ var propertyAndValue = (property && value) ? ' {' + property + ': ' + value + '}' : '';
|
|
|
|
+ splittedOffender.bolded = rule + propertyAndValue;
|
|
|
|
+ splittedOffender.browser = browser;
|
|
|
|
|
|
- return splittedOffender;
|
|
|
|
- })
|
|
|
|
- };
|
|
|
|
|
|
+ return splittedOffender;
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ return offendersHelpers.orderByFile(parsedOffenders);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
"cssOldPropertyPrefixes": {
|
|
"cssOldPropertyPrefixes": {
|
|
@@ -876,24 +847,6 @@ var policies = {
|
|
};
|
|
};
|
|
}
|
|
}
|
|
},
|
|
},
|
|
- "cssUniversalSelectors": {
|
|
|
|
- "tool": "phantomas",
|
|
|
|
- "label": "Universal selectors",
|
|
|
|
- "message": "<p>Universal selectors are the most expensive CSS selectors.</p><p>More informations <a href=\"http://perfectionkills.com/profiling-css-for-fun-and-profit-optimization-notes/\" target=\"_blank\">here</a>.</p>",
|
|
|
|
- "isOkThreshold": 0,
|
|
|
|
- "isBadThreshold": 50,
|
|
|
|
- "isAbnormalThreshold": 150,
|
|
|
|
- "hasOffenders": true,
|
|
|
|
- "offendersTransformFn": function(offenders) {
|
|
|
|
- return {
|
|
|
|
- count: offenders.length,
|
|
|
|
- list: offenders.map(function(offender) {
|
|
|
|
- var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
- return splittedOffender;
|
|
|
|
- })
|
|
|
|
- };
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
"cssRedundantBodySelectors": {
|
|
"cssRedundantBodySelectors": {
|
|
"tool": "phantomas",
|
|
"tool": "phantomas",
|
|
"label": "Redundant body selectors",
|
|
"label": "Redundant body selectors",
|
|
@@ -903,54 +856,50 @@ var policies = {
|
|
"isAbnormalThreshold": 200,
|
|
"isAbnormalThreshold": 200,
|
|
"hasOffenders": true,
|
|
"hasOffenders": true,
|
|
"offendersTransformFn": function(offenders) {
|
|
"offendersTransformFn": function(offenders) {
|
|
- return {
|
|
|
|
- count: offenders.length,
|
|
|
|
- list: offenders.map(function(offender) {
|
|
|
|
- var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
-
|
|
|
|
- splittedOffender.bolded = splittedOffender.css.replace(/body/, '<b>body</b>');
|
|
|
|
|
|
+ var parsedOffenders = offenders.map(function(offender) {
|
|
|
|
+ var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
+ splittedOffender.bolded = splittedOffender.css.replace(/body/, '<b>body</b>');
|
|
|
|
+ return splittedOffender;
|
|
|
|
+ });
|
|
|
|
|
|
- return splittedOffender;
|
|
|
|
- })
|
|
|
|
- };
|
|
|
|
|
|
+ return offendersHelpers.orderByFile(parsedOffenders);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
"cssRedundantChildNodesSelectors": {
|
|
"cssRedundantChildNodesSelectors": {
|
|
"tool": "phantomas",
|
|
"tool": "phantomas",
|
|
"label": "Redundant tags selectors",
|
|
"label": "Redundant tags selectors",
|
|
- "message": "<p>Some tags included inside other tags are obvious. For example, when \"ul li\" is specified in a rule, \"ul\" can be removed because the \"li\" element is <b>always</b> inside a \"ul\". Same thing for \"tr td\", \"select option\", ...</p><p>Lowering compexity in CSS selectors can make the page load a little faster.</p>",
|
|
|
|
|
|
+ "message": "<p>Some tags included inside other tags are obvious. For example, when \"ul li\" is specified in a rule, \"ul\" can be removed because the \"li\" tag is nearly always inside an \"ul\" container (the \"ol\" container is quite rare). Same thing for \"tr td\", \"select option\", ...</p><p>Lowering compexity in CSS selectors can make the page load a little faster.</p>",
|
|
"isOkThreshold": 0,
|
|
"isOkThreshold": 0,
|
|
"isBadThreshold": 60,
|
|
"isBadThreshold": 60,
|
|
"isAbnormalThreshold": 200,
|
|
"isAbnormalThreshold": 200,
|
|
"hasOffenders": true,
|
|
"hasOffenders": true,
|
|
"offendersTransformFn": function(offenders) {
|
|
"offendersTransformFn": function(offenders) {
|
|
- return {
|
|
|
|
- count: offenders.length,
|
|
|
|
- list: offenders.map(function(offender) {
|
|
|
|
- var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
|
|
+ var parsedOffenders = offenders.map(function(offender) {
|
|
|
|
+ var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
|
|
|
- var rule = splittedOffender.css || '';
|
|
|
|
- var redundanters = [
|
|
|
|
- ['ul', 'li'],
|
|
|
|
- ['ol', 'li'],
|
|
|
|
- ['select', 'option'],
|
|
|
|
- ['table', 'tr'],
|
|
|
|
- ['table', 'th'],
|
|
|
|
- ];
|
|
|
|
|
|
+ var rule = splittedOffender.css || '';
|
|
|
|
+ var redundanters = [
|
|
|
|
+ ['ul', 'li'],
|
|
|
|
+ ['ol', 'li'],
|
|
|
|
+ ['select', 'option'],
|
|
|
|
+ ['table', 'tr'],
|
|
|
|
+ ['table', 'th'],
|
|
|
|
+ ];
|
|
|
|
+
|
|
|
|
+ redundanters.forEach(function(couple) {
|
|
|
|
+ rule = rule.replace(new RegExp('(^| |>)' + couple[0] + '([^ >]*)?([ >]| > )' + couple[1] + '([^\\w-]|$)', 'g'), '$1<b>' + couple[0] + '</b>$2$3<b>' + couple[1] + '</b>$4');
|
|
|
|
+ });
|
|
|
|
|
|
- redundanters.forEach(function(couple) {
|
|
|
|
- rule = rule.replace(new RegExp('(^| |>)' + couple[0] + '([^ >]*)?([ >]| > )' + couple[1] + '([^\\w-]|$)', 'g'), '$1<b>' + couple[0] + '</b>$2$3<b>' + couple[1] + '</b>$4');
|
|
|
|
- });
|
|
|
|
|
|
+ splittedOffender.bolded = rule;
|
|
|
|
|
|
- splittedOffender.bolded = rule;
|
|
|
|
|
|
+ return splittedOffender;
|
|
|
|
+ });
|
|
|
|
|
|
- return splittedOffender;
|
|
|
|
- })
|
|
|
|
- };
|
|
|
|
|
|
+ return offendersHelpers.orderByFile(parsedOffenders);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
"totalWeight": {
|
|
"totalWeight": {
|
|
- "tool": "weightChecker",
|
|
|
|
|
|
+ "tool": "redownload",
|
|
"label": "Total weight",
|
|
"label": "Total weight",
|
|
"message": "<p>The weight is of course very important if you want the page to load fast. Try to stay under 1MB, which is alreay very long to download over a slow connection.</p><p>Please note that Yellow Lab Tools' engine (PhantomJS) is not compatible with image srcset (unless you use a polyfill). This can lead to incorrect page weight.</p>",
|
|
"message": "<p>The weight is of course very important if you want the page to load fast. Try to stay under 1MB, which is alreay very long to download over a slow connection.</p><p>Please note that Yellow Lab Tools' engine (PhantomJS) is not compatible with image srcset (unless you use a polyfill). This can lead to incorrect page weight.</p>",
|
|
"isOkThreshold": 716800,
|
|
"isOkThreshold": 716800,
|
|
@@ -960,7 +909,7 @@ var policies = {
|
|
"unit": 'bytes'
|
|
"unit": 'bytes'
|
|
},
|
|
},
|
|
"imageOptimization": {
|
|
"imageOptimization": {
|
|
- "tool": "weightChecker",
|
|
|
|
|
|
+ "tool": "redownload",
|
|
"label": "Image optimization",
|
|
"label": "Image optimization",
|
|
"message": "<p>This metric measures the number of bytes that could be saved by optimizing images.</p><p>Image optimization is generally one of the easiest way to reduce a page weight, and as a result, the page load time. Don't use Photoshop or other image editing tools, they're not very good for optimization. Use specialized tools such as <a href=\"https://kraken.io/\" target=\"_blank\">Kraken.io</a> or the excellent <a href=\"https://imageoptim.com/\" target=\"_blank\">ImageOptim</a> on Mac. For SVG images, you can use <a href=\"https://jakearchibald.github.io/svgomg/\" target=\"_blank\">SVGOMG</a></p><p>The tools in use in YellowLabTools are not set to their maximum optimization power (JPEG quality 85), so you might be able to compress even more!</p><p>Please note that Yellow Lab Tools' engine (PhantomJS) is not compatible with image srcset (unless you use a polyfill). This can lead to incorrect page weight.</p>",
|
|
"message": "<p>This metric measures the number of bytes that could be saved by optimizing images.</p><p>Image optimization is generally one of the easiest way to reduce a page weight, and as a result, the page load time. Don't use Photoshop or other image editing tools, they're not very good for optimization. Use specialized tools such as <a href=\"https://kraken.io/\" target=\"_blank\">Kraken.io</a> or the excellent <a href=\"https://imageoptim.com/\" target=\"_blank\">ImageOptim</a> on Mac. For SVG images, you can use <a href=\"https://jakearchibald.github.io/svgomg/\" target=\"_blank\">SVGOMG</a></p><p>The tools in use in YellowLabTools are not set to their maximum optimization power (JPEG quality 85), so you might be able to compress even more!</p><p>Please note that Yellow Lab Tools' engine (PhantomJS) is not compatible with image srcset (unless you use a polyfill). This can lead to incorrect page weight.</p>",
|
|
"isOkThreshold": 10240,
|
|
"isOkThreshold": 10240,
|
|
@@ -970,7 +919,7 @@ var policies = {
|
|
"unit": 'bytes'
|
|
"unit": 'bytes'
|
|
},
|
|
},
|
|
"gzipCompression": {
|
|
"gzipCompression": {
|
|
- "tool": "weightChecker",
|
|
|
|
|
|
+ "tool": "redownload",
|
|
"label": "Gzip compression",
|
|
"label": "Gzip compression",
|
|
"message": "<p>Measures the number of bytes that could be saved by compressing file transfers.</p><p>Gzip is a powerfull weight reducer and should be enabled on text-based assets in your server's configuration. Note that gzipping small files (< 1 KB) is arguable, and that some assets such as images should not be gzipped as they are already compressed. <a href=\"https://gist.github.com/gmetais/971ce13a1fbeebd88445\" target=\"_blank\">Here</a> is a list of Content-Types that should be gzipped.</p>",
|
|
"message": "<p>Measures the number of bytes that could be saved by compressing file transfers.</p><p>Gzip is a powerfull weight reducer and should be enabled on text-based assets in your server's configuration. Note that gzipping small files (< 1 KB) is arguable, and that some assets such as images should not be gzipped as they are already compressed. <a href=\"https://gist.github.com/gmetais/971ce13a1fbeebd88445\" target=\"_blank\">Here</a> is a list of Content-Types that should be gzipped.</p>",
|
|
"isOkThreshold": 5125,
|
|
"isOkThreshold": 5125,
|
|
@@ -980,7 +929,7 @@ var policies = {
|
|
"unit": 'bytes'
|
|
"unit": 'bytes'
|
|
},
|
|
},
|
|
"fileMinification": {
|
|
"fileMinification": {
|
|
- "tool": "weightChecker",
|
|
|
|
|
|
+ "tool": "redownload",
|
|
"label": "File minification",
|
|
"label": "File minification",
|
|
"message": "<p>This is the weight that could be saved if all text resources were correctly minified.</p><p>The tools in use here are <b>UglifyJS</b>, <b>clean-css</b> and <b>HTMLMinifier</b>. These tools are so good that some of your minified files can be marked as unminified. Change your tool it this happens :)</p><p>The gains of minification are generally small, but the impact can be high when these text files are loaded on the critical path.</p>",
|
|
"message": "<p>This is the weight that could be saved if all text resources were correctly minified.</p><p>The tools in use here are <b>UglifyJS</b>, <b>clean-css</b> and <b>HTMLMinifier</b>. These tools are so good that some of your minified files can be marked as unminified. Change your tool it this happens :)</p><p>The gains of minification are generally small, but the impact can be high when these text files are loaded on the critical path.</p>",
|
|
"isOkThreshold": 5125,
|
|
"isOkThreshold": 5125,
|
|
@@ -990,7 +939,7 @@ var policies = {
|
|
"unit": 'bytes'
|
|
"unit": 'bytes'
|
|
},
|
|
},
|
|
"totalRequests": {
|
|
"totalRequests": {
|
|
- "tool": "weightChecker",
|
|
|
|
|
|
+ "tool": "redownload",
|
|
"label": "Requests number",
|
|
"label": "Requests number",
|
|
"message": "<p>This is one of the most important performance rule. Every request is slowing down the page loading.</p><p>There are several technics to reduce their number:<ul><li>Concatenate JS files</li><li>Concatenate CSS files</li><li>Embed or inline small JS or CSS files in the HTML</li><li>Create sprites or icon fonts</li><li>Base64 encode small images in HTML or stylesheets</li><li>Use lazyloading for images</li></ul></p>",
|
|
"message": "<p>This is one of the most important performance rule. Every request is slowing down the page loading.</p><p>There are several technics to reduce their number:<ul><li>Concatenate JS files</li><li>Concatenate CSS files</li><li>Embed or inline small JS or CSS files in the HTML</li><li>Create sprites or icon fonts</li><li>Base64 encode small images in HTML or stylesheets</li><li>Use lazyloading for images</li></ul></p>",
|
|
"isOkThreshold": 15,
|
|
"isOkThreshold": 15,
|
|
@@ -1045,17 +994,29 @@ var policies = {
|
|
"isAbnormalThreshold": 20,
|
|
"isAbnormalThreshold": 20,
|
|
"hasOffenders": true
|
|
"hasOffenders": true
|
|
},
|
|
},
|
|
- "multipleRequests": {
|
|
|
|
- "tool": "phantomas",
|
|
|
|
- "label": "Duplicated requests",
|
|
|
|
- "message": "<p>This only happens when the asset has no cache and is requested more than once on the same page. Be very careful about it.</p>",
|
|
|
|
|
|
+ "identicalFiles": {
|
|
|
|
+ "tool": "redownload",
|
|
|
|
+ "label": "Identical content",
|
|
|
|
+ "message": "<p>This is the number of requests that could be avoided, because of downloaded files that have the same content but are loaded from different URLs.</p><p>Try to load them from the same URL.</p>",
|
|
"isOkThreshold": 0,
|
|
"isOkThreshold": 0,
|
|
- "isBadThreshold": 3,
|
|
|
|
- "isAbnormalThreshold": 10,
|
|
|
|
|
|
+ "isBadThreshold": 5,
|
|
|
|
+ "isAbnormalThreshold": 15,
|
|
|
|
+ "hasOffenders": true,
|
|
|
|
+ "offendersTransformFn": function(offenders) {
|
|
|
|
+ return offenders;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ "emptyRequests": {
|
|
|
|
+ "tool": "redownload",
|
|
|
|
+ "label": "Empty requests",
|
|
|
|
+ "message": "<p>List of GET requests that respond with an empty body. These are probably the easiest requests to remove.</p>",
|
|
|
|
+ "isOkThreshold": 0,
|
|
|
|
+ "isBadThreshold": 1,
|
|
|
|
+ "isAbnormalThreshold": 5,
|
|
"hasOffenders": true
|
|
"hasOffenders": true
|
|
},
|
|
},
|
|
"smallRequests": {
|
|
"smallRequests": {
|
|
- "tool": "weightChecker",
|
|
|
|
|
|
+ "tool": "redownload",
|
|
"label": "Small requests",
|
|
"label": "Small requests",
|
|
"message": "<p>List of all requests that are less than 2 KB. Try to merge them with other files.</p>",
|
|
"message": "<p>List of all requests that are less than 2 KB. Try to merge them with other files.</p>",
|
|
"isOkThreshold": 4,
|
|
"isOkThreshold": 4,
|
|
@@ -1075,7 +1036,7 @@ var policies = {
|
|
"hiddenImages": {
|
|
"hiddenImages": {
|
|
"tool": "phantomas",
|
|
"tool": "phantomas",
|
|
"label": "Hidden images",
|
|
"label": "Hidden images",
|
|
- "message": "<p>List of all images that have a display:none property, or one of their parents. These images are loaded by the browser even if they're not visible. You might be able to find a way to lazy-load them, only when they get visible.</p><p>Trackers are an exception, you'd better hide them.</p>",
|
|
|
|
|
|
+ "message": "<p>List of all images that have a display:none property, or one of their parents. These images are loaded by the browser even if they're not visible. You might be able to find a way to lazy-load them, only when they get visible.</p><p>As images displayed in 1x1 pixels tend to be trackers, they are excluded from this rule.</p>",
|
|
"isOkThreshold": 1,
|
|
"isOkThreshold": 1,
|
|
"isBadThreshold": 12,
|
|
"isBadThreshold": 12,
|
|
"isAbnormalThreshold": 30,
|
|
"isAbnormalThreshold": 30,
|