Bug 685900 - csshtmltree.refreshPanel should use a setTimeout loop to improve performance (cancel-able); r=msucan
authorMichael Ratcliffe <mratcliffe@mozilla.com>
Wed, 19 Oct 2011 12:25:39 +0200
changeset 79009 a67521de22d58740095ba8babfa2c7ac6f821c3f
parent 79008 f9644e6e81d5cb0c316379ff86a20d76e5683ae1
child 79010 a0abf1681c3d671d13afdeded3f5b6981ff39548
push id241
push userrcampbell@mozilla.com
push dateThu, 20 Oct 2011 21:22:24 +0000
treeherderfx-team@a67521de22d5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmsucan
bugs685900
milestone10.0a1
Bug 685900 - csshtmltree.refreshPanel should use a setTimeout loop to improve performance (cancel-able); r=msucan
browser/devtools/styleinspector/CssHtmlTree.jsm
browser/devtools/styleinspector/test/browser/browser_styleinspector_bug_672744_search_filter.js
browser/devtools/styleinspector/test/browser/browser_styleinspector_bug_672746_default_styles.js
--- a/browser/devtools/styleinspector/CssHtmlTree.jsm
+++ b/browser/devtools/styleinspector/CssHtmlTree.jsm
@@ -62,17 +62,17 @@ var EXPORTED_SYMBOLS = ["CssHtmlTree", "
  */
 function CssHtmlTree(aStyleWin, aCssLogic, aPanel)
 {
   this.styleWin = aStyleWin;
   this.cssLogic = aCssLogic;
   this.doc = aPanel.ownerDocument;
   this.win = this.doc.defaultView;
   this.getRTLAttr = CssHtmlTree.getRTLAttr;
-  this.propertyViews = {};
+  this.propertyViews = [];
 
   // The document in which we display the results (csshtmltree.xhtml).
   this.styleDocument = this.styleWin.contentWindow.document;
 
   // Nodes used in templating
   this.root = this.styleDocument.getElementById("root");
   this.path = this.styleDocument.getElementById("path");
   this.templateRoot = this.styleDocument.getElementById("templateRoot");
@@ -157,16 +157,19 @@ CssHtmlTree.prototype = {
   filterChangedTimeout: null,
 
   // The search filter
   searchField: null,
   
   // Reference to the "Only user Styles" checkbox.
   onlyUserStylesCheckbox: null,
 
+  // Holds the ID of the panelRefresh timeout.
+  _panelRefreshTimeout: null,
+
   get showOnlyUserStyles()
   {
     return this.onlyUserStylesCheckbox.checked;
   },
 
   /**
    * Update the highlighted element. The CssHtmlTree panel will show the style
    * information for the given element.
@@ -197,17 +200,17 @@ CssHtmlTree.prototype = {
           // Display the next 15 properties
           for (let step = i + batchSize; i < step && i <= max; i++) {
             let name = CssHtmlTree.propertyNames[i];
             let propView = new PropertyView(this, name);
             CssHtmlTree.processTemplate(this.templateProperty,
               this.propertyContainer, propView, true);
             propView.refreshMatchedSelectors();
             propView.refreshUnmatchedSelectors();
-            this.propertyViews[name] = propView;
+            this.propertyViews.push(propView);
           }
           if (i < max) {
             // There are still some properties to display. We loop here to display
             // the next batch of 15.
             this.win.setTimeout(displayProperties.bind(this), 50);
           } else {
             this.htmlComplete = true;
             Services.obs.notifyObservers(null, "StyleInspector-populated", null);
@@ -218,20 +221,37 @@ CssHtmlTree.prototype = {
     }
   },
 
   /**
    * Refresh the panel content.
    */
   refreshPanel: function CssHtmlTree_refreshPanel()
   {
-    for each(let propView in this.propertyViews) {
-      propView.refresh();
+    this.win.clearTimeout(this._panelRefreshTimeout);
+
+    // We use a setTimeout loop to display the properties in batches of 15 at a
+    // time. This results in a perceptibly more responsive UI.
+    let i = 0;
+    let batchSize = 15;
+    let max = this.propertyViews.length - 1;
+    function refreshView() {
+      // Refresh the next 15 property views
+      for (let step = i + batchSize; i < step && i <= max; i++) {
+        this.propertyViews[i].refresh();
+      }
+      if (i < max) {
+        // There are still some property views to refresh. We loop here to
+        // display the next batch of 15.
+        this._panelRefreshTimeout = this.win.setTimeout(refreshView.bind(this), 0);
+      } else {
+        Services.obs.notifyObservers(null, "StyleInspector-populated", null);
+      }
     }
-    Services.obs.notifyObservers(null, "StyleInspector-populated", null);
+    this._panelRefreshTimeout = this.win.setTimeout(refreshView.bind(this), 0);
   },
 
   /**
    * Called when the user clicks on a parent element in the "current element"
    * path.
    *
    * @param {Event} aEvent the DOM Event object.
    */
--- a/browser/devtools/styleinspector/test/browser/browser_styleinspector_bug_672744_search_filter.js
+++ b/browser/devtools/styleinspector/test/browser/browser_styleinspector_bug_672744_search_filter.js
@@ -74,21 +74,21 @@ function SI_AddFilterText()
 }
 
 function SI_checkFilter()
 {
   Services.obs.removeObserver(SI_checkFilter, "StyleInspector-populated", false);
   let propertyViews = stylePanel.cssHtmlTree.propertyViews;
 
   info("check that the correct properties are visible");
-  for each(let propView in propertyViews) {
+  propertyViews.forEach(function(propView) {
     let name = propView.name;
     is(propView.visible, name.indexOf("color") > -1,
       "span " + name + " property visibility check");
-  }
+  });
 
   Services.obs.addObserver(finishUp, "StyleInspector-closed", false);
   stylePanel.hidePopup();
 }
 
 function finishUp()
 {
   Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
--- a/browser/devtools/styleinspector/test/browser/browser_styleinspector_bug_672746_default_styles.js
+++ b/browser/devtools/styleinspector/test/browser/browser_styleinspector_bug_672746_default_styles.js
@@ -75,18 +75,23 @@ function SI_checkDefaultStyles()
       "span background-color property is visible");
 
   Services.obs.addObserver(finishUp, "StyleInspector-closed", false);
   stylePanel.hidePopup();
 }
 
 function propertyVisible(aName)
 {
+  info("Checking property visibility for " + aName);
   let propertyViews = stylePanel.cssHtmlTree.propertyViews;
-  return propertyViews[aName].className == "property-view";
+  for each (let propView in propertyViews) {
+    if (propView.name == aName) {
+      return propView.className == "property-view";
+    }
+  }
 }
 
 function finishUp()
 {
   Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
   ok(!stylePanel.isOpen(), "style inspector is closed");
   doc = stylePanel = null;
   gBrowser.removeCurrentTab();