diff --git a/lighthouse-core/config/default.js b/lighthouse-core/config/default.js index 7f1dbe62bb30..ff89cf52a9bf 100644 --- a/lighthouse-core/config/default.js +++ b/lighthouse-core/config/default.js @@ -27,6 +27,8 @@ module.exports = { { "passName": "redirectPass", "useThrottling": false, + // Speed up the redirect pass by blocking stylesheets, fonts, and images + "blockedUrlPatterns": ["*.css", "*.jpg", "*.jpeg", "*.png", "*.gif", "*.svg", "*.ttf", "*.woff", "*.woff2"], "gatherers": [ "http-redirect", "html-without-javascript" diff --git a/lighthouse-core/gather/driver.js b/lighthouse-core/gather/driver.js index 6db4efa8db03..f0e76249665b 100644 --- a/lighthouse-core/gather/driver.js +++ b/lighthouse-core/gather/driver.js @@ -852,9 +852,18 @@ class Driver { return collectUsage; } - blockUrlPatterns(urlPatterns) { - const promiseArr = urlPatterns.map(url => this.sendCommand('Network.addBlockedURL', {url})); - return Promise.all(promiseArr); + /** + * @param {!Array} urls URL patterns to block. Wildcards ('*') are allowed. + * @return {!Promise} + */ + blockUrlPatterns(urls) { + return this.sendCommand('Network.setBlockedURLs', {urls}) + .catch(err => { + // TODO: remove this handler once m59 hits stable + if (!/wasn't found/.test(err.message)) { + throw err; + } + }); } /** diff --git a/lighthouse-core/gather/gather-runner.js b/lighthouse-core/gather/gather-runner.js index c3446feb8e84..a3b82dedd1c2 100644 --- a/lighthouse-core/gather/gather-runner.js +++ b/lighthouse-core/gather/gather-runner.js @@ -40,12 +40,12 @@ let GathererResults; // eslint-disable-line no-unused-vars * iv. evaluateScriptOnLoad rescue native Promise from potential polyfill * v. cleanAndDisableBrowserCaches * vi. clearDataForOrigin - * vii. blockUrlPatterns * * 2. For each pass in the config: * A. GatherRunner.beforePass() * i. navigate to about:blank - * ii. all gatherers' beforePass() + * ii. Enable network request blocking for specified patterns + * iii. all gatherers' beforePass() * B. GatherRunner.pass() * i. beginTrace (if requested) & beginDevtoolsLog * ii. GatherRunner.loadPage() @@ -112,7 +112,6 @@ class GatherRunner { .then(_ => driver.dismissJavaScriptDialogs()) .then(_ => resetStorage && driver.cleanAndDisableBrowserCaches()) .then(_ => resetStorage && driver.clearDataForOrigin(options.url)) - .then(_ => driver.blockUrlPatterns(options.flags.blockedUrlPatterns || [])) .then(_ => gathererResults.UserAgent = [driver.getUserAgent()]); } @@ -171,9 +170,15 @@ class GatherRunner { * @return {!Promise} */ static beforePass(options, gathererResults) { + const blockedUrls = (options.config.blockedUrlPatterns || []) + .concat(options.flags.blockedUrlPatterns || []); const blankPage = options.config.blankPage; const blankDuration = options.config.blankDuration; - const pass = GatherRunner.loadBlank(options.driver, blankPage, blankDuration); + const pass = GatherRunner.loadBlank(options.driver, blankPage, blankDuration) + // Set request blocking before any network activity + // No "clearing" is done at the end of the pass since blockUrlPatterns([]) will unset all if + // neccessary at the beginning of the next pass. + .then(() => options.driver.blockUrlPatterns(blockedUrls)); return options.config.gatherers.reduce((chain, gatherer) => { return chain.then(_ => { diff --git a/lighthouse-core/test/gather/gather-runner-test.js b/lighthouse-core/test/gather/gather-runner-test.js index 681ac71d7323..ba0f269fa95c 100644 --- a/lighthouse-core/test/gather/gather-runner-test.js +++ b/lighthouse-core/test/gather/gather-runner-test.js @@ -77,7 +77,7 @@ function getMockedEmulationDriver(emulationFn, netThrottleFn, cpuThrottleFn, blo case 'Emulation.setDeviceMetricsOverride': fn = emulationFn; break; - case 'Network.addBlockedURL': + case 'Network.setBlockedURLs': fn = blockUrlFn; break; default: @@ -303,25 +303,37 @@ describe('GatherRunner', function() { }); it('tells the driver to block given URL patterns when blockedUrlPatterns is given', () => { - const receivedUrlPatterns = []; - const urlPatterns = ['http://*.evil.com', '.jpg', '.woff2']; + let receivedUrlPatterns = null; const driver = getMockedEmulationDriver(null, null, null, params => { - receivedUrlPatterns.push(params.url); + receivedUrlPatterns = params.urls; }); - return GatherRunner.setupDriver(driver, {}, {flags: {blockedUrlPatterns: urlPatterns.slice()}}) - .then(() => assert.deepStrictEqual(receivedUrlPatterns.sort(), urlPatterns.sort())); + return GatherRunner.beforePass({ + driver, + flags: { + blockedUrlPatterns: ['http://*.evil.com', '.jpg', '.woff2'], + }, + config: { + blockedUrlPatterns: ['*.jpeg'], + gatherers: [], + }, + }).then(() => assert.deepStrictEqual( + receivedUrlPatterns.sort(), + ['*.jpeg', '.jpg', '.woff2', 'http://*.evil.com'] + )); }); it('does not throw when blockedUrlPatterns is not given', () => { - const receivedUrlPatterns = []; + let receivedUrlPatterns = null; const driver = getMockedEmulationDriver(null, null, null, params => { - receivedUrlPatterns.push(params.url); + receivedUrlPatterns = params.urls; }); - return GatherRunner.setupDriver(driver, {}, {flags: {}}) - .then(() => assert.equal(receivedUrlPatterns.length, 0)) - .catch(() => assert.ok(false)); + return GatherRunner.beforePass({ + driver, + flags: {}, + config: {gatherers: []}, + }).then(() => assert.deepStrictEqual(receivedUrlPatterns, [])); }); it('tells the driver to begin tracing', () => {