From def0144dabe675a1e7b63e0322120694b78f09cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Wed, 18 Jan 2017 12:16:26 +0700 Subject: [PATCH 01/10] Fix error when no url is provided --- lib/server/controllers/apiController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/server/controllers/apiController.js b/lib/server/controllers/apiController.js index 953f981..715a57c 100644 --- a/lib/server/controllers/apiController.js +++ b/lib/server/controllers/apiController.js @@ -24,7 +24,7 @@ var ApiController = function(app) { } // Block requests to unwanted websites (=spam) - if (isBlocked(req.body.url)) { + if (req.body.url && isBlocked(req.body.url)) { console.error('Test blocked for URL: %s', req.body.url); res.status(403).send('Forbidden'); return; From c4f243f4b09fe8559a884723545add3a6c906b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Tue, 16 Jan 2018 20:16:03 -0600 Subject: [PATCH 02/10] Large dependencies update (#257) * Massive dependecy update --- .travis.yml | 3 +- Gruntfile.js | 2 +- lib/server/controllers/frontController.js | 4 +- package.json | 84 ++++++++++++----------- 4 files changed, 48 insertions(+), 45 deletions(-) diff --git a/.travis.yml b/.travis.yml index d3027b9..7b0d53b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,9 @@ language: node_js sudo: false node_js: + - "8.9" - "6.2" - - "4.0" + - "4.7" env: - CXX=g++-4.8 addons: diff --git a/Gruntfile.js b/Gruntfile.js index 3d9a755..313447f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -143,7 +143,7 @@ module.exports = function(grunt) { options: { reporter: 'spec', }, - src: ['test/core/fontAnalyzerTest.js'] + src: ['test/core/contentTypeCheckerTest.js'] }, coverage: { options: { diff --git a/lib/server/controllers/frontController.js b/lib/server/controllers/frontController.js index 0fd4c6a..f193a29 100644 --- a/lib/server/controllers/frontController.js +++ b/lib/server/controllers/frontController.js @@ -14,7 +14,7 @@ var FrontController = function(app) { app.get(route, function(req, res) { res.setHeader('Cache-Control', 'public, max-age=20'); res.render(path.join(__dirname, assetsPath, 'main.html'), { - baseUrl: app.locals.baseUrl + baseUrl: app.locals.baseUrl || '/' }); }); }); @@ -23,7 +23,7 @@ var FrontController = function(app) { app.get('/views/:viewName', function(req, res) { res.setHeader('Cache-Control', 'public, max-age=' + cacheDuration); res.render(path.join(__dirname, assetsPath, 'views/' + req.params.viewName), { - baseUrl: app.locals.baseUrl + baseUrl: app.locals.baseUrl || '/' }); }); diff --git a/package.json b/package.json index 52bb7ae..22494bb 100644 --- a/package.json +++ b/package.json @@ -20,37 +20,37 @@ }, "main": "./lib/index.js", "dependencies": { - "angular": "1.6.1", - "angular-animate": "1.6.1", + "angular": "1.6.8", + "angular-animate": "1.6.8", "angular-chart.js": "1.1.1", - "angular-local-storage": "0.5.0", - "angular-resource": "1.6.1", - "angular-route": "1.6.1", - "angular-sanitize": "1.6.1", - "async": "1.5.2", - "body-parser": "1.15.2", - "chart.js": "2.4.0", - "clean-css": "3.4.23", - "color-diff": "1.0.0", - "compression": "1.6.2", - "cors": "2.8.1", + "angular-local-storage": "0.7.1", + "angular-resource": "1.6.8", + "angular-route": "1.6.8", + "angular-sanitize": "1.6.8", + "async": "2.6.0", + "body-parser": "1.18.2", + "chart.js": "2.7.1", + "clean-css": "4.1.9", + "color-diff": "1.1.0", + "compression": "1.7.1", + "cors": "2.8.4", "css-mq-parser": "0.0.3", - "debug": "2.6.0", + "debug": "3.1.0", "easyxml": "2.0.1", - "ejs": "2.5.5", - "express": "4.14.0", - "fontkit": "1.5.1", - "imagemin": "5.2.2", - "imagemin-jpegoptim": "5.0.0", + "ejs": "2.5.7", + "express": "4.16.2", + "fontkit": "1.7.7", + "imagemin": "5.3.1", + "imagemin-jpegoptim": "5.2.0", "imagemin-jpegtran": "5.0.2", "imagemin-optipng": "5.2.1", - "imagemin-svgo": "5.2.0", + "imagemin-svgo": "6.0.0", "is-eot": "1.0.0", "is-gif": "1.0.0", - "is-http2": "1.1.0", + "is-http2": "1.2.0", "is-jpg": "1.0.0", "is-otf": "0.1.2", - "is-png": "1.0.0", + "is-png": "1.1.0", "is-svg": "2.1.0", "is-ttf": "0.2.2", "is-woff": "1.0.3", @@ -58,42 +58,44 @@ "lwip": "0.0.9", "md5": "2.2.1", "meow": "3.7.0", - "minimize": "2.0.0", + "minimize": "2.1.0", "parse-color": "1.0.0", "phantomas": "1.19.0", - "ps-node": "0.1.4", - "q": "1.4.1", - "request": "2.79.0", - "rimraf": "2.5.4", + "ps-node": "0.1.6", + "q": "1.5.1", + "request": "2.83.0", + "rimraf": "2.6.2", "temporary": "0.0.8", - "try-thread-sleep": "1.0.0", - "uglify-js": "2.7.5" + "try-thread-sleep": "1.0.2", + "uglify-js": "2.8.29" }, "devDependencies": { - "chai": "~3.5.0", + "chai": "~4.1.2", "grunt": "~1.0.1", "grunt-blanket": "~0.0.10", - "grunt-contrib-clean": "~1.0.0", + "grunt-contrib-clean": "~1.1.0", "grunt-contrib-concat": "~1.0.1", "grunt-contrib-copy": "~1.0.0", - "grunt-contrib-cssmin": "~1.0.2", - "grunt-contrib-htmlmin": "~2.0.0", + "grunt-contrib-cssmin": "~2.2.1", + "grunt-contrib-htmlmin": "~2.4.0", "grunt-contrib-jshint": "~1.1.0", - "grunt-contrib-less": "~1.4.0", - "grunt-contrib-uglify": "~2.0.0", + "grunt-contrib-less": "~1.4.1", + "grunt-contrib-uglify": "~3.3.0", + "grunt-contrib-watch": "~1.0.0", "grunt-env": "~0.4.4", "grunt-express": "~1.4.1", "grunt-filerev": "~2.3.1", "grunt-inline-angular-templates": "~0.1.5", "grunt-line-remover": "~0.0.2", - "grunt-mocha-test": "~0.13.2", + "grunt-mocha-test": "~0.13.3", + "grunt-parallel": "~0.5.1", "grunt-replace": "~1.0.1", "grunt-usemin": "~3.1.1", - "grunt-webfont": "~1.4.0", - "matchdep": "~1.0.1", - "mocha": "~3.2.0", - "sinon": "~1.17.4", - "sinon-chai": "~2.8.0" + "grunt-webfont": "~1.6.0", + "matchdep": "~2.0.0", + "mocha": "~4.1.0", + "sinon": "~4.1.6", + "sinon-chai": "~2.14.0" }, "scripts": { "test": "grunt test" From 10a4cc270ac5cda2ef2496db5def9c4c0c84dff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Tue, 16 Jan 2018 20:41:04 -0600 Subject: [PATCH 03/10] v1.12.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 27f4ee4..6516b6c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "yellowlabtools", - "version": "1.12.3", + "version": "1.12.4", "description": "Online tool to audit a webpage for performance and front-end quality issues", "license": "GPL-2.0", "author": { From 369512c6c13ed92a7e4afadefc9a1e1e87910a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Tue, 16 Jan 2018 21:06:18 -0600 Subject: [PATCH 04/10] Remove Blanket coverage testing --- Gruntfile.js | 88 ++----------------------------------------------- package.json | 2 -- test/blanket.js | 7 ---- 3 files changed, 2 insertions(+), 95 deletions(-) delete mode 100644 test/blanket.js diff --git a/Gruntfile.js b/Gruntfile.js index 313447f..c72f0f0 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -80,27 +80,11 @@ module.exports = function(grunt) { dev: { src: ['front/src/css'] }, - coverage: { - src: ['.tmp', 'coverage/'] - }, build: { src: ['front/build'] } }, copy: { - beforeCoverage: { - files: [ - {src: ['bin/server.js'], dest: '.tmp/'} - ] - }, - coverage: { - files: [ - {cwd: 'test', src: '**/*', dest: 'coverage/test', expand: true}, - {cwd: 'lib/metadata', src: '**/*', dest: 'coverage/lib/metadata', expand: true}, - {cwd: 'node_modules/phantomas', src: '**/*', dest: 'coverage/node_modules/phantomas', expand: true}, - {cwd: 'lib/tools/phantomas/custom_modules', src: '**/*', dest: 'coverage/lib/tools/phantomas/custom_modules', expand: true} - ] - }, build: { files: [ {src: ['./front/src/img/favicon.png'], dest: './front/build/img/favicon.png'}, @@ -108,50 +92,18 @@ module.exports = function(grunt) { ] } }, - lineremover: { - beforeCoverage: { - files: { - '.tmp/bin/cli.js': 'bin/cli.js' - }, - options: { - exclusionPattern: /#!\/usr\/bin\/env node/ - } - } - }, - blanket: { - coverageApp: { - src: ['app/'], - dest: 'coverage/app/' - }, - coverageLib: { - src: ['lib/'], - dest: 'coverage/lib/' - }, - coverageBin: { - src: ['.tmp/bin/'], - dest: 'coverage/bin/' - } - }, mochaTest: { test: { options: { reporter: 'spec', }, - src: ['coverage/test/core/*.js', 'coverage/test/api/*.js'] + src: ['test/core/*.js', 'test/api/*.js'] }, 'test-current-work': { options: { reporter: 'spec', }, src: ['test/core/contentTypeCheckerTest.js'] - }, - coverage: { - options: { - reporter: 'html-cov', - quiet: true, - captureFile: 'coverage/coverage.html' - }, - src: ['coverage/test/core/*.js', 'coverage/test/api/*.js'] } }, env: { @@ -182,7 +134,7 @@ module.exports = function(grunt) { test: { options: { port: 8387, - server: './coverage/bin/server.js', + server: './bin/server.js', showStack: true } }, @@ -266,34 +218,6 @@ module.exports = function(grunt) { }); - // Custom task: copies the test settings.json file to the coverage folder, and checks if there's no missing fields - grunt.registerTask('copy-test-server-settings', function() { - var mainSettingsFile = './server_config/settings.json'; - var testSettingsFile = './test/fixtures/settings.json'; - - var mainSettings = grunt.file.readJSON(mainSettingsFile); - var testSettings = grunt.file.readJSON(testSettingsFile); - - // Recursively compare keys of two objects (not the values) - function compareKeys(original, copy, context) { - for (var key in original) { - if (!copy[key] && copy[key] !== '' && copy[key] !== 0) { - grunt.fail.warn('Settings file ' + testSettingsFile + ' doesn\'t contain key ' + context + '.' + key); - } - if (original[key] !== null && typeof original[key] === 'object') { - compareKeys(original[key], copy[key], context + '.' + key); - } - } - } - - compareKeys(mainSettings, testSettings, 'settings'); - - var outputFile = './coverage/server_config/settings.json'; - grunt.file.write(outputFile, JSON.stringify(testSettings, null, 4)); - grunt.log.ok('File ' + outputFile + ' created'); - }); - - grunt.registerTask('icons', [ 'webfont:icons', 'less', @@ -335,12 +259,6 @@ module.exports = function(grunt) { grunt.registerTask('test', [ 'build', 'express:testSuite', - 'clean:coverage', - 'copy-test-server-settings', - 'lineremover:beforeCoverage', - 'copy:beforeCoverage', - 'blanket', - 'copy:coverage', 'express:test', 'mochaTest:test', 'clean:tmp' @@ -349,8 +267,6 @@ module.exports = function(grunt) { grunt.registerTask('test-current-work', [ 'jshint', 'express:testSuite', - 'clean:coverage', - 'copy-test-server-settings', 'express:test-current-work', 'mochaTest:test-current-work', 'clean:tmp' diff --git a/package.json b/package.json index 6516b6c..1091cc3 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,6 @@ "devDependencies": { "chai": "~4.1.2", "grunt": "~1.0.1", - "grunt-blanket": "~0.0.10", "grunt-contrib-clean": "~1.1.0", "grunt-contrib-concat": "~1.0.1", "grunt-contrib-copy": "~1.0.0", @@ -86,7 +85,6 @@ "grunt-express": "~1.4.1", "grunt-filerev": "~2.3.1", "grunt-inline-angular-templates": "~0.1.5", - "grunt-line-remover": "~0.0.2", "grunt-mocha-test": "~0.13.3", "grunt-parallel": "~0.5.1", "grunt-replace": "~1.0.1", diff --git a/test/blanket.js b/test/blanket.js deleted file mode 100644 index d8260ab..0000000 --- a/test/blanket.js +++ /dev/null @@ -1,7 +0,0 @@ -var path = require('path'); -var srcDir = path.join(__dirname, '..', 'server'); - -require('blanket')({ - // Only files that match the pattern will be instrumented - pattern: srcDir -}); \ No newline at end of file From 3d368482bb49dbbe371634f39bdd39b9a1760e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Tue, 16 Jan 2018 21:21:56 -0600 Subject: [PATCH 05/10] Don't load analytics.js when not needed --- front/src/main.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/src/main.html b/front/src/main.html index c569b4e..fce557d 100644 --- a/front/src/main.html +++ b/front/src/main.html @@ -63,7 +63,7 @@ \ No newline at end of file From 84425e13195803054ca1a19031671a32fc5f1858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Wed, 17 Jan 2018 10:58:02 -0600 Subject: [PATCH 06/10] Fix tests --- Gruntfile.js | 8 +++++++- lib/server/controllers/apiController.js | 3 ++- lib/server/middlewares/apiLimitsMiddleware.js | 4 ++-- lib/server/middlewares/authMiddleware.js | 4 ++-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index c72f0f0..90eb3d2 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -103,7 +103,7 @@ module.exports = function(grunt) { options: { reporter: 'spec', }, - src: ['test/core/contentTypeCheckerTest.js'] + src: ['test/api/apiTest.js'] } }, env: { @@ -217,6 +217,10 @@ module.exports = function(grunt) { } }); + // Custom task that sets a variable for tests + grunt.registerTask('test-settings', function() { + process.env.IS_TEST = true; + }); grunt.registerTask('icons', [ 'webfont:icons', @@ -257,6 +261,7 @@ module.exports = function(grunt) { ]); grunt.registerTask('test', [ + 'test-settings', 'build', 'express:testSuite', 'express:test', @@ -265,6 +270,7 @@ module.exports = function(grunt) { ]); grunt.registerTask('test-current-work', [ + 'test-settings', 'jshint', 'express:testSuite', 'express:test-current-work', diff --git a/lib/server/controllers/apiController.js b/lib/server/controllers/apiController.js index 715a57c..fab7781 100644 --- a/lib/server/controllers/apiController.js +++ b/lib/server/controllers/apiController.js @@ -6,7 +6,8 @@ var ScreenshotHandler = require('../../screenshotHandler'); var RunsQueue = require('../datastores/runsQueue'); var RunsDatastore = require('../datastores/runsDatastore'); var ResultsDatastore = require('../datastores/resultsDatastore'); -var serverSettings = require('../../../server_config/settings.json'); + +var serverSettings = (process.env.IS_TEST) ? require('../../../test/fixtures/settings.json') : require('../../../server_config/settings.json'); var ApiController = function(app) { 'use strict'; diff --git a/lib/server/middlewares/apiLimitsMiddleware.js b/lib/server/middlewares/apiLimitsMiddleware.js index cce5df2..7e2c643 100644 --- a/lib/server/middlewares/apiLimitsMiddleware.js +++ b/lib/server/middlewares/apiLimitsMiddleware.js @@ -1,6 +1,6 @@ -var config = require('../../../server_config/settings.json'); +var config = (process.env.IS_TEST) ? require('../../../test/fixtures/settings.json') : require('../../../server_config/settings.json'); -var debug = require('debug')('apiLimitsMiddleware'); +var debug = require('debug')('apiLimitsMiddleware'); var apiLimitsMiddleware = function(req, res, next) { diff --git a/lib/server/middlewares/authMiddleware.js b/lib/server/middlewares/authMiddleware.js index e5335e6..d7094e2 100644 --- a/lib/server/middlewares/authMiddleware.js +++ b/lib/server/middlewares/authMiddleware.js @@ -1,6 +1,6 @@ -var config = require('../../../server_config/settings.json'); +var config = (process.env.IS_TEST) ? require('../../../test/fixtures/settings.json') : require('../../../server_config/settings.json'); -var debug = require('debug')('authMiddleware'); +var debug = require('debug')('authMiddleware'); var authMiddleware = function(req, res, next) { From 61bd31e421a2beefd2d5fd5fa930a9c971caa37f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Wed, 17 Jan 2018 11:02:40 -0600 Subject: [PATCH 07/10] Fix google analytics trying to send events --- front/src/js/app.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/front/src/js/app.js b/front/src/js/app.js index d1decbe..7fee1f2 100644 --- a/front/src/js/app.js +++ b/front/src/js/app.js @@ -35,7 +35,9 @@ yltApp.run(['$rootScope', '$location', function($rootScope, $location) { // Google Analytics $rootScope.$on('$routeChangeSuccess', function(){ - ga('send', 'pageview', {'page': $location.path()}); + if (ga) { + ga('send', 'pageview', {'page': $location.path()}); + } }); // GitHub star button (asynchronously loaded iframe) From a0e8a7f935e7d706ff41ab60e26f13c9cb55254a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Fri, 2 Mar 2018 19:17:54 -0600 Subject: [PATCH 08/10] Update jQuery versions (#262) --- lib/metadata/policies.js | 28 ++++++++++++++++------------ test/core/customPoliciesTest.js | 27 +++++++++++++-------------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/lib/metadata/policies.js b/lib/metadata/policies.js index 3a20d32..0ca4c79 100644 --- a/lib/metadata/policies.js +++ b/lib/metadata/policies.js @@ -288,28 +288,32 @@ var policies = { var value = data.toolsResults.phantomas.metrics.jQueryVersion; var score; - if (value.indexOf('3.1.') === 0 || - value.indexOf('3.2.') === 0 || - value.indexOf('3.3.') === 0) { + if (value.indexOf('3.3.') === 0 || + value.indexOf('3.4.') === 0 || + value.indexOf('3.5.') === 0 || + value.indexOf('4.0.') === 0) { score = 100; - } else if (value.indexOf('3.0.') === 0) { + } else if (value.indexOf('3.2.') === 0) { score = 90; + } else if (value.indexOf('3.1.') === 0) { + score = 70; + } else if (value.indexOf('3.0.') === 0) { + score = 50; } else if (value.indexOf('1.12.') === 0 || value.indexOf('2.2.') === 0) { - score = 70; + score = 40; } else if (value.indexOf('1.11.') === 0 || value.indexOf('2.1.') === 0) { - score = 50; + score = 30; } else if (value.indexOf('1.10.') === 0 || value.indexOf('2.0.') === 0) { - score = 40; - } else if (value.indexOf('1.9.') === 0) { - score = 30; - } else if (value.indexOf('1.8.') === 0) { score = 20; - } else if (value.indexOf('1.7') === 0) { + } else if (value.indexOf('1.9') === 0) { score = 10; - } else if (value.indexOf('1.6') === 0 || + } else if (value.indexOf('1.9') === 0 || + value.indexOf('1.8') === 0 || + value.indexOf('1.7') === 0 || + value.indexOf('1.6') === 0 || value.indexOf('1.5') === 0 || value.indexOf('1.4') === 0 || value.indexOf('1.3') === 0 || diff --git a/test/core/customPoliciesTest.js b/test/core/customPoliciesTest.js index 38a6dea..8e5dee3 100644 --- a/test/core/customPoliciesTest.js +++ b/test/core/customPoliciesTest.js @@ -182,20 +182,19 @@ describe('customPolicies', function() { it('should grade correctly jQuery versions', function() { var versions = { - '1.2.9': 0, - '1.6.3': 0, - '1.7.0': 10, - '1.8.3a': 20, - '1.9.2': 30, - '1.10.1': 40, - '2.0.0-rc1': 40, - '1.11.1': 50, - '2.1.1-beta1': 50, - '1.12.1': 70, - '2.2.1': 70, - '3.0.1': 90, - '3.1.0': 100, - '3.2.1': 100 + '1.7.0': 0, + '1.10.1': 20, + '1.10.3a': 20, + '2.0.0-rc1': 20, + '1.11.1': 30, + '2.1.1-beta1': 30, + '1.12.1': 40, + '2.2.1': 40, + '3.0.1': 50, + '3.1.0': 70, + '3.2.1': 90, + '3.3.1': 100, + '3.5.0': 100 }; for (var version in versions) { From 623f25e5219fd6ca67f7c9c8820498591bb84940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Fri, 2 Mar 2018 20:00:31 -0600 Subject: [PATCH 09/10] Update scores to match browsers perfs and new bandwidths --- lib/metadata/policies.js | 82 ++++++++++++++++++++-------------------- test/core/indexTest.js | 6 +-- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/lib/metadata/policies.js b/lib/metadata/policies.js index 0ca4c79..8b6b97e 100644 --- a/lib/metadata/policies.js +++ b/lib/metadata/policies.js @@ -6,18 +6,18 @@ var policies = { "tool": "phantomas", "label": "DOM elements count", "message": "

