moebius#93: DevTools: Network - DOMContentLoaded and load

Issue #31
Improvements: #34
https://github.com/MoonchildProductions/moebius/pull/93
This commit is contained in:
janekptacijarabaci 2018-03-03 17:44:55 +01:00 • committed by Roy Tam
commit ed8a17ae7d
12 changed files with 132 additions and 4 deletions

View file

@ -150,6 +150,11 @@ networkMenu.empty=No requests
# #2 is the size, #3 is the transferred size, #4 is the number of seconds. # #2 is the size, #3 is the transferred size, #4 is the number of seconds.
networkMenu.summary2=One request, #2 KB (transferred: #3 KB), #4 s;#1 requests, #2 KB (transferred: #3 KB), #4 s networkMenu.summary2=One request, #2 KB (transferred: #3 KB), #4 s;#1 requests, #2 KB (transferred: #3 KB), #4 s
# LOCALIZATION NOTE (networkMenu.timeS): This is the label displayed
# in the network table footer providing concise information about all requests.
# Events DOMContentLoaded and load - specifying the number of seconds.
networkMenu.timeS=%S s
# LOCALIZATION NOTE (networkMenu.sizeB): This is the label displayed # LOCALIZATION NOTE (networkMenu.sizeB): This is the label displayed
# in the network menu specifying the size of a request (in bytes). # in the network menu specifying the size of a request (in bytes).
networkMenu.sizeB=%S B networkMenu.sizeB=%S B

View file

@ -5,6 +5,7 @@
const filters = require("./filters"); const filters = require("./filters");
const requests = require("./requests"); const requests = require("./requests");
const timingMarkers = require("./timing-markers");
const ui = require("./ui"); const ui = require("./ui");
module.exports = Object.assign({}, filters, requests, ui); module.exports = Object.assign({}, filters, requests, timingMarkers, ui);

View file

@ -7,5 +7,6 @@ DevToolsModules(
'filters.js', 'filters.js',
'index.js', 'index.js',
'requests.js', 'requests.js',
'timing-markers.js',
'ui.js', 'ui.js',
) )

View file

@ -0,0 +1,19 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { ADD_TIMING_MARKER, CLEAR_TIMING_MARKERS } = require("../constants");
exports.addTimingMarker = (marker) => {
return {
type: ADD_TIMING_MARKER,
marker
};
};
exports.clearTimingMarkers = () => {
return {
type: CLEAR_TIMING_MARKERS
};
};

View file

