|
@@ -17,6 +17,7 @@ var md5 = require('md5');
|
|
var imageOptimizer = require('./imageOptimizer');
|
|
var imageOptimizer = require('./imageOptimizer');
|
|
var fileMinifier = require('./fileMinifier');
|
|
var fileMinifier = require('./fileMinifier');
|
|
var gzipCompressor = require('./gzipCompressor');
|
|
var gzipCompressor = require('./gzipCompressor');
|
|
|
|
+var brotliCompressor = require('./brotliCompressor');
|
|
var contentTypeChecker = require('./contentTypeChecker');
|
|
var contentTypeChecker = require('./contentTypeChecker');
|
|
var fontAnalyzer = require('./fontAnalyzer');
|
|
var fontAnalyzer = require('./fontAnalyzer');
|
|
var imageDimensions = require('./imageDimensions');
|
|
var imageDimensions = require('./imageDimensions');
|
|
@@ -80,6 +81,8 @@ var Redownload = function() {
|
|
|
|
|
|
.then(gzipCompressor.compressFile)
|
|
.then(gzipCompressor.compressFile)
|
|
|
|
|
|
|
|
+ .then(brotliCompressor.compressFile)
|
|
|
|
+
|
|
.then(function(entry) {
|
|
.then(function(entry) {
|
|
return fontAnalyzer.analyzeFont(entry, differentCharacters);
|
|
return fontAnalyzer.analyzeFont(entry, differentCharacters);
|
|
})
|
|
})
|
|
@@ -151,9 +154,9 @@ var Redownload = function() {
|
|
offenders.fileMinification = listFilesNotMinified(results);
|
|
offenders.fileMinification = listFilesNotMinified(results);
|
|
metrics.fileMinification = offenders.fileMinification.totalGain;
|
|
metrics.fileMinification = offenders.fileMinification.totalGain;
|
|
|
|
|
|
- // Gzip compression
|
|
|
|
- offenders.gzipCompression = listFilesNotGzipped(results);
|
|
|
|
- metrics.gzipCompression = offenders.gzipCompression.totalGain;
|
|
|
|
|
|
+ // Gzip/Brotli compression
|
|
|
|
+ offenders.compression = listFilesNotBrotlified(results);
|
|
|
|
+ metrics.compression = offenders.compression.totalGain;
|
|
|
|
|
|
// Small requests
|
|
// Small requests
|
|
offenders.smallRequests = listSmallRequests(results);
|
|
offenders.smallRequests = listSmallRequests(results);
|
|
@@ -338,8 +341,8 @@ var Redownload = function() {
|
|
|
|
|
|
requests.forEach(function(req) {
|
|
requests.forEach(function(req) {
|
|
if (req.weightCheck.bodySize > 0 && imageOptimizer.entryTypeCanBeOptimized(req) && req.weightCheck.isOptimized === false) {
|
|
if (req.weightCheck.bodySize > 0 && imageOptimizer.entryTypeCanBeOptimized(req) && req.weightCheck.isOptimized === false) {
|
|
- var before = req.weightCheck.afterCompression || req.weightCheck.bodySize;
|
|
|
|
- var after = req.weightCheck.afterOptimizationAndCompression || req.weightCheck.optimized;
|
|
|
|
|
|
+ var before = req.weightCheck.afterGzipCompression || req.weightCheck.bodySize;
|
|
|
|
+ var after = req.weightCheck.afterOptimizationAndGzipCompression || req.weightCheck.optimized;
|
|
var gain = before - after;
|
|
var gain = before - after;
|
|
|
|
|
|
if (gain > 200) {
|
|
if (gain > 200) {
|
|
@@ -349,8 +352,8 @@ var Redownload = function() {
|
|
url: req.url,
|
|
url: req.url,
|
|
original: req.weightCheck.bodySize,
|
|
original: req.weightCheck.bodySize,
|
|
isCompressed: req.weightCheck.isCompressed,
|
|
isCompressed: req.weightCheck.isCompressed,
|
|
- afterCompression: req.weightCheck.afterCompression,
|
|
|
|
- afterOptimizationAndCompression: req.weightCheck.afterOptimizationAndCompression,
|
|
|
|
|
|
+ afterGzipCompression: req.weightCheck.afterGzipCompression,
|
|
|
|
+ afterOptimizationAndGzipCompression: req.weightCheck.afterOptimizationAndGzipCompression,
|
|
lossless: req.weightCheck.lossless,
|
|
lossless: req.weightCheck.lossless,
|
|
lossy: req.weightCheck.lossy,
|
|
lossy: req.weightCheck.lossy,
|
|
gain: gain
|
|
gain: gain
|
|
@@ -398,8 +401,8 @@ var Redownload = function() {
|
|
|
|
|
|
requests.forEach(function(req) {
|
|
requests.forEach(function(req) {
|
|
if (req.weightCheck.bodySize > 0 && fileMinifier.entryTypeCanBeMinified(req) && req.weightCheck.isOptimized === false) {
|
|
if (req.weightCheck.bodySize > 0 && fileMinifier.entryTypeCanBeMinified(req) && req.weightCheck.isOptimized === false) {
|
|
- var before = req.weightCheck.afterCompression || req.weightCheck.bodySize;
|
|
|
|
- var after = req.weightCheck.afterOptimizationAndCompression || req.weightCheck.optimized;
|
|
|
|
|
|
+ var before = req.weightCheck.afterGzipCompression || req.weightCheck.bodySize;
|
|
|
|
+ var after = req.weightCheck.afterOptimizationAndGzipCompression || req.weightCheck.optimized;
|
|
var gain = before - after;
|
|
var gain = before - after;
|
|
|
|
|
|
if (gain > 200) {
|
|
if (gain > 200) {
|
|
@@ -409,8 +412,8 @@ var Redownload = function() {
|
|
url: req.url,
|
|
url: req.url,
|
|
original: req.weightCheck.bodySize,
|
|
original: req.weightCheck.bodySize,
|
|
isCompressed: req.weightCheck.isCompressed,
|
|
isCompressed: req.weightCheck.isCompressed,
|
|
- afterCompression: req.weightCheck.afterCompression,
|
|
|
|
- afterOptimizationAndCompression: req.weightCheck.afterOptimizationAndCompression,
|
|
|
|
|
|
+ afterGzipCompression: req.weightCheck.afterGzipCompression,
|
|
|
|
+ afterOptimizationAndGzipCompression: req.weightCheck.afterOptimizationAndGzipCompression,
|
|
optimized: req.weightCheck.optimized,
|
|
optimized: req.weightCheck.optimized,
|
|
gain: gain
|
|
gain: gain
|
|
});
|
|
});
|
|
@@ -421,24 +424,37 @@ var Redownload = function() {
|
|
return results;
|
|
return results;
|
|
}
|
|
}
|
|
|
|
|
|
- function listFilesNotGzipped(requests) {
|
|
|
|
|
|
+ function listFilesNotBrotlified(requests) {
|
|
var results = {
|
|
var results = {
|
|
totalGain: 0,
|
|
totalGain: 0,
|
|
files: []
|
|
files: []
|
|
};
|
|
};
|
|
|
|
|
|
requests.forEach(function(req) {
|
|
requests.forEach(function(req) {
|
|
- if (req.weightCheck.uncompressedSize && req.weightCheck.isCompressed === false && req.weightCheck.afterCompression) {
|
|
|
|
- var gain = req.weightCheck.uncompressedSize - req.weightCheck.afterCompression;
|
|
|
|
|
|
+ if (req.weightCheck.compressionTool !== 'brotli') {
|
|
|
|
+
|
|
|
|
+ var file = {
|
|
|
|
+ url: req.url,
|
|
|
|
+ wasCompressed: req.weightCheck.isCompressed,
|
|
|
|
+ brotlified: req.weightCheck.afterBrotliCompression
|
|
|
|
+ };
|
|
|
|
|
|
- results.totalGain += gain;
|
|
|
|
|
|
+ if (req.weightCheck.isCompressed) {
|
|
|
|
+ // The file was already gzipped (or deflated)
|
|
|
|
+ file.originalSize = req.weightCheck.bodySize;
|
|
|
|
+ file.gain = req.weightCheck.bodySize - req.weightCheck.afterBrotliCompression;
|
|
|
|
+ } else {
|
|
|
|
+ // The file was not compressed at all
|
|
|
|
+ file.originalSize = req.weightCheck.uncompressedSize;
|
|
|
|
+ file.gzipped = req.weightCheck.afterGzipCompression;
|
|
|
|
+ file.gain = req.weightCheck.uncompressedSize - req.weightCheck.afterBrotliCompression;
|
|
|
|
+ }
|
|
|
|
|
|
- results.files.push({
|
|
|
|
- url: req.url,
|
|
|
|
- original: req.weightCheck.uncompressedSize,
|
|
|
|
- gzipped: req.weightCheck.afterCompression,
|
|
|
|
- gain: gain
|
|
|
|
- });
|
|
|
|
|
|
+ // Just checking a last time if the gain is positive
|
|
|
|
+ if (file.gain > 200) {
|
|
|
|
+ results.totalGain += file.gain;
|
|
|
|
+ results.files.push(file);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
@@ -817,6 +833,7 @@ var Redownload = function() {
|
|
var bodySize = 0; // bytes size over the wire
|
|
var bodySize = 0; // bytes size over the wire
|
|
var bodyChunks = []; // an array of buffers
|
|
var bodyChunks = []; // an array of buffers
|
|
var isCompressed = false;
|
|
var isCompressed = false;
|
|
|
|
+ var compressionTool = '';
|
|
|
|
|
|
function tally() {
|
|
function tally() {
|
|
|
|
|
|
@@ -832,6 +849,7 @@ var Redownload = function() {
|
|
headersSize: Buffer.byteLength(rawHeaders, 'utf8'),
|
|
headersSize: Buffer.byteLength(rawHeaders, 'utf8'),
|
|
bodySize: bodySize,
|
|
bodySize: bodySize,
|
|
isCompressed: isCompressed,
|
|
isCompressed: isCompressed,
|
|
|
|
+ compressionTool: compressionTool,
|
|
uncompressedSize: uncompressedSize
|
|
uncompressedSize: uncompressedSize
|
|
};
|
|
};
|
|
|
|
|
|
@@ -849,6 +867,7 @@ var Redownload = function() {
|
|
uncompressedSize += data.length;
|
|
uncompressedSize += data.length;
|
|
}).on('end', function () {
|
|
}).on('end', function () {
|
|
isCompressed = true;
|
|
isCompressed = true;
|
|
|
|
+ compressionTool = 'gzip';
|
|
tally();
|
|
tally();
|
|
}).on('error', function(err) {
|
|
}).on('error', function(err) {
|
|
debug('Error while decoding %s', requestOptions.url);
|
|
debug('Error while decoding %s', requestOptions.url);
|
|
@@ -871,6 +890,7 @@ var Redownload = function() {
|
|
uncompressedSize += data.length;
|
|
uncompressedSize += data.length;
|
|
}).on('end', function () {
|
|
}).on('end', function () {
|
|
isCompressed = true;
|
|
isCompressed = true;
|
|
|
|
+ compressionTool = 'deflate';
|
|
tally();
|
|
tally();
|
|
}).on('error', function(err) {
|
|
}).on('error', function(err) {
|
|
debug('Error while decoding %s', requestOptions.url);
|
|
debug('Error while decoding %s', requestOptions.url);
|
|
@@ -893,6 +913,7 @@ var Redownload = function() {
|
|
uncompressedSize += data.length;
|
|
uncompressedSize += data.length;
|
|
}).on('end', function () {
|
|
}).on('end', function () {
|
|
isCompressed = true;
|
|
isCompressed = true;
|
|
|
|
+ compressionTool = 'brotli';
|
|
tally();
|
|
tally();
|
|
}).on('error', function(err) {
|
|
}).on('error', function(err) {
|
|
debug('Error while decoding %s', requestOptions.url);
|
|
debug('Error while decoding %s', requestOptions.url);
|