A high number of DOM elements means a lot of work for the browser to render the page.

It also slows down JavaScript DOM queries, as there are more elements to search through.

", - "isOkThreshold": 1000, - "isBadThreshold": 2500, - "isAbnormalThreshold": 4000, + "isOkThreshold": 1500, + "isBadThreshold": 3000, + "isAbnormalThreshold": 4500, "hasOffenders": false }, "DOMelementMaxDepth": { "tool": "phantomas", "label": "DOM max depth", "message": "

A deep DOM makes the CSS matching with DOM elements difficult.

It also slows down JavaScript modifications to the DOM because changing the dimensions of an element makes the browser re-calculate the dimensions of it's parents. Same thing for JavaScript events, that bubble up to the document root.

", - "isOkThreshold": 10, - "isBadThreshold": 20, - "isAbnormalThreshold": 28, + "isOkThreshold": 12, + "isBadThreshold": 22, + "isAbnormalThreshold": 30, "hasOffenders": true, "offendersTransformFn": function(offenders) { var domArrays = offenders.map(offendersHelpers.domPathToArray); @@ -32,7 +32,7 @@ var policies = { "tool": "phantomas", "label": "Number of iframes", "message": "

iFrames are the most complex HTML elements. They are pages, just like the main page, and the browser needs to create a new page context, which has a cost.

