Bug 1580431 - Start time, end time relative to first request in the Timings Panel. r=Honza.
authorRuturaj Vartak <ruturaj@gmail.com>
Tue, 26 Nov 2019 08:23:47 +0000
changeset 503810 afe9af7c0dd5a993b42cfcc15e1e5b4c3c2c3830
parent 503809 5004f4181ad73cf46c2bc05dcee7274b2c05d758
child 503811 9816255bcde6bf3f24f4294852f9580e2af0dd74
push id101557
push userjodvarko@mozilla.com
push dateTue, 26 Nov 2019 08:24:17 +0000
treeherderautoland@afe9af7c0dd5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersHonza
bugs1580431
milestone72.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1580431 - Start time, end time relative to first request in the Timings Panel. r=Honza. Differential Revision: https://phabricator.services.mozilla.com/D54297
devtools/client/locales/en-US/netmonitor.properties
devtools/client/netmonitor/src/assets/styles/NetworkDetailsPanel.css
devtools/client/netmonitor/src/components/TimingsPanel.js
--- a/devtools/client/locales/en-US/netmonitor.properties
+++ b/devtools/client/locales/en-US/netmonitor.properties
@@ -319,16 +319,28 @@ netmonitor.waterfall.tooltip.receive=Rec
 # section in Timings side panel. This section contains request timings.
 netmonitor.timings.requestTiming=Request Timing
 
 # LOCALIZATION NOTE (netmonitor.timings.serverTiming): This is the title of a new section
 # in Timings side panel. This section contains server timings transferred from the server
 # through the "Server-Timing" header.
 netmonitor.timings.serverTiming=Server Timing
 
+# LOCALIZATION NOTE (netmonitor.timings.queuedAt): This is relative queued time to the
+# first request
+netmonitor.timings.queuedAt=Queued: %S
+
+# LOCALIZATION NOTE (netmonitor.timings.startedAt): Related to first request,
+# when the request actually started
+netmonitor.timings.startedAt=Started: %S
+
+# LOCALIZATION NOTE (netmonitor.timings.downloadedAt): Related to first request,
+# when the request actually finished downloading
+netmonitor.timings.downloadedAt=Downloaded: %S
+
 # LOCALIZATION NOTE (networkMenu.millisecond): This is the label displayed
 # in the network menu specifying timing interval divisions (in milliseconds).
 networkMenu.millisecond=%S ms
 
 # LOCALIZATION NOTE (networkMenu.second): This is the label displayed
 # in the network menu specifying timing interval divisions (in seconds).
 networkMenu.second=%S s
 
--- a/devtools/client/netmonitor/src/assets/styles/NetworkDetailsPanel.css
+++ b/devtools/client/netmonitor/src/assets/styles/NetworkDetailsPanel.css
@@ -407,16 +407,35 @@
 }
 
 /* Timings tabpanel */
 
 .network-monitor .timings-container {
   display: flex;
 }
 
+.network-monitor .timings-overview {
+  display: flex;
+  border-bottom: 1px solid var(--theme-splitter-color);
+  padding: 4px;
+}
+
+.network-monitor .timings-overview-item {
+  display: inline-flex;
+}
+
+.network-monitor .timings-overview-item:not(:first-of-type)::before {
+  content: "";
+  display: inline-flex;
+  margin-inline-end: 10px;
+  margin-inline-start: 10px;
+  width: 1px;
+  background: var(--theme-splitter-color);
+}
+
 .network-monitor .timings-label {
   width: 10em;
 }
 
 .network-monitor .requests-list-timings-container {
   display: flex;
   flex: 1;
   align-items: center;
--- a/devtools/client/netmonitor/src/components/TimingsPanel.js
+++ b/devtools/client/netmonitor/src/components/TimingsPanel.js
@@ -1,14 +1,17 @@
 /* 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 {
+  connect,
+} = require("devtools/client/shared/redux/visibility-handler-connect");
 const { Component } = require("devtools/client/shared/vendor/react");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
 const { L10N } = require("../utils/l10n");
 const { getNetMonitorTimingsURL } = require("../utils/mdn-utils");
 const { fetchNetworkUpdatePacket } = require("../utils/request-utils");
 const { getFormattedTime } = require("../utils/format-utils");
 const { TIMING_KEYS } = require("../constants");
@@ -24,16 +27,17 @@ const TIMINGS_END_PADDING = "80px";
  * Timings panel component
  * Display timeline bars that shows the total wait time for various stages
  */
 class TimingsPanel extends Component {
   static get propTypes() {
     return {
       connector: PropTypes.object.isRequired,
       request: PropTypes.object.isRequired,
+      firstRequestStartedMs: PropTypes.number.isRequired,
     };
   }
 
   componentDidMount() {
     const { connector, request } = this.props;
     fetchNetworkUpdatePacket(connector.requestData, request, ["eventTimings"]);
   }
 
@@ -89,23 +93,28 @@ class TimingsPanel extends Component {
             )
           )
         );
       })
     );
   }
 
   render() {
-    const { eventTimings, totalTime } = this.props.request;
+    const { eventTimings, totalTime, startedMs } = this.props.request;
+    const { firstRequestStartedMs } = this.props;
 
     if (!eventTimings) {
       return null;
     }
 
     const { timings, offsets } = eventTimings;
+    const queuedAt = startedMs - firstRequestStartedMs;
+    const startedAt = queuedAt + timings.blocked;
+    const downloadedAt = queuedAt + totalTime;
+
     const timelines = TIMING_KEYS.map((type, idx) => {
       // Determine the relative offset for each timings box. For example, the
       // offset of third timings box will be 0 + blocked offset + dns offset
       // If offsets sent from the backend aren't available calculate it
       // from the timing info.
       const offset = offsets
         ? offsets[type]
         : TIMING_KEYS.slice(0, idx).reduce(
@@ -146,22 +155,48 @@ class TimingsPanel extends Component {
           )
         )
       );
     });
 
     return div(
       { className: "panel-container" },
       div(
+        { className: "timings-overview" },
+        span(
+          { className: "timings-overview-item" },
+          L10N.getFormatStr(
+            "netmonitor.timings.queuedAt",
+            getFormattedTime(queuedAt)
+          )
+        ),
+        span(
+          { className: "timings-overview-item" },
+          L10N.getFormatStr(
+            "netmonitor.timings.startedAt",
+            getFormattedTime(startedAt)
+          )
+        ),
+        span(
+          { className: "timings-overview-item" },
+          L10N.getFormatStr(
+            "netmonitor.timings.downloadedAt",
+            getFormattedTime(downloadedAt)
+          )
+        )
+      ),
+      div(
         { className: "label-separator" },
         L10N.getStr("netmonitor.timings.requestTiming")
       ),
       timelines,
       this.renderServerTimings(),
       MDNLink({
         url: getNetMonitorTimingsURL(),
         title: L10N.getStr("netmonitor.timings.learnMore"),
       })
     );
   }
 }
 
-module.exports = TimingsPanel;
+module.exports = connect(state => ({
+  firstRequestStartedMs: state.requests.firstStartedMs,
+}))(TimingsPanel);