From ccbb324270b03386237396c71054bfd80a82ed2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Fri, 19 Jun 2015 23:46:39 +0200 Subject: [PATCH] Replace TotalRequests and SmallRequests rules --- front/src/css/rule.css | 6 + front/src/less/rule.less | 7 + front/src/views/rule.html | 38 ++++++ lib/metadata/policies.js | 163 ++--------------------- lib/metadata/scoreProfileGeneric.json | 2 +- lib/tools/weightChecker/weightChecker.js | 65 ++++++++- test/core/weightCheckerTest.js | 17 +++ 7 files changed, 143 insertions(+), 155 deletions(-) diff --git a/front/src/css/rule.css b/front/src/css/rule.css index ed5794a..ba01a54 100644 --- a/front/src/css/rule.css +++ b/front/src/css/rule.css @@ -236,3 +236,9 @@ border: 1px solid #000; margin-top: 0.5em; } +.smallPreview { + max-height: 1.5em; + max-width: 4em; + border: 1px solid #000; + margin-top: 0.2em; +} diff --git a/front/src/less/rule.less b/front/src/less/rule.less index ce3bd5c..18c6310 100644 --- a/front/src/less/rule.less +++ b/front/src/less/rule.less @@ -259,4 +259,11 @@ border: 1px solid #000; margin-top: 0.5em; } +} + +.smallPreview { + max-height: 1.5em; + max-width: 4em; + border: 1px solid #000; + margin-top: 0.2em; } \ No newline at end of file diff --git a/front/src/views/rule.html b/front/src/views/rule.html index fda2731..553bd73 100644 --- a/front/src/views/rule.html +++ b/front/src/views/rule.html @@ -269,6 +269,44 @@ +
+

Requests by MIME type

+
+

+

Reduce the number of stylesheets by concatenating them.

+

Reduce the number of scripts by concatenating them.

+

Reduce the number of images by lazyloading them or by spriting them.

+

Fonts are generally loaded on the critical path of the head. Load as few as possible.

+

They can be Flash, XML, music or any undetected format.

+
+
+
+
+
+
+
+ +
+
+

+

Try to inline these styles in the head of the HTML or to merge them with other files.

+

Try to inline these scripts in the HTML or merge them with other files.

+