", - "isOkThreshold": 2, + "isOkThreshold": 3, "isBadThreshold": 15, "isAbnormalThreshold": 30, "hasOffenders": false @@ -70,9 +70,9 @@ var policies = { "tool": "jsExecutionTransformer", "label": "DOM access", "message": "

This metric counts the number of calls to DOM related functions (both native DOM functions and jQuery functions) on page load.

The more your JavaScript code accesses the DOM, the slower the page will load.

Try, as much as possible, to have an HTML page fully generated by the server instead of making changes with JS.

Try to reduce the number of queries by refactoring your JavaScript code.

Binding too many events also has a cost. Try to use event delegation as much as possible.

", - "isOkThreshold": 50, - "isBadThreshold": 1500, - "isAbnormalThreshold": 3000, + "isOkThreshold": 200, + "isBadThreshold": 2000, + "isAbnormalThreshold": 4000, "hasOffenders": false }, "queriesWithoutResults": { @@ -80,8 +80,8 @@ var policies = { "label": "Queries without result", "message": "

Number of queries that return no result. Both native and jQuery DOM requests are counted.

It suggests the query is not used on the page, probably because it is some dead code.

Or maybe the code is trying to find an HTML block that is not always here. Look at the JS Timeline to see if the scripts correctly figures out the HTML block is not here and immediatly stops interacting further with the DOM.

