Bug 1333004 - Selecting the details panel request is slow r?honza draft
authorRicky Chien <rchien@mozilla.com>
Wed, 25 Jan 2017 15:40:30 +0800
changeset 467043 b14e7595fc5f416264bb974f507df92d7903b30c
parent 467034 e6823d84f347588e90e32e0d23f4a5ca3f85e2b6
child 543614 947d7b1152a49a7ea2a27d4024de6da5ff0accac
push id43098
push userbmo:rchien@mozilla.com
push dateFri, 27 Jan 2017 03:39:48 +0000
reviewershonza
bugs1333004
milestone54.0a1
Bug 1333004 - Selecting the details panel request is slow r?honza MozReview-Commit-ID: 43EoGR6IZGo
devtools/client/netmonitor/shared/components/details-panel.js
devtools/client/netmonitor/shared/components/editor.js
devtools/client/netmonitor/test/browser_net_security-tab-visibility.js
devtools/client/shared/components/tabs/tabbar.js
devtools/client/shared/components/tabs/tabs.js
--- a/devtools/client/netmonitor/shared/components/details-panel.js
+++ b/devtools/client/netmonitor/shared/components/details-panel.js
@@ -47,16 +47,17 @@ function DetailsPanel({
   if (!request) {
     return null;
   }
 
   return (
     Tabbar({
       activeTabId,
       onSelect: selectTab,
+      renderOnlySelected: true,
       showAllTabsMenu: true,
       toolbox,
     },
       TabPanel({
         id: "headers",
         title: HEADERS_TITLE,
       },
         HeadersPanel({ request, cloneSelectedRequest }),
--- a/devtools/client/netmonitor/shared/components/editor.js
+++ b/devtools/client/netmonitor/shared/components/editor.js
@@ -5,16 +5,17 @@
 /* eslint-disable react/prop-types */
 
 "use strict";
 
 const { createClass, DOM, PropTypes } = require("devtools/client/shared/vendor/react");
 const SourceEditor = require("devtools/client/sourceeditor/editor");
 
 const { div } = DOM;
+const SYNTAX_HIGHLIGHT_MAX_SIZE = 102400;
 
 /**
  * CodeMirror editor as a React component
  */
 const Editor = createClass({
   displayName: "Editor",
 
   propTypes: {
@@ -34,32 +35,32 @@ const Editor = createClass({
     };
   },
 
   componentDidMount() {
     const { mode, text } = this.props;
 
     this.editor = new SourceEditor({
       lineNumbers: true,
-      mode,
+      mode: text.length < SYNTAX_HIGHLIGHT_MAX_SIZE ? mode : null,
       readOnly: true,
       value: text,
     });
 
     this.deferEditor = this.editor.appendTo(this.refs.editorElement);
   },
 
   componentDidUpdate(prevProps) {
     const { mode, open, text } = this.props;
 
     if (!open) {
       return;
     }
 
-    if (prevProps.mode !== mode) {
+    if (prevProps.mode !== mode && text.length < SYNTAX_HIGHLIGHT_MAX_SIZE) {
       this.deferEditor.then(() => {
         this.editor.setMode(mode);
       });
     }
 
     if (prevProps.text !== text) {
       this.deferEditor.then(() => {
         // FIXME: Workaround for browser_net_accessibility test to
--- a/devtools/client/netmonitor/test/browser_net_security-tab-visibility.js
+++ b/devtools/client/netmonitor/test/browser_net_security-tab-visibility.js
@@ -56,41 +56,32 @@ add_task(function* () {
     info("Selecting the request.");
     RequestsMenu.selectedIndex = 0;
 
     is(RequestsMenu.selectedItem.securityState, undefined,
        "Security state has not yet arrived.");
     is(!!document.querySelector("#security-tab"), testcase.visibleOnNewEvent,
       "Security tab is " + (testcase.visibleOnNewEvent ? "visible" : "hidden") +
       " after new request was added to the menu.");
-    is(!!document.querySelector("#security-panel"), testcase.visibleOnNewEvent,
-      "Security panel is " + (testcase.visibleOnNewEvent ? "visible" : "hidden") +
-      " after new request was added to the menu.");
 
     info("Waiting for security information to arrive.");
     yield onSecurityInfo;
 
     ok(RequestsMenu.selectedItem.securityState,
        "Security state arrived.");
     is(!!document.querySelector("#security-tab"), testcase.visibleOnSecurityInfo,
        "Security tab is " + (testcase.visibleOnSecurityInfo ? "visible" : "hidden") +
        " after security information arrived.");
-    is(!!document.querySelector("#security-panel"), testcase.visibleOnSecurityInfo,
-      "Security panel is " + (testcase.visibleOnSecurityInfo? "visible" : "hidden") +
-      " after security information arrived.");
 
     info("Waiting for request to complete.");
     yield onComplete;
 
     is(!!document.querySelector("#security-tab"), testcase.visibleOnceComplete,
        "Security tab is " + (testcase.visibleOnceComplete ? "visible" : "hidden") +
        " after request has been completed.");
-    is(!!document.querySelector("#security-panel"), testcase.visibleOnceComplete,
-      "Security panel is " + (testcase.visibleOnceComplete? "visible" : "hidden") +
-      " after request has been completed.");
 
     info("Clearing requests.");
     RequestsMenu.clear();
   }
 
   return teardown(monitor);
 
   /**
--- a/devtools/client/shared/components/tabs/tabbar.js
+++ b/devtools/client/shared/components/tabs/tabbar.js
@@ -22,16 +22,17 @@ let Tabbar = createClass({
   displayName: "Tabbar",
 
   propTypes: {
     children: PropTypes.object,
     onSelect: PropTypes.func,
     showAllTabsMenu: PropTypes.bool,
     activeTabId: PropTypes.string,
     toolbox: PropTypes.object,
+    renderOnlySelected: PropTypes.bool,
   },
 
   getDefaultProps: function () {
     return {
       showAllTabsMenu: false,
     };
   },
 
@@ -216,16 +217,17 @@ let Tabbar = createClass({
 
   render: function () {
     let tabs = this.state.tabs.map((tab) => this.renderTab(tab));
 
     return (
       div({className: "devtools-sidebar-tabs"},
         Tabs({
           onAllTabsMenuClick: this.onAllTabsMenuClick,
+          renderOnlySelected: this.props.renderOnlySelected,
           showAllTabsMenu: this.props.showAllTabsMenu,
           tabActive: this.state.activeTab,
           onAfterChange: this.onTabChanged,
         },
           tabs
         )
       )
     );
--- a/devtools/client/shared/components/tabs/tabs.js
+++ b/devtools/client/shared/components/tabs/tabs.js
@@ -45,22 +45,28 @@ define(function (require, exports, modul
       onBeforeChange: React.PropTypes.func,
       onAfterChange: React.PropTypes.func,
       children: React.PropTypes.oneOfType([
         React.PropTypes.array,
         React.PropTypes.element
       ]).isRequired,
       showAllTabsMenu: React.PropTypes.bool,
       onAllTabsMenuClick: React.PropTypes.func,
+
+      // Set true will only render selected panel on DOM. It's complete
+      // opposite of the created array, and it's useful if panels content
+      // is unpredictable and update frequently.
+      renderOnlySelected: React.PropTypes.bool,
     },
 
     getDefaultProps: function () {
       return {
         tabActive: 0,
         showAllTabsMenu: false,
+        renderOnlySelected: false,
       };
     },
 
     getInitialState: function () {
       return {
         tabActive: this.props.tabActive,
 
         // This array is used to store an information whether a tab
@@ -281,31 +287,37 @@ define(function (require, exports, modul
             tabs
           ),
           allTabsMenu
         )
       );
     },
 
     renderPanels: function () {
-      if (!this.props.children) {
+      let { children, renderOnlySelected } = this.props;
+
+      if (!children) {
         throw new Error("There must be at least one Tab");
       }
 
-      if (!Array.isArray(this.props.children)) {
-        this.props.children = [this.props.children];
+      if (!Array.isArray(children)) {
+        children = [children];
       }
 
       let selectedIndex = this.state.tabActive;
 
-      let panels = this.props.children
+      let panels = children
         .map((tab) => typeof tab === "function" ? tab() : tab)
         .filter((tab) => tab)
         .map((tab, index) => {
           let selected = selectedIndex === index;
+          if (renderOnlySelected && !selected) {
+            return null;
+          }
+
           let id = tab.props.id;
 
           // Use 'visibility:hidden' + 'width/height:0' for hiding
           // content of non-selected tab. It's faster (not sure why)
           // than display:none and visibility:collapse.
           let style = {
             visibility: selected ? "visible" : "hidden",
             height: selected ? "100%" : "0",