Title: [128043] trunk/Source/WebCore
Revision
128043
Author
[email protected]
Date
2012-09-10 04:09:50 -0700 (Mon, 10 Sep 2012)

Log Message

Web Inspector: [Elements] Poor performance upon continuous attribute changes
https://bugs.webkit.org/show_bug.cgi?id=96252

Reviewed by Vsevolod Vlasov.

The DOM tree is now updated after a non-zero timeout, and same node updates are coalesced rather than added into an array
as many times as the DOM node has been tampered with during the update interval.

* inspector/front-end/ElementsTreeOutline.js:
* inspector/front-end/utilities.js: Implement Map.prototype.size

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (128042 => 128043)


--- trunk/Source/WebCore/ChangeLog	2012-09-10 11:07:45 UTC (rev 128042)
+++ trunk/Source/WebCore/ChangeLog	2012-09-10 11:09:50 UTC (rev 128043)
@@ -1,3 +1,16 @@
+2012-09-10  Alexander Pavlov  <[email protected]>
+
+        Web Inspector: [Elements] Poor performance upon continuous attribute changes
+        https://bugs.webkit.org/show_bug.cgi?id=96252
+
+        Reviewed by Vsevolod Vlasov.
+
+        The DOM tree is now updated after a non-zero timeout, and same node updates are coalesced rather than added into an array
+        as many times as the DOM node has been tampered with during the update interval.
+
+        * inspector/front-end/ElementsTreeOutline.js:
+        * inspector/front-end/utilities.js: Implement Map.prototype.size
+
 2012-09-10  Mike West  <[email protected]>
 
         Warn authors about CSP directives ignored due to non-ASCII values.

Modified: trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js (128042 => 128043)


--- trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js	2012-09-10 11:07:45 UTC (rev 128042)
+++ trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js	2012-09-10 11:09:50 UTC (rev 128043)
@@ -2000,10 +2000,33 @@
     WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.ChildNodeCountUpdated, this._childNodeCountUpdated, this);
 
     this._treeOutline = treeOutline;
