End of the offender transform functions

This commit is contained in:
Gaël Métais
2015-01-22 14:54:51 +01:00
parent fd2271f6d6
commit 4a8a5829d7
3 changed files with 235 additions and 24 deletions
+207 -24
View File
@@ -510,7 +510,7 @@ var policies = {
return offenders.map(function(offender) {
var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
var parts = /^([^{]*)(?: { ([^ ]+): (.*) }) \/\/ (.*)$/.exec(splittedOffender.offender);
var parts = /^([^{]*)(?: ?{ ?([^ ]+): (.*) ?}) \/\/ (.*)$/.exec(splittedOffender.offender);
if (!parts) {
debug('cssOldPropertyPrefixes offenders transform function error with "%s"', offender);
@@ -535,7 +535,17 @@ var policies = {
"message": "<p>This is one way to remove complexity from a CSS rule. Generally, when \"body\" is specified in a rule it can be removed, because an element is necessarily inside the body.</p>",
"isOkThreshold": 0,
"isBadThreshold": 50,
"isAbnormalThreshold": 200
"isAbnormalThreshold": 200,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
var rule = splittedOffender.offender;
rule = rule.replace(/body/, '<b>body</b>');
return rule + ' @ ' + splittedOffender.line + ':' + splittedOffender.character;
});
}
},
"cssRedundantChildNodesSelectors": {
"tool": "phantomas",
@@ -543,7 +553,27 @@ var policies = {
"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>",
"isOkThreshold": 0,
"isBadThreshold": 50,
"isAbnormalThreshold": 200
"isAbnormalThreshold": 200,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
var rule = splittedOffender.offender;
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');
});
return rule + ' @ ' + splittedOffender.line + ':' + splittedOffender.character;
});
}
},
"requests": {
"tool": "phantomas",
@@ -552,7 +582,17 @@ var policies = {
"isOkThreshold": 15,
"isBadThreshold": 100,
"isAbnormalThreshold": 200,
"takeOffendersFrom": ["htmlCount", "jsCount", "cssCount", "imageCount", "webfontCount", "videoCount", "jsonCount", "jsonCount"]
"takeOffendersFrom": ["htmlCount", "jsCount", "cssCount", "imageCount", "webfontCount", "videoCount", "jsonCount", "jsonCount"],
"offendersTransformFn": function(offenders) {
return offenders
.map(function(offender) {
return offendersHelpers.fileWithSizePattern(offender);
}).sort(function(a, b) {
return b.size - a.size;
}).map(function(fileObj) {
return offendersHelpers.urlToLink(fileObj.file) + ((fileObj.size !== undefined) ? ' (' + fileObj.size + ' kB)' : '');
});
}
},
"htmlCount": {
"tool": "phantomas",
@@ -560,7 +600,13 @@ var policies = {
"message": "<p>The number of HTML pages requests, HTML fragments or iframes.</p>",
"isOkThreshold": 10,
"isBadThreshold": 20,
"isAbnormalThreshold": 30
"isAbnormalThreshold": 30,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
var fileObj = offendersHelpers.fileWithSizePattern(offender);
return offendersHelpers.urlToLink(fileObj.file) + ((fileObj.size !== undefined) ? ' (' + fileObj.size + ' kB)' : '');
});
}
},
"jsCount": {
"tool": "phantomas",
@@ -568,7 +614,13 @@ var policies = {
"message": "<p>Reduce the number of scripts by concatenating them.</p>",
"isOkThreshold": 5,
"isBadThreshold": 15,
"isAbnormalThreshold": 30
"isAbnormalThreshold": 30,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
var fileObj = offendersHelpers.fileWithSizePattern(offender);
return offendersHelpers.urlToLink(fileObj.file) + ((fileObj.size !== undefined) ? ' (' + fileObj.size + ' kB)' : '');
});
}
},
"cssCount": {
"tool": "phantomas",
@@ -576,7 +628,13 @@ var policies = {
"message": "<p>Reduce the number of stylesheets by concatenating them.</p>",
"isOkThreshold": 3,
"isBadThreshold": 10,
"isAbnormalThreshold": 22
"isAbnormalThreshold": 22,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
var fileObj = offendersHelpers.fileWithSizePattern(offender);
return offendersHelpers.urlToLink(fileObj.file) + ((fileObj.size !== undefined) ? ' (' + fileObj.size + ' kB)' : '');
});
}
},
"imageCount": {
"tool": "phantomas",
@@ -584,7 +642,13 @@ var policies = {
"message": "<p>Reduce the number of images by lazyloading them, by spriting them or by creating an icons font.</p>",
"isOkThreshold": 15,
"isBadThreshold": 40,
"isAbnormalThreshold": 70
"isAbnormalThreshold": 70,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
var fileObj = offendersHelpers.fileWithSizePattern(offender);
return offendersHelpers.urlToLink(fileObj.file) + ((fileObj.size !== undefined) ? ' (' + fileObj.size + ' kB)' : '');
});
}
},
"webfontCount": {
"tool": "phantomas",
@@ -592,15 +656,27 @@ var policies = {
"message": "<p>Fonts are loaded on the critical path of the head. Load as many as possible.</p>",
"isOkThreshold": 0,
"isBadThreshold": 3,
"isAbnormalThreshold": 5
"isAbnormalThreshold": 5,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
var fileObj = offendersHelpers.fileWithSizePattern(offender);
return offendersHelpers.urlToLink(fileObj.file) + ((fileObj.size !== undefined) ? ' (' + fileObj.size + ' kB)' : '');
});
}
},
"videoCount": {
"tool": "phantomas",
"label": "Videos count",
"label": "Video count",
"message": "<p>The number of videos loaded.</p>",
"isOkThreshold": 1,
"isBadThreshold": 5,
"isAbnormalThreshold": 15
"isAbnormalThreshold": 15,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
var fileObj = offendersHelpers.fileWithSizePattern(offender);
return offendersHelpers.urlToLink(fileObj.file) + ((fileObj.size !== undefined) ? ' (' + fileObj.size + ' kB)' : '');
});
}
},
"jsonCount": {
"tool": "phantomas",
@@ -608,7 +684,13 @@ var policies = {
"message": "<p>The number of AJAX requests to JSON files or webservices.</p>",
"isOkThreshold": 2,
"isBadThreshold": 10,
"isAbnormalThreshold": 25
"isAbnormalThreshold": 25,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
var fileObj = offendersHelpers.fileWithSizePattern(offender);
return offendersHelpers.urlToLink(fileObj.file) + ((fileObj.size !== undefined) ? ' (' + fileObj.size + ' kB)' : '');
});
}
},
"otherCount": {
"tool": "phantomas",
@@ -616,7 +698,13 @@ var policies = {
"message": "<p>They can be Flash, XML, music or any unknown format.</p>",
"isOkThreshold": 5,
"isBadThreshold": 20,
"isAbnormalThreshold": 40
"isAbnormalThreshold": 40,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
var fileObj = offendersHelpers.fileWithSizePattern(offender);
return offendersHelpers.urlToLink(fileObj.file) + ((fileObj.size !== undefined) ? ' (' + fileObj.size + ' kB)' : '');
});
}
},
"smallJsFiles": {
"tool": "phantomas",
@@ -624,7 +712,13 @@ var policies = {
"message": "<p>Number of JS assets smaller than 2 KB that could probably be inlined or merged.</p>",
"isOkThreshold": 2,
"isBadThreshold": 10,
"isAbnormalThreshold": 16
"isAbnormalThreshold": 16,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
var fileObj = offendersHelpers.fileWithSizePattern(offender);
return offendersHelpers.urlToLink(fileObj.file) + ((fileObj.size !== undefined) ? ' (' + fileObj.size + ' kB)' : '');
});
}
},
"smallCssFiles": {
"tool": "phantomas",
@@ -632,7 +726,13 @@ var policies = {
"message": "<p>Number of CSS assets smaller than 2 KB that could probably be inlined or merged.</p>",
"isOkThreshold": 0,
"isBadThreshold": 8,
"isAbnormalThreshold": 12
"isAbnormalThreshold": 12,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
var fileObj = offendersHelpers.fileWithSizePattern(offender);
return offendersHelpers.urlToLink(fileObj.file) + ((fileObj.size !== undefined) ? ' (' + fileObj.size + ' kB)' : '');
});
}
},
"smallImages": {
"tool": "phantomas",
@@ -640,7 +740,13 @@ var policies = {
"message": "<p>Images smaller than 2 KB that could be base64 encoded or merged into a sprite.</p>",
"isOkThreshold": 2,
"isBadThreshold": 17,
"isAbnormalThreshold": 30
"isAbnormalThreshold": 30,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
var fileObj = offendersHelpers.fileWithSizePattern(offender);
return offendersHelpers.urlToLink(fileObj.file) + ((fileObj.size !== undefined) ? ' (' + fileObj.size + ' kB)' : '');
});
}
},
"notFound": {
"tool": "phantomas",
@@ -648,7 +754,12 @@ var policies = {
"message": "<p>404 errors are never cached, so each time a page ask for it, it hits se server. Even if it is behind a CDN or a reverse-proxy cache.</p>",
"isOkThreshold": 0,
"isBadThreshold": 1,
"isAbnormalThreshold": 1
"isAbnormalThreshold": 1,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
return offendersHelpers.urlToLink(offender);
});
}
},
"closedConnections": {
"tool": "phantomas",
@@ -656,15 +767,25 @@ var policies = {
"message": "<p>This counts the number of requests not keeping the connection alive (specifying \"Connection: close\" in the response headers). It is only counting a request if it is followed by another request on the same domain.</p><p>This is slowing down the next request, because the brower needs to open a new connection to the server, which means a additional round-trip.</p><p>Correct the problem by setting a Keep-Alive header on the guilty server.</p>",
"isOkThreshold": 0,
"isBadThreshold": 8,
"isAbnormalThreshold": 20
"isAbnormalThreshold": 20,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
return offendersHelpers.urlToLink(offender);
});
}
},
"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>",
"isOkThreshold": 0,
"isBadThreshold": 5,
"isAbnormalThreshold": 10
"isBadThreshold": 3,
"isAbnormalThreshold": 10,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
return offendersHelpers.urlToLink(offender);
});
}
},
"cachingDisabled": {
"tool": "phantomas",
@@ -672,7 +793,12 @@ var policies = {
"message": "<p>Counts responses with caching disabled (max-age=0)</p><p>Fix immediatly if on static assets.</p>",
"isOkThreshold": 0,
"isBadThreshold": 12,
"isAbnormalThreshold": 25
"isAbnormalThreshold": 25,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
return offendersHelpers.urlToLink(offender);
});
}
},
"cachingNotSpecified": {
"tool": "phantomas",
@@ -680,7 +806,12 @@ var policies = {
"message": "<p>When no caching is specified, each browser will handle it differently. Most of the time, it will automatically add a cache for you, but a poor one. You'd better handle it yourself.</p>",
"isOkThreshold": 5,
"isBadThreshold": 20,
"isAbnormalThreshold": 40
"isAbnormalThreshold": 40,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
return offendersHelpers.urlToLink(offender);
});
}
},
"cachingTooShort": {
"tool": "phantomas",
@@ -688,7 +819,47 @@ var policies = {
"message": "<p>Responses with too short caching time (less than a week).</p><p>The longer you cache, the better. Add versionning to your static assets, if it's not already done, and set their cache time to one year.</p>",
"isOkThreshold": 5,
"isBadThreshold": 20,
"isAbnormalThreshold": 40
"isAbnormalThreshold": 40,
"offendersTransformFn": function(offenders) {
return offenders
.map(function(offender) {
var parts = /^([^ ]*) cached for (-?\d+(\.\d+)?) s$/.exec(offender);
if (!parts) {
debug('cachingTooShort offenders transform function error with "%s"', offender);
return {
file: offender
};
}
return {
file: parts[1],
ttl: Math.round(parseFloat(parts[2]))
};
}).sort(function(a, b) {
return a.ttl - b.ttl;
}).map(function(obj) {
var duration = obj.ttl;
var unit = 'seconds';
if (duration >= 120) {
duration = Math.round(duration / 60);
unit = 'minutes';
}
if (duration >= 120) {
duration = Math.round(duration / 60);
unit = 'hours';
}
if (duration >= 48) {
duration = Math.round(duration / 24);
unit = 'days';
}
return offendersHelpers.urlToLink(obj.file) + ' cached for <b>' + duration + ' ' + unit + '</b>';
});
}
},
"domains": {
"tool": "phantomas",
@@ -696,7 +867,19 @@ var policies = {
"message": "<p>For each domain met, the browser needs to make a DNS look-up, which is slow. Avoid having to many different domains and the page should render faster.</p><p>By the way, domain sharding is not a good practice anymore.</p>",
"isOkThreshold": 10,
"isBadThreshold": 25,
"isAbnormalThreshold": 50
"isAbnormalThreshold": 50,
"offendersTransformFn": function(offenders) {
return offenders.map(function(offender) {
var parts = /^([^ ]*): (\d+) request\(s\)$/.exec(offender);
if (!parts) {
debug('domains offenders transform function error with "%s"', offender);
return offender;
}
return '<b>' + parts[1] + '</b> (' + parts[2] + ' ' + ((parseInt(parts[2], 10) > 1) ? 'requests' : 'request') + ')';
});
}
}
};
+15
View File
@@ -172,6 +172,21 @@ var OffendersHelpers = function() {
}
};
this.fileWithSizePattern = function(fileWithSize) {
var parts = /^([^ ]*) \((\d+\.\d{2}) kB\)$/.exec(fileWithSize);
if (!parts) {
return {
file: fileWithSize
};
} else {
return {
file: parts[1],
size: parseFloat(parts[2])
};
}
};
};
module.exports = new OffendersHelpers();
+13
View File
@@ -267,4 +267,17 @@ describe('offendersHelpers', function() {
});
describe('fileWithSizePattern', function() {
it('should return an object', function() {
var result = offendersHelpers.fileWithSizePattern('http://img3.pouet.com/2008/portail/js/jq-timer.js (1.72 kB)');
result.should.deep.equal({
file: 'http://img3.pouet.com/2008/portail/js/jq-timer.js',
size: 1.72
});
});
});
});