core(config): switch to throttling settings object (#4879)
This commit is contained in:
Родитель
2200c7851e
Коммит
467453d2c1
|
@ -137,7 +137,7 @@ class UnusedBytes extends Audit {
|
|||
static createAuditResult(result, graph) {
|
||||
const simulatorOptions = PredictivePerf.computeRTTAndServerResponseTime(graph);
|
||||
// TODO: calibrate multipliers, see https://github.com/GoogleChrome/lighthouse/issues/820
|
||||
Object.assign(simulatorOptions, {cpuTaskMultiplier: 1, layoutTaskMultiplier: 1});
|
||||
Object.assign(simulatorOptions, {cpuSlowdownMultiplier: 1, layoutTaskMultiplier: 1});
|
||||
const simulator = new LoadSimulator(graph, simulatorOptions);
|
||||
|
||||
const debugString = result.debugString;
|
||||
|
|
|
@ -80,7 +80,7 @@ class LoadFastEnough4Pwa extends Audit {
|
|||
});
|
||||
|
||||
let firstRequestLatencies = Array.from(firstRequestLatenciesByOrigin.values());
|
||||
const latency3gMin = Emulation.settings.TYPICAL_MOBILE_THROTTLING_METRICS.targetLatency - 10;
|
||||
const latency3gMin = Emulation.settings.MOBILE_3G_THROTTLING.targetLatencyMs - 10;
|
||||
const areLatenciesAll3G = firstRequestLatencies.every(val => val.latency > latency3gMin);
|
||||
firstRequestLatencies = firstRequestLatencies.map(item => ({
|
||||
url: item.url,
|
||||
|
|
|
@ -6,12 +6,20 @@
|
|||
'use strict';
|
||||
|
||||
const Driver = require('../gather/driver');
|
||||
const emulation = require('../lib/emulation').settings;
|
||||
|
||||
/* eslint-disable max-len */
|
||||
|
||||
module.exports = {
|
||||
settings: {
|
||||
maxWaitForLoad: Driver.MAX_WAIT_FOR_FULLY_LOADED,
|
||||
throttlingMethod: 'devtools',
|
||||
throttling: {
|
||||
requestLatencyMs: emulation.MOBILE_3G_THROTTLING.adjustedLatencyMs,
|
||||
downloadThroughputKbps: emulation.MOBILE_3G_THROTTLING.adjustedDownloadThroughputKbps,
|
||||
uploadThroughputKbps: emulation.MOBILE_3G_THROTTLING.adjustedUploadThroughputKbps,
|
||||
cpuSlowdownMultiplier: emulation.CPU_THROTTLE_METRICS.rate,
|
||||
},
|
||||
},
|
||||
passes: [{
|
||||
passName: 'defaultPass',
|
||||
|
|
|
@ -1033,14 +1033,16 @@ class Driver {
|
|||
* @return {Promise<void>}
|
||||
*/
|
||||
async setThrottling(settings, passConfig) {
|
||||
const throttleCpu = passConfig.useThrottling && !settings.disableCpuThrottling;
|
||||
const throttleNetwork = passConfig.useThrottling && !settings.disableNetworkThrottling;
|
||||
const cpuPromise = throttleCpu ?
|
||||
emulation.enableCPUThrottling(this) :
|
||||
if (settings.throttlingMethod !== 'devtools') {
|
||||
return emulation.clearAllNetworkEmulation(this);
|
||||
}
|
||||
|
||||
const cpuPromise = passConfig.useThrottling ?
|
||||
emulation.enableCPUThrottling(this, settings.throttling) :
|
||||
emulation.disableCPUThrottling(this);
|
||||
const networkPromise = throttleNetwork ?
|
||||
emulation.enableNetworkThrottling(this) :
|
||||
emulation.disableNetworkThrottling(this);
|
||||
const networkPromise = passConfig.useThrottling ?
|
||||
emulation.enableNetworkThrottling(this, settings.throttling) :
|
||||
emulation.clearAllNetworkEmulation(this);
|
||||
|
||||
await Promise.all([cpuPromise, networkPromise]);
|
||||
}
|
||||
|
@ -1056,8 +1058,7 @@ class Driver {
|
|||
}
|
||||
|
||||
/**
|
||||
* Enable internet connection, using emulated mobile settings if
|
||||
* `options.settings.disableNetworkThrottling` is false.
|
||||
* Enable internet connection, using emulated mobile settings if applicable.
|
||||
* @param {{settings: LH.ConfigSettings, passConfig: LH.ConfigPass}} options
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
|
|
|
@ -16,13 +16,13 @@ const emulation = require('../../emulation').settings;
|
|||
const DEFAULT_MAXIMUM_CONCURRENT_REQUESTS = 10;
|
||||
|
||||
// Fast 3G emulation target from DevTools, WPT 3G - Fast setting
|
||||
const DEFAULT_RTT = emulation.TYPICAL_MOBILE_THROTTLING_METRICS.targetLatency;
|
||||
const DEFAULT_THROUGHPUT = emulation.TYPICAL_MOBILE_THROTTLING_METRICS.targetDownloadThroughput * 8; // 1.6 Mbps
|
||||
const DEFAULT_RTT = emulation.MOBILE_3G_THROTTLING.targetLatencyMs;
|
||||
const DEFAULT_THROUGHPUT = emulation.MOBILE_3G_THROTTLING.targetDownloadThroughputKbps * 1024; // 1.6 Mbps
|
||||
|
||||
// same multiplier as Lighthouse uses for CPU emulation
|
||||
const DEFAULT_CPU_TASK_MULTIPLIER = emulation.CPU_THROTTLE_METRICS.rate;
|
||||
// layout tasks tend to be less CPU-bound and do not experience the same increase in duration
|
||||
const DEFAULT_LAYOUT_TASK_MULTIPLIER = DEFAULT_CPU_TASK_MULTIPLIER / 2;
|
||||
const DEFAULT_LAYOUT_TASK_MULTIPLIER = 0.5;
|
||||
// if a task takes more than 10 seconds it's usually a sign it isn't actually CPU bound and we're overestimating
|
||||
const DEFAULT_MAXIMUM_CPU_TASK_DURATION = 10000;
|
||||
|
||||
|
@ -45,7 +45,7 @@ class Simulator {
|
|||
rtt: DEFAULT_RTT,
|
||||
throughput: DEFAULT_THROUGHPUT,
|
||||
maximumConcurrentRequests: DEFAULT_MAXIMUM_CONCURRENT_REQUESTS,
|
||||
cpuTaskMultiplier: DEFAULT_CPU_TASK_MULTIPLIER,
|
||||
cpuSlowdownMultiplier: DEFAULT_CPU_TASK_MULTIPLIER,
|
||||
layoutTaskMultiplier: DEFAULT_LAYOUT_TASK_MULTIPLIER,
|
||||
},
|
||||
options
|
||||
|
@ -57,8 +57,8 @@ class Simulator {
|
|||
TcpConnection.maximumSaturatedConnections(this._rtt, this._throughput),
|
||||
this._options.maximumConcurrentRequests
|
||||
);
|
||||
this._cpuTaskMultiplier = this._options.cpuTaskMultiplier;
|
||||
this._layoutTaskMultiplier = this._options.layoutTaskMultiplier;
|
||||
this._cpuSlowdownMultiplier = this._options.cpuSlowdownMultiplier;
|
||||
this._layoutTaskMultiplier = this._cpuSlowdownMultiplier * this._options.layoutTaskMultiplier;
|
||||
|
||||
this._nodeTiming = new Map();
|
||||
this._numberInProgressByType = new Map();
|
||||
|
@ -206,7 +206,7 @@ class Simulator {
|
|||
const timingData = this._nodeTiming.get(node);
|
||||
const multiplier = (/** @type {CpuNode} */ (node)).didPerformLayout()
|
||||
? this._layoutTaskMultiplier
|
||||
: this._cpuTaskMultiplier;
|
||||
: this._cpuSlowdownMultiplier;
|
||||
const totalDuration = Math.min(
|
||||
Math.round((/** @type {CpuNode} */ (node)).event.dur / 1000 * multiplier),
|
||||
DEFAULT_MAXIMUM_CPU_TASK_DURATION
|
||||
|
@ -360,7 +360,7 @@ module.exports = Simulator;
|
|||
* @property {number} [throughput]
|
||||
* @property {number} [fallbackTTFB]
|
||||
* @property {number} [maximumConcurrentRequests]
|
||||
* @property {number} [cpuTaskMultiplier]
|
||||
* @property {number} [cpuSlowdownMultiplier]
|
||||
* @property {number} [layoutTaskMultiplier]
|
||||
*/
|
||||
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
// @ts-nocheck
|
||||
'use strict';
|
||||
|
||||
const Driver = require('../gather/driver'); // eslint-disable-line no-unused-vars
|
||||
|
||||
const NBSP = '\xa0';
|
||||
|
||||
/**
|
||||
* Nexus 5X metrics adapted from emulated_devices/module.json
|
||||
*/
|
||||
|
@ -40,17 +43,16 @@ const LATENCY_FACTOR = 3.75;
|
|||
const THROUGHPUT_FACTOR = 0.9;
|
||||
|
||||
const TARGET_LATENCY = 150; // 150ms
|
||||
const TARGET_DOWNLOAD_THROUGHPUT = Math.floor(1.6 * 1024 * 1024 / 8); // 1.6Mbps
|
||||
const TARGET_UPLOAD_THROUGHPUT = Math.floor(750 * 1024 / 8); // 750Kbps
|
||||
const TARGET_DOWNLOAD_THROUGHPUT = Math.floor(1.6 * 1024); // 1.6Mbps
|
||||
const TARGET_UPLOAD_THROUGHPUT = Math.floor(750); // 750Kbps
|
||||
|
||||
const TYPICAL_MOBILE_THROTTLING_METRICS = {
|
||||
targetLatency: TARGET_LATENCY,
|
||||
latency: TARGET_LATENCY * LATENCY_FACTOR,
|
||||
targetDownloadThroughput: TARGET_DOWNLOAD_THROUGHPUT,
|
||||
downloadThroughput: TARGET_DOWNLOAD_THROUGHPUT * THROUGHPUT_FACTOR,
|
||||
targetUploadThroughput: TARGET_UPLOAD_THROUGHPUT,
|
||||
uploadThroughput: TARGET_UPLOAD_THROUGHPUT * THROUGHPUT_FACTOR,
|
||||
offline: false,
|
||||
const MOBILE_3G_THROTTLING = {
|
||||
targetLatencyMs: TARGET_LATENCY,
|
||||
adjustedLatencyMs: TARGET_LATENCY * LATENCY_FACTOR,
|
||||
targetDownloadThroughputKbps: TARGET_DOWNLOAD_THROUGHPUT,
|
||||
adjustedDownloadThroughputKbps: TARGET_DOWNLOAD_THROUGHPUT * THROUGHPUT_FACTOR,
|
||||
targetUploadThroughputKbps: TARGET_UPLOAD_THROUGHPUT,
|
||||
adjustedUploadThroughputKbps: TARGET_UPLOAD_THROUGHPUT * THROUGHPUT_FACTOR,
|
||||
};
|
||||
|
||||
const OFFLINE_METRICS = {
|
||||
|
@ -75,34 +77,10 @@ const CPU_THROTTLE_METRICS = {
|
|||
rate: 4,
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Driver} driver
|
||||
*/
|
||||
function enableNexus5X(driver) {
|
||||
// COMPAT FIMXE
|
||||
// Injecting this function clientside is no longer neccessary as of m62. This is done
|
||||
// on the backend when `Emulation.setTouchEmulationEnabled` is set.
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=133915#c63
|
||||
// Once m62 hits stable (~Oct 20th) we can nuke this entirely
|
||||
/**
|
||||
* Finalizes touch emulation by enabling `"ontouchstart" in window` feature detect
|
||||
* to work. Messy hack, though copied verbatim from DevTools' emulation/TouchModel.js
|
||||
* where it's been working for years. addScriptToEvaluateOnLoad runs before any of the
|
||||
* page's JavaScript executes.
|
||||
*/
|
||||
/* eslint-disable no-proto */ /* global window, document */ /* istanbul ignore next */
|
||||
const injectedTouchEventsFunction = function() {
|
||||
const touchEvents = ['ontouchstart', 'ontouchend', 'ontouchmove', 'ontouchcancel'];
|
||||
const recepients = [window.__proto__, document.__proto__];
|
||||
for (let i = 0; i < touchEvents.length; ++i) {
|
||||
for (let j = 0; j < recepients.length; ++j) {
|
||||
if (!(touchEvents[i] in recepients[j])) {
|
||||
Object.defineProperty(recepients[j], touchEvents[i], {
|
||||
value: null, writable: true, configurable: true, enumerable: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/* eslint-enable */
|
||||
|
||||
return Promise.all([
|
||||
driver.sendCommand('Emulation.setDeviceMetricsOverride', NEXUS5X_EMULATION_METRICS),
|
||||
// Network.enable must be called for UA overriding to work
|
||||
|
@ -112,47 +90,122 @@ function enableNexus5X(driver) {
|
|||
enabled: true,
|
||||
configuration: 'mobile',
|
||||
}),
|
||||
driver.sendCommand('Page.addScriptToEvaluateOnLoad', {
|
||||
scriptSource: '(' + injectedTouchEventsFunction.toString() + ')()',
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
function enableNetworkThrottling(driver) {
|
||||
return driver.sendCommand('Network.emulateNetworkConditions', TYPICAL_MOBILE_THROTTLING_METRICS);
|
||||
/**
|
||||
* @param {Driver} driver
|
||||
* @param {LH.ThrottlingSettings|undefined} throttlingSettings
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function enableNetworkThrottling(driver, throttlingSettings) {
|
||||
/** @type {LH.Crdp.Network.EmulateNetworkConditionsRequest} */
|
||||
let conditions;
|
||||
if (throttlingSettings) {
|
||||
conditions = {
|
||||
offline: false,
|
||||
latency: throttlingSettings.requestLatencyMs || 0,
|
||||
downloadThroughput: throttlingSettings.downloadThroughputKbps || 0,
|
||||
uploadThroughput: throttlingSettings.uploadThroughputKbps || 0,
|
||||
};
|
||||
} else {
|
||||
conditions = {
|
||||
offline: false,
|
||||
latency: MOBILE_3G_THROTTLING.adjustedLatencyMs,
|
||||
downloadThroughput: MOBILE_3G_THROTTLING.adjustedDownloadThroughputKbps,
|
||||
uploadThroughput: MOBILE_3G_THROTTLING.adjustedUploadThroughputKbps,
|
||||
};
|
||||
}
|
||||
|
||||
// DevTools expects throughput in bytes per second rather than kbps
|
||||
conditions.downloadThroughput = Math.floor(conditions.downloadThroughput * 1024 / 8);
|
||||
conditions.uploadThroughput = Math.floor(conditions.uploadThroughput * 1024 / 8);
|
||||
return driver.sendCommand('Network.emulateNetworkConditions', conditions);
|
||||
}
|
||||
|
||||
function disableNetworkThrottling(driver) {
|
||||
/**
|
||||
* @param {Driver} driver
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function clearAllNetworkEmulation(driver) {
|
||||
return driver.sendCommand('Network.emulateNetworkConditions', NO_THROTTLING_METRICS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Driver} driver
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function goOffline(driver) {
|
||||
return driver.sendCommand('Network.emulateNetworkConditions', OFFLINE_METRICS);
|
||||
}
|
||||
|
||||
function enableCPUThrottling(driver) {
|
||||
return driver.sendCommand('Emulation.setCPUThrottlingRate', CPU_THROTTLE_METRICS);
|
||||
/**
|
||||
* @param {Driver} driver
|
||||
* @param {LH.ThrottlingSettings|undefined} throttlingSettings
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function enableCPUThrottling(driver, throttlingSettings) {
|
||||
const rate = throttlingSettings
|
||||
? throttlingSettings.cpuSlowdownMultiplier
|
||||
: CPU_THROTTLE_METRICS.rate;
|
||||
return driver.sendCommand('Emulation.setCPUThrottlingRate', {rate});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Driver} driver
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function disableCPUThrottling(driver) {
|
||||
return driver.sendCommand('Emulation.setCPUThrottlingRate', NO_CPU_THROTTLE_METRICS);
|
||||
}
|
||||
|
||||
function getEmulationDesc() {
|
||||
const {latency, downloadThroughput, uploadThroughput} = TYPICAL_MOBILE_THROTTLING_METRICS;
|
||||
const byteToMbit = bytes => (bytes / 1024 / 1024 * 8).toFixed(1);
|
||||
/**
|
||||
* @param {LH.ConfigSettings} settings
|
||||
* @return {{deviceEmulation: string, cpuThrottling: string, networkThrottling: string}}
|
||||
*/
|
||||
function getEmulationDesc(settings) {
|
||||
let cpuThrottling;
|
||||
let networkThrottling;
|
||||
|
||||
/** @type {LH.ThrottlingSettings} */
|
||||
const throttling = settings.throttling || {};
|
||||
|
||||
switch (settings.throttlingMethod) {
|
||||
case 'provided':
|
||||
cpuThrottling = 'Provided by environment';
|
||||
networkThrottling = 'Provided by environment';
|
||||
break;
|
||||
case 'devtools': {
|
||||
const {cpuSlowdownMultiplier, requestLatencyMs} = throttling;
|
||||
cpuThrottling = `${cpuSlowdownMultiplier}x slowdown (DevTools)`;
|
||||
networkThrottling = `${requestLatencyMs}${NBSP}ms HTTP RTT, ` +
|
||||
`${throttling.downloadThroughputKbps}${NBSP}Kbps down, ` +
|
||||
`${throttling.uploadThroughputKbps}${NBSP}Kbps up (DevTools)`;
|
||||
break;
|
||||
}
|
||||
case 'simulate': {
|
||||
const {cpuSlowdownMultiplier, rttMs, throughputKbps} = throttling;
|
||||
cpuThrottling = `${cpuSlowdownMultiplier}x slowdown (Simulated)`;
|
||||
networkThrottling = `${rttMs}${NBSP}ms TCP RTT, ` +
|
||||
`${throughputKbps}${NBSP}Kbps throughput (Simulated)`;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
cpuThrottling = 'Unknown';
|
||||
networkThrottling = 'Unknown';
|
||||
}
|
||||
|
||||
return {
|
||||
'deviceEmulation': 'Nexus 5X',
|
||||
'cpuThrottling': `${CPU_THROTTLE_METRICS.rate}x slowdown`,
|
||||
'networkThrottling': `${latency}ms RTT, ${byteToMbit(downloadThroughput)}Mbps down, ` +
|
||||
`${byteToMbit(uploadThroughput)}Mbps up`,
|
||||
deviceEmulation: settings.disableDeviceEmulation ? 'Disabled' : 'Nexus 5X',
|
||||
cpuThrottling,
|
||||
networkThrottling,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
enableNexus5X,
|
||||
enableNetworkThrottling,
|
||||
disableNetworkThrottling,
|
||||
clearAllNetworkEmulation,
|
||||
enableCPUThrottling,
|
||||
disableCPUThrottling,
|
||||
goOffline,
|
||||
|
@ -160,7 +213,7 @@ module.exports = {
|
|||
settings: {
|
||||
NEXUS5X_EMULATION_METRICS,
|
||||
NEXUS5X_USERAGENT,
|
||||
TYPICAL_MOBILE_THROTTLING_METRICS,
|
||||
MOBILE_3G_THROTTLING,
|
||||
OFFLINE_METRICS,
|
||||
NO_THROTTLING_METRICS,
|
||||
NO_CPU_THROTTLE_METRICS,
|
||||
|
|
|
@ -82,12 +82,11 @@ sentryDelegate.init = function init(opts) {
|
|||
);
|
||||
}
|
||||
|
||||
const context = {
|
||||
const context = Object.assign({
|
||||
url: opts.url,
|
||||
deviceEmulation: !opts.flags.disableDeviceEmulation,
|
||||
networkThrottling: !opts.flags.disableNetworkThrottling,
|
||||
cpuThrottling: !opts.flags.disableCpuThrottling,
|
||||
};
|
||||
throttlingMethod: opts.flags.throttlingMethod,
|
||||
}, opts.flags.throttling);
|
||||
|
||||
sentryDelegate.mergeContext({extra: Object.assign({}, environmentData.extra, context)});
|
||||
return context;
|
||||
|
|
|
@ -69,8 +69,6 @@ class ReportRenderer {
|
|||
const item = this._dom.cloneTemplate('#tmpl-lh-env__items', env);
|
||||
this._dom.find('.lh-env__name', item).textContent = runtime.name;
|
||||
this._dom.find('.lh-env__description', item).textContent = runtime.description;
|
||||
this._dom.find('.lh-env__enabled', item).textContent =
|
||||
runtime.enabled ? 'Enabled' : 'Disabled';
|
||||
env.appendChild(item);
|
||||
});
|
||||
|
||||
|
|
|
@ -338,9 +338,8 @@
|
|||
</li>
|
||||
<template id="tmpl-lh-env__items">
|
||||
<li class="lh-env__item">
|
||||
<span class="lh-env__name"><!-- fill me --></span>
|
||||
<span class="lh-env__description"><!-- fill me --></span>:
|
||||
<b class="lh-env__enabled"><!-- fill me --></b>
|
||||
<span class="lh-env__name"><!-- fill me --></span>:
|
||||
<span class="lh-env__description"><!-- fill me --></span>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
|
|
|
@ -389,21 +389,18 @@ class Runner {
|
|||
* @return {!Object} runtime config
|
||||
*/
|
||||
static getRuntimeConfig(settings) {
|
||||
const emulationDesc = emulation.getEmulationDesc();
|
||||
const emulationDesc = emulation.getEmulationDesc(settings);
|
||||
const environment = [
|
||||
{
|
||||
name: 'Device Emulation',
|
||||
enabled: !settings.disableDeviceEmulation,
|
||||
description: emulationDesc['deviceEmulation'],
|
||||
},
|
||||
{
|
||||
name: 'Network Throttling',
|
||||
enabled: !settings.disableNetworkThrottling,
|
||||
description: emulationDesc['networkThrottling'],
|
||||
},
|
||||
{
|
||||
name: 'CPU Throttling',
|
||||
enabled: !settings.disableCpuThrottling,
|
||||
description: emulationDesc['cpuThrottling'],
|
||||
},
|
||||
];
|
||||
|
|
|
@ -79,10 +79,13 @@ connection.sendCommand = function(command, params) {
|
|||
case 'Network.getResponseBody':
|
||||
return new Promise(res => setTimeout(res, MAX_WAIT_FOR_PROTOCOL + 20));
|
||||
case 'Page.enable':
|
||||
case 'Network.enable':
|
||||
case 'Tracing.start':
|
||||
case 'ServiceWorker.enable':
|
||||
case 'ServiceWorker.disable':
|
||||
case 'Network.setExtraHTTPHeaders':
|
||||
case 'Network.emulateNetworkConditions':
|
||||
case 'Emulation.setCPUThrottlingRate':
|
||||
return Promise.resolve({});
|
||||
case 'Tracing.end':
|
||||
return Promise.reject(new Error('tracing not started'));
|
||||
|
@ -401,4 +404,88 @@ describe('Multiple tab check', () => {
|
|||
|
||||
return driverStub.assertNoSameOriginServiceWorkerClients(pageUrl);
|
||||
});
|
||||
|
||||
describe('.goOnline', () => {
|
||||
it('re-establishes previous throttling settings', async () => {
|
||||
await driverStub.goOnline({
|
||||
passConfig: {useThrottling: true},
|
||||
settings: {
|
||||
throttlingMethod: 'devtools',
|
||||
throttling: {
|
||||
requestLatencyMs: 500,
|
||||
downloadThroughputKbps: 1000,
|
||||
uploadThroughputKbps: 1000,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const emulateCommand = sendCommandParams
|
||||
.find(item => item.command === 'Network.emulateNetworkConditions');
|
||||
assert.ok(emulateCommand, 'did not call emulate network');
|
||||
assert.deepStrictEqual(emulateCommand.params, {
|
||||
offline: false,
|
||||
latency: 500,
|
||||
downloadThroughput: 1000 * 1024 / 8,
|
||||
uploadThroughput: 1000 * 1024 / 8,
|
||||
});
|
||||
});
|
||||
|
||||
it('clears network emulation when throttling is not devtools', async () => {
|
||||
await driverStub.goOnline({
|
||||
passConfig: {useThrottling: true},
|
||||
settings: {
|
||||
throttlingMethod: 'provided',
|
||||
},
|
||||
});
|
||||
|
||||
const emulateCommand = sendCommandParams
|
||||
.find(item => item.command === 'Network.emulateNetworkConditions');
|
||||
assert.ok(emulateCommand, 'did not call emulate network');
|
||||
assert.deepStrictEqual(emulateCommand.params, {
|
||||
offline: false,
|
||||
latency: 0,
|
||||
downloadThroughput: 0,
|
||||
uploadThroughput: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it('clears network emulation when useThrottling is false', async () => {
|
||||
await driverStub.goOnline({
|
||||
passConfig: {useThrottling: false},
|
||||
settings: {
|
||||
throttlingMethod: 'devtools',
|
||||
throttling: {
|
||||
requestLatencyMs: 500,
|
||||
downloadThroughputKbps: 1000,
|
||||
uploadThroughputKbps: 1000,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const emulateCommand = sendCommandParams
|
||||
.find(item => item.command === 'Network.emulateNetworkConditions');
|
||||
assert.ok(emulateCommand, 'did not call emulate network');
|
||||
assert.deepStrictEqual(emulateCommand.params, {
|
||||
offline: false,
|
||||
latency: 0,
|
||||
downloadThroughput: 0,
|
||||
uploadThroughput: 0,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('.goOffline', () => {
|
||||
it('should send offline emulation', async () => {
|
||||
await driverStub.goOffline();
|
||||
const emulateCommand = sendCommandParams
|
||||
.find(item => item.command === 'Network.emulateNetworkConditions');
|
||||
assert.ok(emulateCommand, 'did not call emulate network');
|
||||
assert.deepStrictEqual(emulateCommand.params, {
|
||||
offline: true,
|
||||
latency: 0,
|
||||
downloadThroughput: 0,
|
||||
uploadThroughput: 0,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -134,8 +134,8 @@ describe('GatherRunner', function() {
|
|||
calledNetworkEmulation: false,
|
||||
calledCpuEmulation: false,
|
||||
};
|
||||
const createEmulationCheck = variable => () => {
|
||||
tests[variable] = true;
|
||||
const createEmulationCheck = variable => (arg) => {
|
||||
tests[variable] = arg;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
@ -148,9 +148,11 @@ describe('GatherRunner', function() {
|
|||
return GatherRunner.setupDriver(driver, {}, {
|
||||
settings: {},
|
||||
}).then(_ => {
|
||||
assert.equal(tests.calledDeviceEmulation, true);
|
||||
assert.equal(tests.calledNetworkEmulation, true);
|
||||
assert.equal(tests.calledCpuEmulation, true);
|
||||
assert.ok(tests.calledDeviceEmulation, 'did not call device emulation');
|
||||
assert.deepEqual(tests.calledNetworkEmulation, {
|
||||
latency: 0, downloadThroughput: 0, uploadThroughput: 0, offline: false,
|
||||
});
|
||||
assert.ok(!tests.calledCpuEmulation, 'called cpu emulation');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -173,6 +175,8 @@ describe('GatherRunner', function() {
|
|||
return GatherRunner.setupDriver(driver, {}, {
|
||||
settings: {
|
||||
disableDeviceEmulation: true,
|
||||
throttlingMethod: 'devtools',
|
||||
throttling: {},
|
||||
},
|
||||
}).then(_ => {
|
||||
assert.equal(tests.calledDeviceEmulation, false);
|
||||
|
@ -181,7 +185,7 @@ describe('GatherRunner', function() {
|
|||
});
|
||||
});
|
||||
|
||||
it('stops network throttling when disableNetworkThrottling flag is true', () => {
|
||||
it('stops throttling when not devtools', () => {
|
||||
const tests = {
|
||||
calledDeviceEmulation: false,
|
||||
calledNetworkEmulation: false,
|
||||
|
@ -199,18 +203,18 @@ describe('GatherRunner', function() {
|
|||
|
||||
return GatherRunner.setupDriver(driver, {}, {
|
||||
settings: {
|
||||
disableNetworkThrottling: true,
|
||||
throttlingMethod: 'provided',
|
||||
},
|
||||
}).then(_ => {
|
||||
assert.ok(tests.calledDeviceEmulation, 'called device emulation');
|
||||
assert.ok(tests.calledDeviceEmulation, 'did not call device emulation');
|
||||
assert.deepEqual(tests.calledNetworkEmulation, [{
|
||||
latency: 0, downloadThroughput: 0, uploadThroughput: 0, offline: false,
|
||||
}]);
|
||||
assert.ok(tests.calledCpuEmulation, 'called CPU emulation');
|
||||
assert.ok(!tests.calledCpuEmulation, 'called CPU emulation');
|
||||
});
|
||||
});
|
||||
|
||||
it('stops cpu throttling when disableCpuThrottling flag is true', () => {
|
||||
it('sets throttling according to settings', () => {
|
||||
const tests = {
|
||||
calledDeviceEmulation: false,
|
||||
calledNetworkEmulation: false,
|
||||
|
@ -228,11 +232,19 @@ describe('GatherRunner', function() {
|
|||
|
||||
return GatherRunner.setupDriver(driver, {}, {
|
||||
settings: {
|
||||
disableCpuThrottling: true,
|
||||
throttlingMethod: 'devtools',
|
||||
throttling: {
|
||||
requestLatencyMs: 100,
|
||||
downloadThroughputKbps: 8,
|
||||
uploadThroughputKbps: 8,
|
||||
cpuSlowdownMultiplier: 1,
|
||||
},
|
||||
},
|
||||
}).then(_ => {
|
||||
assert.ok(tests.calledDeviceEmulation, 'called device emulation');
|
||||
assert.ok(tests.calledNetworkEmulation, 'called network emulation');
|
||||
assert.ok(tests.calledDeviceEmulation, 'did not call device emulation');
|
||||
assert.deepEqual(tests.calledNetworkEmulation, [{
|
||||
latency: 100, downloadThroughput: 1024, uploadThroughput: 1024, offline: false,
|
||||
}]);
|
||||
assert.deepEqual(tests.calledCpuEmulation, [{rate: 1}]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -61,7 +61,10 @@ describe('DependencyGraph/Simulator', () => {
|
|||
const cpuNode = new CpuNode(cpuTask({duration: 200}));
|
||||
cpuNode.addDependency(rootNode);
|
||||
|
||||
const simulator = new Simulator(rootNode, {serverResponseTimeByOrigin, cpuTaskMultiplier: 5});
|
||||
const simulator = new Simulator(rootNode, {
|
||||
serverResponseTimeByOrigin,
|
||||
cpuSlowdownMultiplier: 5,
|
||||
});
|
||||
const result = simulator.simulate();
|
||||
// should be 2 RTTs and 500ms for the server response time + 200 CPU
|
||||
assert.equal(result.timeInMs, 300 + 500 + 200);
|
||||
|
@ -99,7 +102,10 @@ describe('DependencyGraph/Simulator', () => {
|
|||
nodeA.addDependent(nodeC);
|
||||
nodeA.addDependent(nodeD);
|
||||
|
||||
const simulator = new Simulator(nodeA, {serverResponseTimeByOrigin, cpuTaskMultiplier: 5});
|
||||
const simulator = new Simulator(nodeA, {
|
||||
serverResponseTimeByOrigin,
|
||||
cpuSlowdownMultiplier: 5,
|
||||
});
|
||||
const result = simulator.simulate();
|
||||
// should be 800ms A, then 1000 ms total for B, C, D in serial
|
||||
assert.equal(result.timeInMs, 1800);
|
||||
|
@ -123,7 +129,10 @@ describe('DependencyGraph/Simulator', () => {
|
|||
nodeC.addDependent(nodeD);
|
||||
nodeC.addDependent(nodeF); // finishes 400 ms after D
|
||||
|
||||
const simulator = new Simulator(nodeA, {serverResponseTimeByOrigin, cpuTaskMultiplier: 5});
|
||||
const simulator = new Simulator(nodeA, {
|
||||
serverResponseTimeByOrigin,
|
||||
cpuSlowdownMultiplier: 5,
|
||||
});
|
||||
const result = simulator.simulate();
|
||||
// should be 800ms each for A, B, C, D, with F finishing 400 ms after D
|
||||
assert.equal(result.timeInMs, 3600);
|
||||
|
|
|
@ -105,11 +105,9 @@ describe('ReportRenderer V2', () => {
|
|||
assert.equal(userAgent.textContent, sampleResults.userAgent, 'user agent populated');
|
||||
|
||||
// Check runtime settings were populated.
|
||||
const enables = header.querySelectorAll('.lh-env__enabled');
|
||||
const names = Array.from(header.querySelectorAll('.lh-env__name')).slice(1);
|
||||
const descriptions = header.querySelectorAll('.lh-env__description');
|
||||
sampleResults.runtimeConfig.environment.forEach((env, i) => {
|
||||
assert.equal(enables[i].textContent, env.enabled ? 'Enabled' : 'Disabled');
|
||||
assert.equal(names[i].textContent, env.name);
|
||||
assert.equal(descriptions[i].textContent, env.description);
|
||||
});
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
"lighthouse-cli/**/*.js",
|
||||
"lighthouse-core/audits/audit.js",
|
||||
"lighthouse-core/lib/dependency-graph/**/*.js",
|
||||
"lighthouse-core/lib/emulation.js",
|
||||
"lighthouse-core/gather/connections/**/*.js",
|
||||
"lighthouse-core/gather/gatherers/gatherer.js",
|
||||
"lighthouse-core/scripts/*.js",
|
||||
|
|
|
@ -10,6 +10,18 @@ declare global {
|
|||
module LH {
|
||||
export import Crdp = _Crdp;
|
||||
|
||||
interface ThrottlingSettings {
|
||||
// simulation settings
|
||||
rttMs?: number;
|
||||
throughputKbps?: number;
|
||||
// devtools settings
|
||||
requestLatencyMs?: number;
|
||||
downloadThroughputKbps?: number;
|
||||
uploadThroughputKbps?: number;
|
||||
// used by both
|
||||
cpuSlowdownMultiplier?: number
|
||||
}
|
||||
|
||||
interface SharedFlagsSettings {
|
||||
maxWaitForLoad?: number;
|
||||
blockedUrlPatterns?: string[];
|
||||
|
@ -18,8 +30,8 @@ declare global {
|
|||
gatherMode?: boolean | string;
|
||||
disableStorageReset?: boolean;
|
||||
disableDeviceEmulation?: boolean;
|
||||
disableCpuThrottling?: boolean;
|
||||
disableNetworkThrottling?: boolean;
|
||||
throttlingMethod?: 'devtools'|'simulate'|'provided';
|
||||
throttling?: ThrottlingSettings;
|
||||
onlyAudits?: string[];
|
||||
onlyCategories?: string[];
|
||||
skipAudits?: string[];
|
||||
|
|
Загрузка…
Ссылка в новой задаче