Bug 1434855 - Improve performance of HAR export; r=ochameau
MozReview-Commit-ID: 6H6P6wYmdQL
--- a/browser/components/extensions/test/browser/browser_ext_devtools_network.js
+++ b/browser/components/extensions/test/browser/browser_ext_devtools_network.js
@@ -175,16 +175,18 @@ add_task(async function test_devtools_ne
extension.sendMessage("navigate");
// Wait till the navigation is complete and request
// added into the net panel.
await Promise.all([
extension.awaitMessage("tabUpdated"),
extension.awaitMessage("onNavigatedFired"),
extension.awaitMessage("onRequestFinished"),
+ extension.awaitMessage("onRequestFinished-callbackExecuted"),
+ extension.awaitMessage("onRequestFinished-promiseResolved"),
waitForRequestAdded(toolbox),
]);
// Get HAR, it should not be empty now.
const getHARPromise = extension.awaitMessage("getHAR-result");
extension.sendMessage("getHAR");
const getHARResult = await getHARPromise;
is(getHARResult.log.entries.length, 1, "HAR log should not be empty");
--- a/devtools/client/netmonitor/src/connector/chrome-connector.js
+++ b/devtools/client/netmonitor/src/connector/chrome-connector.js
@@ -38,16 +38,20 @@ class ChromeConnector {
pause() {
this.disconnect();
}
resume() {
this.setup();
}
+ enableActions(enable) {
+ // TODO : implement.
+ }
+
/**
* currently all events are about "navigation" is not support on CDP
*/
willNavigate() {
this.actions.batchReset();
this.actions.clearRequests();
}
--- a/devtools/client/netmonitor/src/connector/firefox-connector.js
+++ b/devtools/client/netmonitor/src/connector/firefox-connector.js
@@ -122,16 +122,20 @@ class FirefoxConnector {
}
if (this.webConsoleClient) {
this.webConsoleClient.off("networkEvent");
this.webConsoleClient.off("networkEventUpdate");
this.webConsoleClient.off("docEvent");
}
}
+ enableActions(enable) {
+ this.dataProvider.enableActions(enable);
+ }
+
willNavigate() {
if (!Services.prefs.getBoolPref("devtools.netmonitor.persistlog")) {
this.actions.batchReset();
this.actions.clearRequests();
} else {
// If the log is persistent, just clear all accumulated timing markers.
this.actions.clearTimingMarkers();
}
--- a/devtools/client/netmonitor/src/connector/firefox-data-provider.js
+++ b/devtools/client/netmonitor/src/connector/firefox-data-provider.js
@@ -17,16 +17,17 @@ const { fetchHeaders } = require("../uti
* so it's possible to determine whether all has been fetched
* or not.
*/
class FirefoxDataProvider {
constructor({webConsoleClient, actions}) {
// Options
this.webConsoleClient = webConsoleClient;
this.actions = actions;
+ this.actionsEnabled = true;
// Internal properties
this.payloadQueue = new Map();
// Map[key string => Promise] used by `requestData` to prevent requesting the same
// request data twice.
this.lazyRequestData = new Map();
@@ -34,33 +35,42 @@ class FirefoxDataProvider {
this.getLongString = this.getLongString.bind(this);
// Event handlers
this.onNetworkEvent = this.onNetworkEvent.bind(this);
this.onNetworkEventUpdate = this.onNetworkEventUpdate.bind(this);
}
/**
+ * Enable/disable firing redux actions (enabled by default).
+ *
+ * @param {boolean} enable Set to true to fire actions.
+ */
+ enableActions(enable) {
+ this.actionsEnabled = enable;
+ }
+
+ /**
* Add a new network request to application state.
*
* @param {string} id request id
* @param {object} data data payload will be added to application state
*/
async addRequest(id, data) {
let {
method,
url,
isXHR,
cause,
startedDateTime,
fromCache,
fromServiceWorker,
} = data;
- if (this.actions.addRequest) {
+ if (this.actionsEnabled && this.actions.addRequest) {
await this.actions.addRequest(id, {
// Convert the received date/time string to a unix timestamp.
startedMillis: Date.parse(startedDateTime),
method,
url,
isXHR,
cause,
@@ -115,17 +125,17 @@ class FirefoxDataProvider {
responseContentObj,
requestHeadersObj,
responseHeadersObj,
postDataObj,
requestCookiesObj,
responseCookiesObj
);
- if (this.actions.updateRequest) {
+ if (this.actionsEnabled && this.actions.updateRequest) {
await this.actions.updateRequest(id, payload, true);
}
return payload;
}
async fetchResponseContent(responseContent) {
let payload = {};
@@ -372,17 +382,17 @@ class FirefoxDataProvider {
if (!payload.requestHeadersAvailable || !payload.requestCookiesAvailable ||
!payload.eventTimingsAvailable || !payload.responseContentAvailable) {
return;
}
this.payloadQueue.delete(actor);
- if (this.actions.updateRequest) {
+ if (this.actionsEnabled && this.actions.updateRequest) {
await this.actions.updateRequest(actor, payload, true);
}
// This event is fired only once per request, once all the properties are fetched
// from `onNetworkEventUpdate`. There should be no more RDP requests after this.
emit(EVENTS.PAYLOAD_READY, actor);
}
@@ -409,17 +419,17 @@ class FirefoxDataProvider {
return promise;
}
// Fetch the data
promise = this._requestData(actor, method).then(async (payload) => {
// Remove the request from the cache, any new call to requestData will fetch the
// data again.
this.lazyRequestData.delete(key);
- if (this.actions.updateRequest) {
+ if (this.actionsEnabled && this.actions.updateRequest) {
await this.actions.updateRequest(actor, {
...payload,
// Lockdown *Available property once we fetch data from back-end.
// Using this as a flag to prevent fetching arrived data again.
[`${method}Available`]: false,
}, true);
}
--- a/devtools/client/netmonitor/src/connector/index.js
+++ b/devtools/client/netmonitor/src/connector/index.js
@@ -66,16 +66,20 @@ class Connector {
pause() {
return this.connector.pause();
}
resume() {
return this.connector.resume();
}
+ enableActions() {
+ this.connector.enableActions(...arguments);
+ }
+
// Public API
getLongString() {
return this.connector.getLongString(...arguments);
}
getNetworkRequest() {
return this.connector.getNetworkRequest(...arguments);
--- a/devtools/client/netmonitor/src/har/har-exporter.js
+++ b/devtools/client/netmonitor/src/har/har-exporter.js
@@ -190,28 +190,34 @@ const HarExporter = {
let { connector } = options;
let {
getTabTarget,
} = connector;
let {
form: { title, url }
} = getTabTarget();
+ // Disconnect from redux actions/store.
+ connector.enableActions(false);
+
options = {
...options,
title: title || url,
getString: connector.getLongString,
getTimingMarker: connector.getTimingMarker,
requestData: connector.requestData,
};
// Build HAR object from collected data.
let builder = new HarBuilder(options);
let result = await builder.build();
+ // Connect to redux actions again.
+ connector.enableActions(true);
+
return result;
},
/**
* Build JSON string from the HAR data object.
*/
stringify: function (har) {
if (!har) {