core(config): switch to throttling settings object (#4879)

This commit is contained in:
Patrick Hulce 2018-03-29 16:10:59 -07:00 коммит произвёл GitHub
Родитель 2200c7851e
Коммит 467453d2c1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
16 изменённых файлов: 281 добавлений и 107 удалений

Просмотреть файл

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

16
typings/externs.d.ts поставляемый
Просмотреть файл

@ -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[];