|
@@ -43,7 +43,7 @@ var policies = {
|
|
|
"message": "<p>IDs of HTML elements must be document-wide unique. This can cause problems with getElementById returning the wrong element.</p>",
|
|
|
"isOkThreshold": 0,
|
|
|
"isBadThreshold": 5,
|
|
|
- "isAbnormalThreshold": 10,
|
|
|
+ "isAbnormalThreshold": 50,
|
|
|
"hasOffenders": true,
|
|
|
"offendersTransformFn": function(offenders) {
|
|
|
return {
|
|
@@ -122,7 +122,7 @@ var policies = {
|
|
|
"message": "<p>Number of 'scroll' event listeners binded to 'window' or 'document'.</p><p>Asking too much work to the browser on scroll hurts the smoothness of the scroll. Merging all your event listeners into an unique listener can help you factorize their code and reduce their footprint on scroll.</p>",
|
|
|
"isOkThreshold": 1,
|
|
|
"isBadThreshold": 7,
|
|
|
- "isAbnormalThreshold": 12,
|
|
|
+ "isAbnormalThreshold": 15,
|
|
|
"hasOffenders": true,
|
|
|
"offendersTransformFn": function(offenders) {
|
|
|
return {
|
|
@@ -190,15 +190,6 @@ var policies = {
|
|
|
};
|
|
|
}
|
|
|
},
|
|
|
- /*"evalCalls": {
|
|
|
- "tool": "phantomas",
|
|
|
- "label": "eval calls",
|
|
|
- "message": "<p>The 'eval' function is slow and is a bad coding practice. Try to get rid of it.</p>",
|
|
|
- "isOkThreshold": 0,
|
|
|
- "isBadThreshold": 10,
|
|
|
- "isAbnormalThreshold": 20,
|
|
|
- "hasOffenders": false
|
|
|
- },*/
|
|
|
"documentWriteCalls": {
|
|
|
"tool": "phantomas",
|
|
|
"label": "document.write calls",
|
|
@@ -256,7 +247,7 @@ var policies = {
|
|
|
"message": "<p>Try to keep your console clean when in production. Debugging is good for development only.</p><p>Writing in the console has a cost, especially when dumping large object variables.</p><p>There is also a problem with Internet Explorer 8, not knowing the console object.</p>",
|
|
|
"isOkThreshold": 0,
|
|
|
"isBadThreshold": 10,
|
|
|
- "isAbnormalThreshold": 25,
|
|
|
+ "isAbnormalThreshold": 50,
|
|
|
"hasOffenders": false
|
|
|
},
|
|
|
"globalVariables": {
|
|
@@ -264,8 +255,8 @@ var policies = {
|
|
|
"label": "Global variables",
|
|
|
"message": "<p>It is a bad practice because they clutter up the global namespace. If two scripts use the same variable name in the global scope, it can cause conflicts and it is generally hard to debug.</p><p>Global variables also take a (very) little bit longer to be accessed than variables in the local scope of a function.</p>",
|
|
|
"isOkThreshold": 30,
|
|
|
- "isBadThreshold": 100,
|
|
|
- "isAbnormalThreshold": 400,
|
|
|
+ "isBadThreshold": 150,
|
|
|
+ "isAbnormalThreshold": 700,
|
|
|
"hasOffenders": true,
|
|
|
"offendersTransformFn": function(offenders) {
|
|
|
return {
|
|
@@ -375,7 +366,7 @@ var policies = {
|
|
|
"message": "<p>Yellow Lab Tools failed to parse a CSS file. I doubt the problem comes from the css parser.</p><p>Maybe a <a href=\"http://jigsaw.w3.org/css-validator\" target=\"_blank\">CSS validator</a> can help you.</p>",
|
|
|
"isOkThreshold": 0,
|
|
|
"isBadThreshold": 1,
|
|
|
- "isAbnormalThreshold": 8,
|
|
|
+ "isAbnormalThreshold": 20,
|
|
|
"hasOffenders": true,
|
|
|
"offendersTransformFn": function(offenders) {
|
|
|
return {
|
|
@@ -852,258 +843,99 @@ var policies = {
|
|
|
};
|
|
|
}
|
|
|
},
|
|
|
- "requests": {
|
|
|
- "tool": "phantomas",
|
|
|
- "label": "Total 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>",
|
|
|
- "isOkThreshold": 15,
|
|
|
- "isBadThreshold": 100,
|
|
|
- "isAbnormalThreshold": 200,
|
|
|
+ "totalWeight": {
|
|
|
+ "tool": "weightChecker",
|
|
|
+ "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>",
|
|
|
+ "isOkThreshold": 716800,
|
|
|
+ "isBadThreshold": 2097152,
|
|
|
+ "isAbnormalThreshold": 3145728,
|
|
|
"hasOffenders": true,
|
|
|
- "takeOffendersFrom": ["htmlCount", "jsCount", "cssCount", "imageCount", "webfontCount", "videoCount", "jsonCount", "jsonCount"],
|
|
|
- "offendersTransformFn": function(offenders) {
|
|
|
- return {
|
|
|
- count: offenders.length,
|
|
|
- list: offenders
|
|
|
- .map(function(offender) {
|
|
|
- return offendersHelpers.fileWithSizePattern(offender);
|
|
|
- }).sort(function(a, b) {
|
|
|
- return b.size - a.size;
|
|
|
- })
|
|
|
- };
|
|
|
- }
|
|
|
+ "unit": 'bytes'
|
|
|
},
|
|
|
- "htmlCount": {
|
|
|
- "tool": "phantomas",
|
|
|
- "label": "Document count",
|
|
|
- "message": "<p>The number of HTML pages requests, HTML fragments or iframes.</p>",
|
|
|
- "isOkThreshold": 10,
|
|
|
- "isBadThreshold": 20,
|
|
|
- "isAbnormalThreshold": 30,
|
|
|
+ "imageOptimization": {
|
|
|
+ "tool": "weightChecker",
|
|
|
+ "label": "Image optimization",
|
|
|
+ "message": "<p>This metric mesures 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\">ImageOption</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, so you might be able to compress even more!</p>",
|
|
|
+ "isOkThreshold": 10240,
|
|
|
+ "isBadThreshold": 122880,
|
|
|
+ "isAbnormalThreshold": 307200,
|
|
|
"hasOffenders": true,
|
|
|
- "offendersTransformFn": function(offenders) {
|
|
|
- return {
|
|
|
- count: offenders.length,
|
|
|
- list: offenders.map(function(offender) {
|
|
|
- return offendersHelpers.fileWithSizePattern(offender);
|
|
|
- })
|
|
|
- };
|
|
|
- }
|
|
|
+ "unit": 'bytes'
|
|
|
},
|
|
|
- "jsCount": {
|
|
|
- "tool": "phantomas",
|
|
|
- "label": "Script count",
|
|
|
- "message": "<p>Reduce the number of scripts by concatenating them.</p>",
|
|
|
- "isOkThreshold": 5,
|
|
|
- "isBadThreshold": 15,
|
|
|
- "isAbnormalThreshold": 30,
|
|
|
+ "gzipCompression": {
|
|
|
+ "tool": "weightChecker",
|
|
|
+ "label": "Gzip compression",
|
|
|
+ "message": "<p>Mesures 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,
|
|
|
+ "isBadThreshold": 81920,
|
|
|
+ "isAbnormalThreshold": 153600,
|
|
|
"hasOffenders": true,
|
|
|
- "offendersTransformFn": function(offenders) {
|
|
|
- return {
|
|
|
- count: offenders.length,
|
|
|
- list: offenders.map(function(offender) {
|
|
|
- return offendersHelpers.fileWithSizePattern(offender);
|
|
|
- })
|
|
|
- };
|
|
|
- }
|
|
|
+ "unit": 'bytes'
|
|
|
},
|
|
|
- "cssCount": {
|
|
|
- "tool": "phantomas",
|
|
|
- "label": "CSS count",
|
|
|
- "message": "<p>Reduce the number of stylesheets by concatenating them.</p>",
|
|
|
- "isOkThreshold": 3,
|
|
|
- "isBadThreshold": 10,
|
|
|
- "isAbnormalThreshold": 22,
|
|
|
+ "fileMinification": {
|
|
|
+ "tool": "weightChecker",
|
|
|
+ "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>",
|
|
|
+ "isOkThreshold": 5125,
|
|
|
+ "isBadThreshold": 61440,
|
|
|
+ "isAbnormalThreshold": 122880,
|
|
|
"hasOffenders": true,
|
|
|
- "offendersTransformFn": function(offenders) {
|
|
|
- return {
|
|
|
- count: offenders.length,
|
|
|
- list: offenders.map(function(offender) {
|
|
|
- return offendersHelpers.fileWithSizePattern(offender);
|
|
|
- })
|
|
|
- };
|
|
|
- }
|
|
|
+ "unit": 'bytes'
|
|
|
},
|
|
|
- "imageCount": {
|
|
|
- "tool": "phantomas",
|
|
|
- "label": "Image count",
|
|
|
- "message": "<p>Reduce the number of images by lazyloading them, by spriting them or by creating an icons font.</p>",
|
|
|
+ "totalRequests": {
|
|
|
+ "tool": "weightChecker",
|
|
|
+ "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>",
|
|
|
"isOkThreshold": 15,
|
|
|
- "isBadThreshold": 40,
|
|
|
- "isAbnormalThreshold": 70,
|
|
|
- "hasOffenders": true,
|
|
|
- "offendersTransformFn": function(offenders) {
|
|
|
- return {
|
|
|
- count: offenders.length,
|
|
|
- list: offenders.map(function(offender) {
|
|
|
- return offendersHelpers.fileWithSizePattern(offender);
|
|
|
- })
|
|
|
- };
|
|
|
- }
|
|
|
- },
|
|
|
- "webfontCount": {
|
|
|
- "tool": "phantomas",
|
|
|
- "label": "Font count",
|
|
|
- "message": "<p>Fonts are loaded on the critical path of the head. Load as few as possible.</p>",
|
|
|
- "isOkThreshold": 1,
|
|
|
- "isBadThreshold": 3,
|
|
|
- "isAbnormalThreshold": 5,
|
|
|
- "hasOffenders": true,
|
|
|
- "offendersTransformFn": function(offenders) {
|
|
|
- return {
|
|
|
- count: offenders.length,
|
|
|
- list: offenders.map(function(offender) {
|
|
|
- return offendersHelpers.fileWithSizePattern(offender);
|
|
|
- })
|
|
|
- };
|
|
|
- }
|
|
|
- },
|
|
|
- "videoCount": {
|
|
|
- "tool": "phantomas",
|
|
|
- "label": "Video count",
|
|
|
- "message": "<p>The number of videos loaded.</p>",
|
|
|
- "isOkThreshold": 1,
|
|
|
- "isBadThreshold": 5,
|
|
|
- "isAbnormalThreshold": 15,
|
|
|
- "hasOffenders": true,
|
|
|
- "offendersTransformFn": function(offenders) {
|
|
|
- return {
|
|
|
- count: offenders.length,
|
|
|
- list: offenders.map(function(offender) {
|
|
|
- return offendersHelpers.fileWithSizePattern(offender);
|
|
|
- })
|
|
|
- };
|
|
|
- }
|
|
|
- },
|
|
|
- "jsonCount": {
|
|
|
- "tool": "phantomas",
|
|
|
- "label": "JSON count",
|
|
|
- "message": "<p>The number of AJAX requests to JSON files or webservices.</p>",
|
|
|
- "isOkThreshold": 2,
|
|
|
- "isBadThreshold": 10,
|
|
|
- "isAbnormalThreshold": 25,
|
|
|
- "hasOffenders": true,
|
|
|
- "offendersTransformFn": function(offenders) {
|
|
|
- return {
|
|
|
- count: offenders.length,
|
|
|
- list: offenders.map(function(offender) {
|
|
|
- return offendersHelpers.fileWithSizePattern(offender);
|
|
|
- })
|
|
|
- };
|
|
|
- }
|
|
|
- },
|
|
|
- "otherCount": {
|
|
|
- "tool": "phantomas",
|
|
|
- "label": "Other types of requests",
|
|
|
- "message": "<p>They can be Flash, XML, music or any unknown format.</p>",
|
|
|
- "isOkThreshold": 5,
|
|
|
- "isBadThreshold": 20,
|
|
|
- "isAbnormalThreshold": 40,
|
|
|
- "hasOffenders": true,
|
|
|
- "offendersTransformFn": function(offenders) {
|
|
|
- return {
|
|
|
- count: offenders.length,
|
|
|
- list: offenders.map(function(offender) {
|
|
|
- return offendersHelpers.fileWithSizePattern(offender);
|
|
|
- })
|
|
|
- };
|
|
|
- }
|
|
|
- },
|
|
|
- "smallJsFiles": {
|
|
|
- "tool": "phantomas",
|
|
|
- "label": "Small JS files",
|
|
|
- "message": "<p>Number of JS assets smaller than 2 KB that could probably be inlined or merged.</p>",
|
|
|
- "isOkThreshold": 2,
|
|
|
- "isBadThreshold": 10,
|
|
|
- "isAbnormalThreshold": 16,
|
|
|
- "hasOffenders": true,
|
|
|
- "offendersTransformFn": function(offenders) {
|
|
|
- return {
|
|
|
- count: offenders.length,
|
|
|
- list: offenders.map(function(offender) {
|
|
|
- return offendersHelpers.fileWithSizePattern(offender);
|
|
|
- })
|
|
|
- };
|
|
|
- }
|
|
|
- },
|
|
|
- "smallCssFiles": {
|
|
|
- "tool": "phantomas",
|
|
|
- "label": "Small CSS files",
|
|
|
- "message": "<p>Number of CSS assets smaller than 2 KB that could probably be inlined or merged.</p>",
|
|
|
- "isOkThreshold": 0,
|
|
|
- "isBadThreshold": 8,
|
|
|
- "isAbnormalThreshold": 12,
|
|
|
- "hasOffenders": true,
|
|
|
- "offendersTransformFn": function(offenders) {
|
|
|
- return {
|
|
|
- count: offenders.length,
|
|
|
- list: offenders.map(function(offender) {
|
|
|
- return offendersHelpers.fileWithSizePattern(offender);
|
|
|
- })
|
|
|
- };
|
|
|
- }
|
|
|
- },
|
|
|
- "smallImages": {
|
|
|
- "tool": "phantomas",
|
|
|
- "label": "Small images",
|
|
|
- "message": "<p>Images smaller than 2 KB that could be base64 encoded or merged into a sprite.</p>",
|
|
|
- "isOkThreshold": 2,
|
|
|
- "isBadThreshold": 17,
|
|
|
- "isAbnormalThreshold": 30,
|
|
|
- "hasOffenders": true,
|
|
|
- "offendersTransformFn": function(offenders) {
|
|
|
- return {
|
|
|
- count: offenders.length,
|
|
|
- list: offenders.map(function(offender) {
|
|
|
- return offendersHelpers.fileWithSizePattern(offender);
|
|
|
- })
|
|
|
- };
|
|
|
- }
|
|
|
- },
|
|
|
- "notFound": {
|
|
|
- "tool": "phantomas",
|
|
|
- "label": "404 not found",
|
|
|
- "message": "<p>404 errors are never cached, so each time a page ask for it, it hits the server. Even if it is behind a CDN or a reverse-proxy cache.</p>",
|
|
|
- "isOkThreshold": 0,
|
|
|
- "isBadThreshold": 1,
|
|
|
- "isAbnormalThreshold": 1,
|
|
|
+ "isBadThreshold": 100,
|
|
|
+ "isAbnormalThreshold": 180,
|
|
|
"hasOffenders": true
|
|
|
},
|
|
|
- "assetsNotGzipped": {
|
|
|
+ "domains": {
|
|
|
"tool": "phantomas",
|
|
|
- "label": "Not gzipped",
|
|
|
- "message": "<p>This is the number of requests that should be compressed with gzip but aren't.</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": 0,
|
|
|
- "isBadThreshold": 12,
|
|
|
- "isAbnormalThreshold": 20,
|
|
|
+ "label": "Different domains",
|
|
|
+ "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,
|
|
|
"hasOffenders": true,
|
|
|
"offendersTransformFn": function(offenders) {
|
|
|
return {
|
|
|
count: offenders.length,
|
|
|
list: offenders.map(function(offender) {
|
|
|
- var parts = /^([^ ]*) \((.+)\)$/.exec(offender);
|
|
|
+ var parts = /^([^ ]*): (\d+) request\(s\)$/.exec(offender);
|
|
|
|
|
|
if (!parts) {
|
|
|
- debug('assetsNotGzipped offenders transform function error with "%s"', offender);
|
|
|
+ debug('domains offenders transform function error with "%s"', offender);
|
|
|
return {
|
|
|
- parseError: offender
|
|
|
+ file: offender
|
|
|
};
|
|
|
}
|
|
|
|
|
|
return {
|
|
|
- file: parts[1],
|
|
|
- type: parts[2]
|
|
|
+ domain: parts[1],
|
|
|
+ requests: parseInt(parts[2])
|
|
|
};
|
|
|
})
|
|
|
};
|
|
|
}
|
|
|
},
|
|
|
+ "notFound": {
|
|
|
+ "tool": "phantomas",
|
|
|
+ "label": "404 not found",
|
|
|
+ "message": "<p>404 errors are never cached, so each time a page ask for it, it hits the server. Even if it is behind a CDN or a reverse-proxy cache.</p>",
|
|
|
+ "isOkThreshold": 0,
|
|
|
+ "isBadThreshold": 1,
|
|
|
+ "isAbnormalThreshold": 1,
|
|
|
+ "hasOffenders": true
|
|
|
+ },
|
|
|
"closedConnections": {
|
|
|
"tool": "phantomas",
|
|
|
"label": "Connections closed",
|
|
|
"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 an additional round-trip.</p><p>Correct the problem by setting a Keep-Alive header on the guilty server.</p>",
|
|
|
"isOkThreshold": 0,
|
|
|
- "isBadThreshold": 8,
|
|
|
+ "isBadThreshold": 7,
|
|
|
"isAbnormalThreshold": 20,
|
|
|
"hasOffenders": true
|
|
|
},
|
|
@@ -1116,6 +948,24 @@ var policies = {
|
|
|
"isAbnormalThreshold": 10,
|
|
|
"hasOffenders": true
|
|
|
},
|
|
|
+ "smallRequests": {
|
|
|
+ "tool": "weightChecker",
|
|
|
+ "label": "Small requests",
|
|
|
+ "message": "<p>List of all requests that are less than 2 KB. Try to merge them with other files.</p>",
|
|
|
+ "isOkThreshold": 4,
|
|
|
+ "isBadThreshold": 30,
|
|
|
+ "isAbnormalThreshold": 50,
|
|
|
+ "hasOffenders": true
|
|
|
+ },
|
|
|
+ "lazyLoadableImagesBelowTheFold": {
|
|
|
+ "tool": "phantomas",
|
|
|
+ "label": "Not lazyloaded images",
|
|
|
+ "message": "<p>This is the number of images displayed below the fold that could be lazy-loaded. This is an excellent way to accelerate the loading time of an heavy page.</p><p>I recommend using <a href=\"https://github.com/vvo/lazyload\" target=\"_blank\">this lazyloader</a>.</p>",
|
|
|
+ "isOkThreshold": 1,
|
|
|
+ "isBadThreshold": 12,
|
|
|
+ "isAbnormalThreshold": 30,
|
|
|
+ "hasOffenders": true
|
|
|
+ },
|
|
|
"cachingDisabled": {
|
|
|
"tool": "phantomas",
|
|
|
"label": "Caching disabled",
|
|
@@ -1192,35 +1042,6 @@ var policies = {
|
|
|
})
|
|
|
};
|
|
|
}
|
|
|
- },
|
|
|
- "domains": {
|
|
|
- "tool": "phantomas",
|
|
|
- "label": "Different domains",
|
|
|
- "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,
|
|
|
- "hasOffenders": true,
|
|
|
- "offendersTransformFn": function(offenders) {
|
|
|
- return {
|
|
|
- count: offenders.length,
|
|
|
- list: offenders.map(function(offender) {
|
|
|
- var parts = /^([^ ]*): (\d+) request\(s\)$/.exec(offender);
|
|
|
-
|
|
|
- if (!parts) {
|
|
|
- debug('domains offenders transform function error with "%s"', offender);
|
|
|
- return {
|
|
|
- file: offender
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- return {
|
|
|
- domain: parts[1],
|
|
|
- requests: parseInt(parts[2])
|
|
|
- };
|
|
|
- })
|
|
|
- };
|
|
|
- }
|
|
|
}
|
|
|
};
|
|
|
|