", "isOkThreshold": 0, - "isBadThreshold": 100, - "isAbnormalThreshold": 200, + "isBadThreshold": 150, + "isAbnormalThreshold": 250, "hasOffenders": false }, "DOMqueriesAvoidable": { @@ -89,8 +89,8 @@ var policies = { "label": "Duplicated DOM queries", "message": "

This is the number of queries that could be avoided by removing all duplicated queries.

Simply save the result of a query in a variable. Ok it is not always simple, especially with third-party scripts, but at least do it with your own code.

", "isOkThreshold": 0, - "isBadThreshold": 200, - "isAbnormalThreshold": 500, + "isBadThreshold": 300, + "isAbnormalThreshold": 600, "hasOffenders": true, "takeOffendersFrom": "DOMqueriesDuplicated", "offendersTransformFn": function(offenders) { @@ -121,7 +121,7 @@ var policies = { "label": "Scroll events bound", "message": "

Number of 'scroll' event listeners binded to 'window' or 'document'.

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.

", "isOkThreshold": 1, - "isBadThreshold": 7, + "isBadThreshold": 8, "isAbnormalThreshold": 15, "hasOffenders": true, "offendersTransformFn": function(offenders) { @@ -195,8 +195,8 @@ var policies = { "label": "document.write calls", "message": "