-    this._recentlyModifiedNodes = [];
+    this._recentlyModifiedNodes = new Map();
 }
 
 WebInspector.ElementsTreeUpdater.prototype = {
+
+    /**
+     * @param {!WebInspector.DOMNode} node
+     * @param {boolean} isUpdated
+     * @param {WebInspector.DOMNode=} parentNode
+     */
+    _nodeModified: function(node, isUpdated, parentNode)
+    {
+        if (this._treeOutline._visible)
+            this._updateModifiedNodesSoon();
+
+        var entry = /** @type {WebInspector.ElementsTreeUpdater.UpdateEntry} */ this._recentlyModifiedNodes.get(node);
+        if (!entry) {
+            entry = new WebInspector.ElementsTreeUpdater.UpdateEntry(isUpdated, parentNode);
+            this._recentlyModifiedNodes.put(node, entry);
+            return;
+        }
+
+        entry.isUpdated |= isUpdated;
+        if (parentNode)
+            entry.parent = parentNode;
+    },
+
     _documentUpdated: function(event)
     {
         var inspectedRootDocument = event.data;
@@ -2018,30 +2041,22 @@
 
     _attributesUpdated: function(event)
     {
-        this._recentlyModifiedNodes.push({node: event.data.node, updated: true});
-        if (this._treeOutline._visible)
-            this._updateModifiedNodesSoon();
+        this._nodeModified(event.data.node, true);
     },
 
     _characterDataModified: function(event)
     {
-        this._recentlyModifiedNodes.push({node: event.data, updated: true});
-        if (this._treeOutline._visible)
-            this._updateModifiedNodesSoon();
+        this._nodeModified(event.data, true);
     },
 
     _nodeInserted: function(event)
     {
-        this._recentlyModifiedNodes.push({node: event.data, parent: event.data.parentNode, inserted: true});
-        if (this._treeOutline._visible)
-            this._updateModifiedNodesSoon();
+        this._nodeModified(event.data, false, event.data.parentNode);
     },
 
     _nodeRemoved: function(event)
     {
-        this._recentlyModifiedNodes.push({node: event.data.node, parent: event.data.parent, removed: true});
-        if (this._treeOutline._visible)
-            this._updateModifiedNodesSoon();
+        this._nodeModified(event.data.node, false, event.data.parent);
     },
 
     _childNodeCountUpdated: function(event)
@@ -2055,7 +2070,7 @@
     {
         if (this._updateModifiedNodesTimeout)
             return;
-        this._updateModifiedNodesTimeout = setTimeout(this._updateModifiedNodes.bind(this), 0);
+        this._updateModifiedNodesTimeout = setTimeout(this._updateModifiedNodes.bind(this), 50);
     },
 
     _updateModifiedNodes: function()
@@ -2067,15 +2082,18 @@
 
         var updatedParentTreeElements = [];
 
-        var hidePanelWhileUpdating = this._recentlyModifiedNodes.length > 10;
+        var hidePanelWhileUpdating = this._recentlyModifiedNodes.size() > 10;
         if (hidePanelWhileUpdating) {
             var treeOutlineContainerElement = this._treeOutline.element.parentNode;
             this._treeOutline.element.addStyleClass("hidden");
             var originalScrollTop = treeOutlineContainerElement ? treeOutlineContainerElement.scrollTop : 0;
         }
 
-        for (var i = 0; i < this._recentlyModifiedNodes.length; ++i) {
-            var parent = this._recentlyModifiedNodes[i].parent;
+        var keys = this._recentlyModifiedNodes.keys();
+        for (var i = 0, size = keys.length; i < size; ++i) {
+            var node = keys[i];
+            var entry = this._recentlyModifiedNodes.get(node);
+            var parent = entry.parent;
 
             if (parent === this._treeOutline._rootDOMNode) {
                 // Document's children have changed, perform total update.
@@ -2084,13 +2102,10 @@
                 return;
             }
 
-            var node = this._recentlyModifiedNodes[i].node;
-
-            if (this._recentlyModifiedNodes[i].updated) {
+            if (entry.isUpdated) {
                 var nodeItem = this._treeOutline.findTreeElement(node);
                 if (nodeItem)
                     nodeItem.updateTitle();
-                continue;
             }
 
             if (!parent)
@@ -2113,7 +2128,7 @@
                 treeOutlineContainerElement.scrollTop = originalScrollTop;
             this._treeOutline.updateSelection();
         }
-        this._recentlyModifiedNodes = [];
+        this._recentlyModifiedNodes.clear();
     },
 
     _reset: function()
@@ -2121,6 +2136,18 @@
         this._treeOutline.rootDOMNode = null;
         this._treeOutline.selectDOMNode(null, false);
         WebInspector.domAgent.hideDOMNodeHighlight();
-        this._recentlyModifiedNodes = [];
+        this._recentlyModifiedNodes.clear();
     }
 }
+
+/**
+ * @constructor
+ * @param {boolean} isUpdated
+ * @param {WebInspector.DOMNode=} parent
+ */
+WebInspector.ElementsTreeUpdater.UpdateEntry = function(isUpdated, parent)
+{
+    this.isUpdated = isUpdated;
+    if (parent)
+        this.parent = parent;
+}

Modified: trunk/Source/WebCore/inspector/front-end/utilities.js (128042 => 128043)


--- trunk/Source/WebCore/inspector/front-end/utilities.js	2012-09-10 11:07:45 UTC (rev 128042)
+++ trunk/Source/WebCore/inspector/front-end/utilities.js	2012-09-10 11:09:50 UTC (rev 128043)
@@ -684,6 +684,7 @@
 var Map = function()
 {
     this._map = {};
+    this._size = 0;
 }
 
 Map._lastObjectIdentifier = 0;
@@ -699,6 +700,8 @@
             objectIdentifier = ++Map._lastObjectIdentifier;
             key.__identifier = objectIdentifier;
         }
+        if (!this._map[objectIdentifier])
+            ++this._size;
         this._map[objectIdentifier] = [key, value];
     },
     
@@ -709,6 +712,7 @@
     {
         var result = this._map[key.__identifier];
         delete this._map[key.__identifier];
+        --this._size;
         return result ? result[1] : undefined;
     },
 
@@ -730,9 +734,10 @@
      */
     _list: function(index)
     {
-        var result = [];
+        var result = new Array(this._size);
+        var i = 0;
         for (var objectIdentifier in this._map)
-            result.push(this._map[objectIdentifier][index]);
+            result[i++] = this._map[objectIdentifier][index];
         return result;
     },
 
@@ -744,10 +749,16 @@
         var entry = this._map[key.__identifier];
         return entry ? entry[1] : undefined;
     },
-    
+
+    size: function()
+    {
+        return this._size;
+    },
+
     clear: function()
     {
         this._map = {};
+        this._size = 0;
     }
 }
 /**
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to