Try to inline these images (with base64 encoding for most image types except SVG that don't need base64 encoding). You can also create sprites.

+
+
+
Preview
+
File
+
Weight (bytes)
+
+
+
+
+
{{request.size}}
+
+
+
+
+

{{rule.value}} offenders

Please open the JS timeline diff --git a/lib/metadata/policies.js b/lib/metadata/policies.js index b80d276..b30d589 100644 --- a/lib/metadata/policies.js +++ b/lib/metadata/policies.js @@ -892,162 +892,23 @@ var policies = { "hasOffenders": true, "unit": 'bytes' }, - "requests": { - "tool": "phantomas", + "totalRequests": { + "tool": "weightChecker", "label": "Total requests number", "message": "

This is one of the most important performance rule. Every request is slowing down the page loading.

There are several technics to reduce their number:

", "isOkThreshold": 15, "isBadThreshold": 100, - "isAbnormalThreshold": 200, - "hasOffenders": true, - "takeOffendersFrom": ["htmlCount", "jsCount", "cssCount", "imageCount", "webfontCount", "videoCount", "jsonCount", "otherCount"], - "offendersTransformFn": function(offenders) { - return { - count: offenders.length, - list: offenders - .map(function(offender) { - return offendersHelpers.fileWithSizePattern(offender); - }).sort(function(a, b) { - return (b.file < a.file) ? 1 : (b.file > a.file) ? -1 : 0; - }) - }; - } + "isAbnormalThreshold": 180, + "hasOffenders": true }, - "htmlCount": { - "tool": "phantomas", - "label": "Document count", - "message": "

The number of HTML pages requests, HTML fragments or iframes.

", - "isOkThreshold": 10, - "isBadThreshold": 20, - "isAbnormalThreshold": 30, - "hasOffenders": true, - "offendersTransformFn": function(offenders) { - return { - count: offenders.length, - list: offenders.map(function(offender) { - return offendersHelpers.fileWithSizePattern(offender); - }) - }; - } - }, - "jsCount": { - "tool": "phantomas", - "label": "Script count", - "message": "

Reduce the number of scripts by concatenating them.

", - "isOkThreshold": 5, - "isBadThreshold": 15, - "isAbnormalThreshold": 30, - "hasOffenders": true, - "offendersTransformFn": function(offenders) { - return { - count: offenders.length, - list: offenders.map(function(offender) { - return offendersHelpers.fileWithSizePattern(offender); - }) - }; - } - }, - "cssCount": { - "tool": "phantomas", - "label": "CSS count", - "message": "

Reduce the number of stylesheets by concatenating them.

", - "isOkThreshold": 3, - "isBadThreshold": 10, - "isAbnormalThreshold": 22, - "hasOffenders": true, - "offendersTransformFn": function(offenders) { - return { - count: offenders.length, - list: offenders.map(function(offender) { - return offendersHelpers.fileWithSizePattern(offender); - }) - }; - } - }, - "imageCount": { - "tool": "phantomas", - "label": "Image count", - "message": "

Reduce the number of images by lazyloading them, by spriting them or by creating an icons font.

", - "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": "

Fonts are loaded on the critical path of the head. Load as few as possible.

", - "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": "

The number of videos loaded.

", - "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": "

The number of AJAX requests to JSON files or webservices.

", - "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": "

They can be Flash, XML, music or any unknown format.

", - "isOkThreshold": 5, - "isBadThreshold": 20, - "isAbnormalThreshold": 40, - "hasOffenders": true, - "offendersTransformFn": function(offenders) { - return { - count: offenders.length, - list: offenders.map(function(offender) { - return offendersHelpers.fileWithSizePattern(offender); - }) - }; - } + "smallRequests": { + "tool": "weightChecker", + "label": "Small requests", + "message": "

List of all requests that are less than 2 KB. Try to merge them with other files.

", + "isOkThreshold": 4, + "isBadThreshold": 30, + "isAbnormalThreshold": 50, + "hasOffenders": true }, "smallJsFiles": { "tool": "phantomas", diff --git a/lib/metadata/scoreProfileGeneric.json b/lib/metadata/scoreProfileGeneric.json index 277b06d..24f29e8 100644 --- a/lib/metadata/scoreProfileGeneric.json +++ b/lib/metadata/scoreProfileGeneric.json @@ -81,7 +81,7 @@ "requests": { "label": "Requests", "policies": { - "requests": 5, + "totalRequests": 5, "domains": 3, "notFound": 3, "multipleRequests": 2, diff --git a/lib/tools/weightChecker/weightChecker.js b/lib/tools/weightChecker/weightChecker.js index 7fb85db..dfc00b3 100644 --- a/lib/tools/weightChecker/weightChecker.js +++ b/lib/tools/weightChecker/weightChecker.js @@ -67,13 +67,17 @@ var WeightChecker = function() { endTime = Date.now(); debug('Redownload took %d ms', endTime - startTime); + var metrics = {}; + var offenders = {}; + + // Count requests + offenders.totalRequests = listRequestsByType(results); + metrics.totalRequests = offenders.totalRequests.total; + // Remove unwanted requests (redirections, about:blank) results = results.filter(function(result) { return (result !== null && result.weightCheck && result.weightCheck.bodySize > 0); }); - - var metrics = {}; - var offenders = {}; // Total weight @@ -92,6 +96,10 @@ var WeightChecker = function() { offenders.gzipCompression = listFilesNotGzipped(results); metrics.gzipCompression = offenders.gzipCompression.totalGain; + // Small requests + offenders.smallRequests = listSmallRequests(results); + metrics.smallRequests = offenders.smallRequests.total; + data.toolsResults.weightChecker = { metrics: metrics, offenders: offenders @@ -249,6 +257,57 @@ var WeightChecker = function() { return results; } + function listRequestsByType(requests) { + var results = { + total: 0, + byType: { + html: [], + css: [], + js: [], + json: [], + image: [], + video: [], + webfont: [], + other: [] + } + }; + + requests.forEach(function(req) { + if (req.url !== 'about:blank') { + var type = req.type || 'other'; + results.byType[type].push(req.url); + results.total ++; + } + }); + + return results; + } + + function listSmallRequests(requests) { + var results = { + total: 0, + byType: { + css: [], + js: [], + image: [] + } + }; + + requests.forEach(function(req) { + if (req.weightCheck.bodySize > 0 && req.weightCheck.bodySize < 2048) { + if (req.isCSS || req.isJS || req.isImage) { + results.byType[req.type].push({ + url: req.url, + size: req.weightCheck.bodySize + }); + results.total ++; + } + } + }); + + return results; + } + function redownloadEntry(entry) { var deferred = Q.defer(); diff --git a/test/core/weightCheckerTest.js b/test/core/weightCheckerTest.js index 9b1bb08..6e68d67 100644 --- a/test/core/weightCheckerTest.js +++ b/test/core/weightCheckerTest.js @@ -136,6 +136,23 @@ describe('weightChecker', function() { data.toolsResults.weightChecker.offenders.fileMinification.totalGain.should.be.above(0); data.toolsResults.weightChecker.offenders.fileMinification.files.length.should.equal(2); + data.toolsResults.weightChecker.metrics.should.have.a.property('totalRequests').that.equals(6); + data.toolsResults.weightChecker.offenders.should.have.a.property('totalRequests'); + data.toolsResults.weightChecker.offenders.totalRequests.byType.html.length.should.equal(1); + data.toolsResults.weightChecker.offenders.totalRequests.byType.js.length.should.equal(2); + data.toolsResults.weightChecker.offenders.totalRequests.byType.css.length.should.equal(1); + data.toolsResults.weightChecker.offenders.totalRequests.byType.image.length.should.equal(2); + data.toolsResults.weightChecker.offenders.totalRequests.byType.json.length.should.equal(0); + data.toolsResults.weightChecker.offenders.totalRequests.byType.webfont.length.should.equal(0); + data.toolsResults.weightChecker.offenders.totalRequests.byType.video.length.should.equal(0); + data.toolsResults.weightChecker.offenders.totalRequests.byType.other.length.should.equal(0); + + data.toolsResults.weightChecker.metrics.should.have.a.property('smallRequests').that.equals(0); + data.toolsResults.weightChecker.offenders.should.have.a.property('smallRequests'); + data.toolsResults.weightChecker.offenders.smallRequests.byType.js.length.should.equal(0); + data.toolsResults.weightChecker.offenders.smallRequests.byType.css.length.should.equal(0); + data.toolsResults.weightChecker.offenders.smallRequests.byType.image.length.should.equal(0); + done(); })