They slow down the page construction, especially if they are used to insert scripts in the page. Remove them ASAP.

If you cannot remove them because they come from a third-party script (such as ads), have a look at PostScribe.

", "isOkThreshold": 0, - "isBadThreshold": 5, - "isAbnormalThreshold": 10, + "isBadThreshold": 3, + "isAbnormalThreshold": 8, "hasOffenders": true, "offendersTransformFn": function(offenders) { return { @@ -254,8 +254,8 @@ var policies = { "tool": "phantomas", "label": "Console messages", "message": "

Try to keep your console clean when in production. Debugging is good for development only.

Writing in the console has a cost, especially when dumping large object variables.

There is also a problem with Internet Explorer 8, not knowing the console object.

", - "isOkThreshold": 0, - "isBadThreshold": 10, + "isOkThreshold": 3, + "isBadThreshold": 20, "isAbnormalThreshold": 50, "hasOffenders": false }, @@ -423,7 +423,7 @@ var policies = { "tool": "phantomas", "label": "Rules count", "message": "

Having a huge number of CSS rules hurts performances. If the number of CSS rules is higher than the number of DOM elements, there is clearly a problem.

Huge stylesheets generally occur when the different pages of a website load all the CSS, concatenated in a single stylesheet, even if a large part of the rules are page-specific. Solution is to create one main CSS file with global rules and one custom file per page.