@ -15,16 +15,22 @@ const { connect } = require("devtools/client/shared/vendor/react-redux");
const { PluralForm } = require("devtools/shared/plural-form"); const { PluralForm } = require("devtools/shared/plural-form");
const { L10N } = require("../l10n"); const { L10N } = require("../l10n");
const { const {
getDisplayedRequestsSummary getDisplayedRequestsSummary,
getDisplayedTimingMarker
} = require("../selectors/index"); } = require("../selectors/index");
const { button, span } = DOM; const { button, span } = DOM;
function SummaryButton({ function SummaryButton({
summary, summary,
triggerSummary triggerSummary,
timingMarkers
}) { }) {
let { count, contentSize, transferredSize, millis } = summary; let { count, contentSize, transferredSize, millis } = summary;
let {
DOMContentLoaded,
load,
} = timingMarkers;
const text = (count === 0) ? L10N.getStr("networkMenu.empty") : const text = (count === 0) ? L10N.getStr("networkMenu.empty") :
PluralForm.get(count, L10N.getStr("networkMenu.summary2")) PluralForm.get(count, L10N.getStr("networkMenu.summary2"))
.replace("#1", count) .replace("#1", count)
@ -33,7 +39,13 @@ function SummaryButton({
.replace("#3", L10N.numberWithDecimals(transferredSize / 1024, .replace("#3", L10N.numberWithDecimals(transferredSize / 1024,
CONTENT_SIZE_DECIMALS)) CONTENT_SIZE_DECIMALS))
.replace("#4", L10N.numberWithDecimals(millis / 1000, .replace("#4", L10N.numberWithDecimals(millis / 1000,
REQUEST_TIME_DECIMALS)); REQUEST_TIME_DECIMALS))
+ ((DOMContentLoaded > -1)
? ", " + "DOMContentLoaded: " + L10N.getFormatStrWithNumbers("networkMenu.timeS", L10N.numberWithDecimals(DOMContentLoaded / 1000, REQUEST_TIME_DECIMALS))
: "")
+ ((load > -1)
? ", " + "load: " + L10N.getFormatStrWithNumbers("networkMenu.timeS", L10N.numberWithDecimals(load / 1000, REQUEST_TIME_DECIMALS))
: "");
return button({ return button({
id: "requests-menu-network-summary-button", id: "requests-menu-network-summary-button",
@ -47,11 +59,17 @@ function SummaryButton({
SummaryButton.propTypes = { SummaryButton.propTypes = {
summary: PropTypes.object.isRequired, summary: PropTypes.object.isRequired,
timingMarkers: PropTypes.object.isRequired,
}; };
module.exports = connect( module.exports = connect(
(state) => ({ (state) => ({
summary: getDisplayedRequestsSummary(state), summary: getDisplayedRequestsSummary(state),
timingMarkers: {
DOMContentLoaded:
getDisplayedTimingMarker(state, "firstDocumentDOMContentLoadedTimestamp"),
load: getDisplayedTimingMarker(state, "firstDocumentLoadTimestamp"),
},
}), }),
(dispatch) => ({ (dispatch) => ({
triggerSummary: () => { triggerSummary: () => {

View file

@ -10,6 +10,8 @@ const general = {
}; };
const actionTypes = { const actionTypes = {
ADD_TIMING_MARKER: "ADD_TIMING_MARKER",
CLEAR_TIMING_MARKERS: "CLEAR_TIMING_MARKERS",
TOGGLE_FILTER_TYPE: "TOGGLE_FILTER_TYPE", TOGGLE_FILTER_TYPE: "TOGGLE_FILTER_TYPE",
ENABLE_FILTER_TYPE_ONLY: "ENABLE_FILTER_TYPE_ONLY", ENABLE_FILTER_TYPE_ONLY: "ENABLE_FILTER_TYPE_ONLY",
SET_FILTER_TEXT: "SET_FILTER_TEXT", SET_FILTER_TEXT: "SET_FILTER_TEXT",

View file

@ -414,6 +414,7 @@ TargetEventsHandler.prototype = {
} }
// Clear any accumulated markers. // Clear any accumulated markers.
NetMonitorController.NetworkEventsHandler.clearMarkers(); NetMonitorController.NetworkEventsHandler.clearMarkers();
gStore.dispatch(Actions.clearTimingMarkers());
window.emit(EVENTS.TARGET_WILL_NAVIGATE); window.emit(EVENTS.TARGET_WILL_NAVIGATE);
break; break;
@ -534,6 +535,7 @@ NetworkEventsHandler.prototype = {
_onDocLoadingMarker: function (marker) { _onDocLoadingMarker: function (marker) {
window.emit(EVENTS.TIMELINE_EVENT, marker); window.emit(EVENTS.TIMELINE_EVENT, marker);
this._markers.push(marker); this._markers.push(marker);
gStore.dispatch(Actions.addTimingMarker(marker));
}, },
/** /**

View file

@ -6,10 +6,12 @@
const { combineReducers } = require("devtools/client/shared/vendor/redux"); const { combineReducers } = require("devtools/client/shared/vendor/redux");
const filters = require("./filters"); const filters = require("./filters");
const requests = require("./requests"); const requests = require("./requests");
const timingMarkers = require("./timing-markers");
const ui = require("./ui"); const ui = require("./ui");
module.exports = combineReducers({ module.exports = combineReducers({
filters, filters,
requests, requests,
timingMarkers,
ui, ui,
}); });

View file

@ -7,5 +7,6 @@ DevToolsModules(
'filters.js', 'filters.js',
'index.js', 'index.js',
'requests.js', 'requests.js',
'timing-markers.js',
'ui.js', 'ui.js',
) )

View file

@ -0,0 +1,52 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const I = require("devtools/client/shared/vendor/immutable");
const { ADD_TIMING_MARKER,
CLEAR_TIMING_MARKERS } = require("../constants");
const TimingMarkers = I.Record({
firstDocumentDOMContentLoadedTimestamp: -1,
firstDocumentLoadTimestamp: -1,
});
function addTimingMarker(state, action) {
if (action.marker.name == "document::DOMContentLoaded" &&
state.firstDocumentDOMContentLoadedTimestamp == -1) {
return state.set("firstDocumentDOMContentLoadedTimestamp",
action.marker.unixTime / 1000);
}
if (action.marker.name == "document::Load" &&
state.firstDocumentLoadTimestamp == -1) {
return state.set("firstDocumentLoadTimestamp",
action.marker.unixTime / 1000);
}
return state;
}
function clearTimingMarkers(state) {
return state.withMutations(st => {
st.remove("firstDocumentDOMContentLoadedTimestamp");
st.remove("firstDocumentLoadTimestamp");
});
}
function timingMarkers(state = new TimingMarkers(), action) {
switch (action.type) {
case ADD_TIMING_MARKER:
return addTimingMarker(state, action);
case CLEAR_TIMING_MARKERS:
return clearTimingMarkers(state);
default:
return state;
}
}
module.exports = timingMarkers;

View file

@ -275,6 +275,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
this._addQueue = []; this._addQueue = [];
this._updateQueue = []; this._updateQueue = [];
this._firstRequestStartedMillis = -1; this._firstRequestStartedMillis = -1;
this._firstRequestStartedMillisInRequests = false;
this._lastRequestEndedMillis = -1; this._lastRequestEndedMillis = -1;
}, },
@ -650,6 +651,9 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
// Append a network request item to this container. // Append a network request item to this container.
let requestItem = this.push([menuView, id], { let requestItem = this.push([menuView, id], {
attachment: { attachment: {
firstRequestStartedMillis: this._firstRequestStartedMillisInRequests
? null
: this._firstRequestStartedMillis,
startedDeltaMillis: unixTime - this._firstRequestStartedMillis, startedDeltaMillis: unixTime - this._firstRequestStartedMillis,
startedMillis: unixTime, startedMillis: unixTime,
method: method, method: method,
@ -661,6 +665,8 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
} }
}); });
this._firstRequestStartedMillisInRequests = true;
if (id == this._preferredItemId) { if (id == this._preferredItemId) {
this.selectedItem = requestItem; this.selectedItem = requestItem;
} }
@ -1563,6 +1569,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
_ctx: null, _ctx: null,
_cachedWaterfallWidth: 0, _cachedWaterfallWidth: 0,
_firstRequestStartedMillis: -1, _firstRequestStartedMillis: -1,
_firstRequestStartedMillisInRequests: false,
_lastRequestEndedMillis: -1, _lastRequestEndedMillis: -1,
_updateQueue: [], _updateQueue: [],
_addQueue: [], _addQueue: [],

View file

@ -73,6 +73,24 @@ const getDisplayedRequestsSummary = createSelector(
}) })
); );
function getDisplayedTimingMarker(state, marker) {
let timingMarker = null;
if (state.timingMarkers) {
timingMarker = state.timingMarkers.get(marker);
}
let firstRequestStartedMillis = null;
if (state.requests.items.length) {
firstRequestStartedMillis = state.requests.items[0]
.attachment.firstRequestStartedMillis;
}
if (timingMarker && firstRequestStartedMillis) {
return timingMarker - firstRequestStartedMillis;
} else {
return -1;
}
}
module.exports = { module.exports = {
getDisplayedRequestsSummary, getDisplayedRequestsSummary,
getDisplayedTimingMarker,
}; };