browsertime
Version:
Get performance metrics from your web page using Browsertime.
110 lines (96 loc) • 2.93 kB
JavaScript
import intel from 'intel';
import get from 'lodash.get';
const log = intel.getLogger('browsertime.chrome.network');
export class NetworkManager {
constructor(bidi, browsingContextIds, options) {
this.bidi = bidi;
this.browsingContextIds = browsingContextIds;
this.maxTimeout = get(options, 'timeouts.pageCompleteCheck', 30_000);
this.idleTime = get(options, 'timeouts.networkIdle', 5000);
}
async waitForNetworkIdle() {
await this.bidi.subscribe(
'network.beforeRequestSent',
this.browsingContextIds
);
await this.bidi.subscribe(
'network.responseCompleted',
this.browsingContextIds
);
await this.bidi.subscribe('network.fetchError', this.browsingContextIds);
let inflight = 0;
let lastRequestTimestamp;
let lastResponseTimestamp;
this.ws = await this.bidi.socket;
this.ws.on('message', function (event) {
const { method } = JSON.parse(Buffer.from(event.toString()));
if (method) {
switch (method) {
case 'network.beforeRequestSent': {
inflight++;
lastRequestTimestamp = Date.now();
break;
}
case 'network.responseCompleted': {
inflight--;
lastResponseTimestamp = Date.now();
break;
}
case 'network.fetchError': {
inflight--;
lastResponseTimestamp = Date.now();
break;
}
// No default
}
}
});
const startTime = Date.now();
while (true) {
const now = Date.now();
const sinceLastResponseRequest =
now - Math.max(lastResponseTimestamp, lastRequestTimestamp);
const sinceStart = now - startTime;
if (sinceLastResponseRequest >= this.idleTime) {
if (inflight > 0) {
log.info(
'Idle time without any request/responses. Inflight requests:' +
inflight
);
}
await this.bidi.unsubscribe(
'network.beforeRequestSent',
this.browsingContextIds
);
await this.bidi.unsubscribe(
'network.responseCompleted',
this.browsingContextIds
);
await this.bidi.unsubscribe(
'network.fetchError',
this.browsingContextIds
);
break;
}
if (sinceStart >= this.maxTimeout) {
log.info(
'Timeout waiting for network idle. Inflight requests:' + inflight
);
await this.bidi.unsubscribe(
'network.beforeRequestSent',
this.browsingContextIds
);
await this.bidi.unsubscribe(
'network.responseCompleted',
this.browsingContextIds
);
await this.bidi.unsubscribe(
'network.fetchError',
this.browsingContextIds
);
break;
}
await new Promise(r => setTimeout(r, 200));
}
}
}