", - "isOkThreshold": 750, + "isOkThreshold": 1000, "isBadThreshold": 3000, "isAbnormalThreshold": 4500, "hasOffenders": true, @@ -466,7 +466,7 @@ var policies = { "label": "Complex selectors", "message": "

Complex selectors are CSS selectors with 4 or more expressions, like \"#header ul li .foo\".

They are adding more work for the browser, and this could be avoided by simplifying selectors. The B.E.M. methodology is an useful way to simplify your CSS.

", "isOkThreshold": 0, - "isBadThreshold": 600, + "isBadThreshold": 800, "isAbnormalThreshold": 2000, "hasOffenders": true, "offendersTransformFn": function(offenders) { @@ -482,7 +482,7 @@ var policies = { "tool": "phantomas", "label": "Colors count", "message": "

This is the number of different colors defined in CSS.

Your CSS will be easier to maintain if you keep a small color set.

", - "isOkThreshold": 30, + "isOkThreshold": 50, "isBadThreshold": 150, "isAbnormalThreshold": 400, "hasOffenders": true, @@ -565,8 +565,8 @@ var policies = { "tool": "mediaQueriesChecker", "label": "Not mobile-first media queries", "message": "

This is the number of CSS rules inside media queries that address small screens.

The common good practice, when creating a responsive website, is to write it \"mobile-first\". More explanation in this great article.

