Changeset 128043 in webkit


Ignore:
Timestamp:
Sep 10, 2012 4:09:50 AM (12 years ago)
Author:
apavlov@chromium.org
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
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r128042 r128043  
     12012-09-10  Alexander Pavlov  <apavlov@chromium.org>
     2
     3        Web Inspector: [Elements] Poor performance upon continuous attribute changes
     4        https://bugs.webkit.org/show_bug.cgi?id=96252
     5
     6        Reviewed by Vsevolod Vlasov.
     7
     8        The DOM tree is now updated after a non-zero timeout, and same node updates are coalesced rather than added into an array
     9        as many times as the DOM node has been tampered with during the update interval.
     10
     11        * inspector/front-end/ElementsTreeOutline.js:
     12        * inspector/front-end/utilities.js: Implement Map.prototype.size
     13
    1142012-09-10  Mike West  <mkwst@chromium.org>
    215
  • trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js

    r127449 r128043  
    20012001
    20022002    this._treeOutline = treeOutline;
    2003     this._recentlyModifiedNodes = [];
     2003    this._recentlyModifiedNodes = new Map();
    20042004}
    20052005
    20062006WebInspector.ElementsTreeUpdater.prototype = {
    2007     _documentUpdated: function(event)
    2008     {
    2009         var inspectedRootDocument = event.data;
    2010 
    2011         this._reset();
    2012 
    2013         if (!inspectedRootDocument)
    2014             return;
    2015 
    2016         this._treeOutline.rootDOMNode = inspectedRootDocument;
    2017     },
    2018 
    2019     _attributesUpdated: function(event)
    2020     {
    2021         this._recentlyModifiedNodes.push({node: event.data.node, updated: true});
     2007
     2008    /**
     2009     * @param {!WebInspector.DOMNode} node
     2010     * @param {boolean} isUpdated
     2011     * @param {WebInspector.DOMNode=} parentNode
     2012     */
     2013    _nodeModified: function(node, isUpdated, parentNode)
     2014    {
    20222015        if (this._treeOutline._visible)
    20232016            this._updateModifiedNodesSoon();
     2017
     2018        var entry = /** @type {WebInspector.ElementsTreeUpdater.UpdateEntry} */ this._recentlyModifiedNodes.get(node);
     2019        if (!entry) {
     2020            entry = new WebInspector.ElementsTreeUpdater.UpdateEntry(isUpdated, parentNode);
     2021            this._recentlyModifiedNodes.put(node, entry);
     2022            return;
     2023        }
     2024
     2025        entry.isUpdated |= isUpdated;
     2026        if (parentNode)
     2027            entry.parent = parentNode;
     2028    },
     2029
     2030    _documentUpdated: function(event)
     2031    {
     2032        var inspectedRootDocument = event.data;
     2033
     2034        this._reset();
     2035
     2036        if (!inspectedRootDocument)
     2037            return;
     2038
     2039        this._treeOutline.rootDOMNode = inspectedRootDocument;
     2040    },
     2041
     2042    _attributesUpdated: function(event)
     2043    {
     2044        this._nodeModified(event.data.node, true);
    20242045    },
    20252046
    20262047    _characterDataModified: function(event)
    20272048    {
    2028         this._recentlyModifiedNodes.push({node: event.data, updated: true});
    2029         if (this._treeOutline._visible)
    2030             this._updateModifiedNodesSoon();
     2049        this._nodeModified(event.data, true);
    20312050    },
    20322051
    20332052    _nodeInserted: function(event)
    20342053    {
    2035         this._recentlyModifiedNodes.push({node: event.data, parent: event.data.parentNode, inserted: true});
    2036         if (this._treeOutline._visible)
    2037             this._updateModifiedNodesSoon();
     2054        this._nodeModified(event.data, false, event.data.parentNode);
    20382055    },
    20392056
    20402057    _nodeRemoved: function(event)
    20412058    {
    2042         this._recentlyModifiedNodes.push({node: event.data.node, parent: event.data.parent, removed: true});
    2043         if (this._treeOutline._visible)
    2044             this._updateModifiedNodesSoon();
     2059        this._nodeModified(event.data.node, false, event.data.parent);
    20452060    },
    20462061
     
    20562071        if (this._updateModifiedNodesTimeout)
    20572072            return;
    2058         this._updateModifiedNodesTimeout = setTimeout(this._updateModifiedNodes.bind(this), 0);
     2073        this._updateModifiedNodesTimeout = setTimeout(this._updateModifiedNodes.bind(this), 50);
    20592074    },
    20602075
     
    20682083        var updatedParentTreeElements = [];
    20692084
    2070         var hidePanelWhileUpdating = this._recentlyModifiedNodes.length > 10;
     2085        var hidePanelWhileUpdating = this._recentlyModifiedNodes.size() > 10;
    20712086        if (hidePanelWhileUpdating) {
    20722087            var treeOutlineContainerElement = this._treeOutline.element.parentNode;
     
    20752090        }
    20762091
    2077         for (var i = 0; i < this._recentlyModifiedNodes.length; ++i) {
    2078             var parent = this._recentlyModifiedNodes[i].parent;
     2092        var keys = this._recentlyModifiedNodes.keys();
     2093        for (var i = 0, size = keys.length; i < size; ++i) {
     2094            var node = keys[i];
     2095            var entry = this._recentlyModifiedNodes.get(node);
     2096            var parent = entry.parent;
    20792097
    20802098            if (parent === this._treeOutline._rootDOMNode) {
     
    20852103            }
    20862104
    2087             var node = this._recentlyModifiedNodes[i].node;
    2088 
    2089             if (this._recentlyModifiedNodes[i].updated) {
     2105            if (entry.isUpdated) {
    20902106                var nodeItem = this._treeOutline.findTreeElement(node);
    20912107                if (nodeItem)
    20922108                    nodeItem.updateTitle();
    2093                 continue;
    20942109            }
    20952110
     
    21142129            this._treeOutline.updateSelection();
    21152130        }
    2116         this._recentlyModifiedNodes = [];
     2131        this._recentlyModifiedNodes.clear();
    21172132    },
    21182133
     
    21222137        this._treeOutline.selectDOMNode(null, false);
    21232138        WebInspector.domAgent.hideDOMNodeHighlight();
    2124         this._recentlyModifiedNodes = [];
     2139        this._recentlyModifiedNodes.clear();
    21252140    }
    21262141}
     2142
     2143/**
     2144 * @constructor
     2145 * @param {boolean} isUpdated
     2146 * @param {WebInspector.DOMNode=} parent
     2147 */
     2148WebInspector.ElementsTreeUpdater.UpdateEntry = function(isUpdated, parent)
     2149{
     2150    this.isUpdated = isUpdated;
     2151    if (parent)
     2152        this.parent = parent;
     2153}
  • trunk/Source/WebCore/inspector/front-end/utilities.js

    r126572 r128043  
    685685{
    686686    this._map = {};
     687    this._size = 0;
    687688}
    688689
     
    700701            key.__identifier = objectIdentifier;
    701702        }
     703        if (!this._map[objectIdentifier])
     704            ++this._size;
    702705        this._map[objectIdentifier] = [key, value];
    703706    },
     
    710713        var result = this._map[key.__identifier];
    711714        delete this._map[key.__identifier];
     715        --this._size;
    712716        return result ? result[1] : undefined;
    713717    },
     
    731735    _list: function(index)
    732736    {
    733         var result = [];
     737        var result = new Array(this._size);
     738        var i = 0;
    734739        for (var objectIdentifier in this._map)
    735             result.push(this._map[objectIdentifier][index]);
     740            result[i++] = this._map[objectIdentifier][index];
    736741        return result;
    737742    },
     
    745750        return entry ? entry[1] : undefined;
    746751    },
    747    
     752
     753    size: function()
     754    {
     755        return this._size;
     756    },
     757
    748758    clear: function()
    749759    {
    750760        this._map = {};
     761        this._size = 0;
    751762    }
    752763}
Note: See TracChangeset for help on using the changeset viewer.