End of the offender transform functions
This commit is contained in:
+207
-24
@@ -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') + ')';
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
@@ -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
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user