", - "isOkThreshold": 25, - "isBadThreshold": 200, + "isOkThreshold": 50, + "isBadThreshold": 250, "isAbnormalThreshold": 1000, "hasOffenders": true, "offendersTransformFn": function(offenders) { @@ -739,8 +739,8 @@ var policies = { "label": "Old IE fixes", "message": "

What browser do you need to support? Once you've got the answer, take a look at these old rules that pollute your CSS code and remove them.

IE6:

  • * html
  • html > body (everything but IE6)

IE7:

  • *height: 123px;
  • height: 123px !ie;

IE9:

  • -ms-filter
  • progid:DXImageTransform.Microsoft

", "isOkThreshold": 0, - "isBadThreshold": 75, - "isAbnormalThreshold": 300, + "isBadThreshold": 50, + "isAbnormalThreshold": 150, "hasOffenders": true, "offendersTransformFn": function(offenders) { var parsedOffenders = offenders.map(function(offender) { @@ -795,8 +795,8 @@ var policies = { "label": "Old prefixes", "message": "

Many property prefixes such as -moz- or -webkit- are not needed anymore, or by very few people. Sometimes, they have never even existed. You can remove them or replace them with the non-prefixed version. This will help reducing your stylesheets weight.

The prefixes database comes from Can I Use.

", "isOkThreshold": 0, - "isBadThreshold": 75, - "isAbnormalThreshold": 300, + "isBadThreshold": 50, + "isAbnormalThreshold": 200, "hasOffenders": true, "offendersTransformFn": function(offenders) { var properties = {}; @@ -898,9 +898,9 @@ var policies = { "tool": "redownload", "label": "Total weight", "message": "

The weight is of course very important if you want the page to load fast. Try to stay under 1MB, which is already very long to download over a slow connection.

Please note that Yellow Lab Tools' engine (PhantomJS) is not compatible with image srcset (unless you use a polyfill). This can lead to incorrect page weight.

", - "isOkThreshold": 716800, - "isBadThreshold": 2097152, - "isAbnormalThreshold": 3145728, + "isOkThreshold": 1048576, + "isBadThreshold": 2621440, + "isAbnormalThreshold": 4194304, "hasOffenders": true, "unit": 'bytes' }, @@ -908,8 +908,8 @@ var policies = { "tool": "redownload", "label": "Image optimization", "message": "

This metric measures the number of bytes that could be saved by optimizing images.

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 Kraken.io or the excellent ImageOptim on Mac. For SVG images, you can use SVGOMG

The tools in use in YellowLabTools are not set to their maximum optimization power (JPEG quality 85), so you might be able to compress even more!

Please note that Yellow Lab Tools' engine (PhantomJS) is not compatible with image srcset (unless you use a polyfill). This can lead to incorrect page weight.

", - "isOkThreshold": 10240, - "isBadThreshold": 122880, + "isOkThreshold": 20480, + "isBadThreshold": 204800, "isAbnormalThreshold": 307200, "hasOffenders": true, "unit": 'bytes' @@ -938,9 +938,9 @@ var policies = { "tool": "redownload", "label": "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:

  • Concatenate JS files
  • Concatenate CSS files
  • Embed or inline small JS or CSS files in the HTML
  • Create sprites
  • Base64 encode small images in HTML or stylesheets
  • Use lazyloading for images

", - "isOkThreshold": 15, - "isBadThreshold": 100, - "isAbnormalThreshold": 180, + "isOkThreshold": 20, + "isBadThreshold": 120, + "isAbnormalThreshold": 200, "hasOffenders": true }, "domains": { @@ -986,8 +986,8 @@ var policies = { "label": "Connections closed", "message": "

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.

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.

Correct the problem by setting a Keep-Alive header on the guilty server.

", "isOkThreshold": 0, - "isBadThreshold": 7, - "isAbnormalThreshold": 20, + "isBadThreshold": 4, + "isAbnormalThreshold": 15, "hasOffenders": true }, "identicalFiles": { @@ -1015,9 +1015,9 @@ var policies = { "tool": "redownload", "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, + "isOkThreshold": 10, + "isBadThreshold": 50, + "isAbnormalThreshold": 80, "hasOffenders": true }, "lazyLoadableImagesBelowTheFold": { diff --git a/test/core/indexTest.js b/test/core/indexTest.js index 64de646..71874d9 100644 --- a/test/core/indexTest.js +++ b/test/core/indexTest.js @@ -66,9 +66,9 @@ describe('index.js', function() { "tool": "phantomas", "label": "DOM max depth", "message": "

A deep DOM makes the CSS matching with DOM elements difficult.

It also slows down JavaScript modifications to the DOM because changing the dimensions of an element makes the browser re-calculate the dimensions of it's parents. Same thing for JavaScript events, that bubble up to the document root.

", - "isOkThreshold": 10, - "isBadThreshold": 20, - "isAbnormalThreshold": 28, + "isOkThreshold": 12, + "isBadThreshold": 22, + "isAbnormalThreshold": 30, "hasOffenders": true }, "value": 1, From 6bdbfa2657979e3263d3a83866d96cc3b50d33c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Fri, 2 Mar 2018 20:13:47 -0600 Subject: [PATCH 10/10] v1.13 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1091cc3..fab364f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "yellowlabtools", - "version": "1.12.4", + "version": "1.13.0", "description": "Online tool to audit a webpage for performance and front-end quality issues", "license": "GPL-2.0", "author": {