Changeset 142161 in webkit


Ignore:
Timestamp:
Feb 7, 2013 12:02:39 PM (11 years ago)
Author:
vivek.vg@samsung.com
Message:

Web Inspector: CPU pegged when inspecting LocalStorage that mutates.
https://bugs.webkit.org/show_bug.cgi?id=107937

Reviewed by Yury Semikhatsky.

The DOM storage agent will fire an event to the frontend based on the action
performed on the storage. Based on this action, the front-end will just add/update/remove
the entry in the view. This enhances the front-end responsiveness as the round trip
for fetching the storage entries has been eliminated.

Existing test: LayoutTests/inspector/storage-panel-dom-storage-update.html should verify the change

  • inspector/Inspector.json:
  • inspector/InspectorDOMStorageAgent.cpp:

(WebCore::InspectorDOMStorageAgent::didDispatchDOMStorageEvent):

  • inspector/front-end/DOMStorage.js:

(WebInspector.DOMStorageModel.prototype._domStorageItemsCleared):
(WebInspector.DOMStorageModel.prototype._domStorageItemRemoved):
(WebInspector.DOMStorageModel.prototype._domStorageItemAdded):
(WebInspector.DOMStorageModel.prototype._domStorageItemUpdated):
(WebInspector.DOMStorageDispatcher.prototype.domStorageItemsCleared):
(WebInspector.DOMStorageDispatcher.prototype.domStorageItemRemoved):
(WebInspector.DOMStorageDispatcher.prototype.domStorageItemAdded):
(WebInspector.DOMStorageDispatcher.prototype.domStorageItemUpdated):

  • inspector/front-end/DOMStorageItemsView.js:

(WebInspector.DOMStorageItemsView):
(WebInspector.DOMStorageItemsView.prototype.wasShown):
(WebInspector.DOMStorageItemsView.prototype._domStorageItemsCleared):
(WebInspector.DOMStorageItemsView.prototype._domStorageItemRemoved):
(WebInspector.DOMStorageItemsView.prototype._domStorageItemAdded):
(WebInspector.DOMStorageItemsView.prototype._domStorageItemUpdated):
(WebInspector.DOMStorageItemsView.prototype._update):
(WebInspector.DOMStorageItemsView.prototype._showDOMStorageEntries):
(WebInspector.DOMStorageItemsView.prototype._refreshButtonClicked):
(WebInspector.DOMStorageItemsView.prototype._editingCallback):
(WebInspector.DOMStorageItemsView.prototype._deleteCallback):

  • inspector/front-end/ResourcesPanel.js:

(WebInspector.ResourcesPanel):
(WebInspector.ResourcesPanel.prototype._showDOMStorage.get if):
(WebInspector.ResourcesPanel.prototype._showDOMStorage):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r142159 r142161  
     12013-02-07  Vivek Galatage  <vivek.vg@samsung.com>
     2
     3        Web Inspector: CPU pegged when inspecting LocalStorage that mutates.
     4        https://bugs.webkit.org/show_bug.cgi?id=107937
     5
     6        Reviewed by Yury Semikhatsky.
     7
     8        The DOM storage agent will fire an event to the frontend based on the action
     9        performed on the storage. Based on this action, the front-end will just add/update/remove
     10        the entry in the view. This enhances the front-end responsiveness as the round trip
     11        for fetching the storage entries has been eliminated.
     12
     13        Existing test: LayoutTests/inspector/storage-panel-dom-storage-update.html should verify the change
     14
     15        * inspector/Inspector.json:
     16        * inspector/InspectorDOMStorageAgent.cpp:
     17        (WebCore::InspectorDOMStorageAgent::didDispatchDOMStorageEvent):
     18        * inspector/front-end/DOMStorage.js:
     19        (WebInspector.DOMStorageModel.prototype._domStorageItemsCleared):
     20        (WebInspector.DOMStorageModel.prototype._domStorageItemRemoved):
     21        (WebInspector.DOMStorageModel.prototype._domStorageItemAdded):
     22        (WebInspector.DOMStorageModel.prototype._domStorageItemUpdated):
     23        (WebInspector.DOMStorageDispatcher.prototype.domStorageItemsCleared):
     24        (WebInspector.DOMStorageDispatcher.prototype.domStorageItemRemoved):
     25        (WebInspector.DOMStorageDispatcher.prototype.domStorageItemAdded):
     26        (WebInspector.DOMStorageDispatcher.prototype.domStorageItemUpdated):
     27        * inspector/front-end/DOMStorageItemsView.js:
     28        (WebInspector.DOMStorageItemsView):
     29        (WebInspector.DOMStorageItemsView.prototype.wasShown):
     30        (WebInspector.DOMStorageItemsView.prototype._domStorageItemsCleared):
     31        (WebInspector.DOMStorageItemsView.prototype._domStorageItemRemoved):
     32        (WebInspector.DOMStorageItemsView.prototype._domStorageItemAdded):
     33        (WebInspector.DOMStorageItemsView.prototype._domStorageItemUpdated):
     34        (WebInspector.DOMStorageItemsView.prototype._update):
     35        (WebInspector.DOMStorageItemsView.prototype._showDOMStorageEntries):
     36        (WebInspector.DOMStorageItemsView.prototype._refreshButtonClicked):
     37        (WebInspector.DOMStorageItemsView.prototype._editingCallback):
     38        (WebInspector.DOMStorageItemsView.prototype._deleteCallback):
     39        * inspector/front-end/ResourcesPanel.js:
     40        (WebInspector.ResourcesPanel):
     41        (WebInspector.ResourcesPanel.prototype._showDOMStorage.get if):
     42        (WebInspector.ResourcesPanel.prototype._showDOMStorage):
     43
    1442013-02-07  Dan Carney  <dcarney@google.com>
    245
  • trunk/Source/WebCore/inspector/Inspector.json

    r142144 r142161  
    838838            {
    839839                "name": "enable",
    840                 "description": "Enables console domain, sends the messages collected so far to the client by means of the <code>messageAdded</code> notification." 
     840                "description": "Enables console domain, sends the messages collected so far to the client by means of the <code>messageAdded</code> notification."
    841841            },
    842842            {
    843843                "name": "disable",
    844                 "description": "Disables console domain, prevents further console messages from being reported to the client." 
     844                "description": "Disables console domain, prevents further console messages from being reported to the client."
    845845            },
    846846            {
    847847                "name": "clearMessages",
    848                 "description": "Clears console messages collected in the browser." 
     848                "description": "Clears console messages collected in the browser."
    849849            },
    850850            {
     
    853853                    { "name": "enabled", "type": "boolean", "description": "Monitoring enabled state." }
    854854                ],
    855                 "description": "Toggles monitoring of XMLHttpRequest. If <code>true</code>, console will receive messages upon each XHR issued.", 
     855                "description": "Toggles monitoring of XMLHttpRequest. If <code>true</code>, console will receive messages upon each XHR issued.",
    856856                "hidden": true
    857857            },
     
    10941094                    { "name": "cacheDisabled", "type": "boolean", "description": "Cache disabled state." }
    10951095                ],
    1096                 "description": "Toggles ignoring cache for each request. If <code>true</code>, cache will not be used." 
     1096                "description": "Toggles ignoring cache for each request. If <code>true</code>, cache will not be used."
    10971097            }
    10981098        ],
     
    15341534            },
    15351535            {
    1536                 "name": "domStorageUpdated",
     1536                "name": "domStorageItemsCleared",
    15371537                "parameters": [
    15381538                    { "name": "storageId",  "$ref": "StorageId" }
     1539                ]
     1540            },
     1541            {
     1542                "name": "domStorageItemRemoved",
     1543                "parameters": [
     1544                    { "name": "storageId",  "$ref": "StorageId" },
     1545                    { "name": "key", "type": "string" }
     1546                ]
     1547            },
     1548            {
     1549                "name": "domStorageItemAdded",
     1550                "parameters": [
     1551                    { "name": "storageId",  "$ref": "StorageId" },
     1552                    { "name": "key", "type": "string" },
     1553                    { "name": "newValue", "type": "string" }
     1554                ]
     1555            },
     1556            {
     1557                "name": "domStorageItemUpdated",
     1558                "parameters": [
     1559                    { "name": "storageId",  "$ref": "StorageId" },
     1560                    { "name": "key", "type": "string" },
     1561                    { "name": "oldValue", "type": "string" },
     1562                    { "name": "newValue", "type": "string" }
    15391563                ]
    15401564            }
  • trunk/Source/WebCore/inspector/InspectorDOMStorageAgent.cpp

    r141690 r142161  
    11/*
    22 * Copyright (C) 2010 Google Inc. All rights reserved.
     3 * Copyright (C) 2013 Samsung Electronics. All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    223224}
    224225
    225 void InspectorDOMStorageAgent::didDispatchDOMStorageEvent(const String&, const String&, const String&, StorageType storageType, SecurityOrigin* securityOrigin, Page*)
     226void InspectorDOMStorageAgent::didDispatchDOMStorageEvent(const String& key, const String& oldValue, const String& newValue, StorageType storageType, SecurityOrigin* securityOrigin, Page*)
    226227{
    227228    if (!m_frontend || !m_enabled)
     
    233234        return;
    234235
    235     m_frontend->domstorage()->domStorageUpdated(id);
     236    if (key.isNull())
     237        m_frontend->domstorage()->domStorageItemsCleared(id);
     238    else if (newValue.isNull())
     239        m_frontend->domstorage()->domStorageItemRemoved(id, key);
     240    else if (oldValue.isNull())
     241        m_frontend->domstorage()->domStorageItemAdded(id, key, newValue);
     242    else
     243        m_frontend->domstorage()->domStorageItemUpdated(id, key, oldValue, newValue);
    236244}
    237245
  • trunk/Source/WebCore/inspector/front-end/DOMStorage.js

    r130149 r142161  
    11/*
    22 * Copyright (C) 2008 Nokia Inc.  All rights reserved.
     3 * Copyright (C) 2013 Samsung Electronics. All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    9798WebInspector.DOMStorageModel.Events = {
    9899    DOMStorageAdded: "DOMStorageAdded",
    99     DOMStorageUpdated: "DOMStorageUpdated"
     100    DOMStorageItemsCleared: "DOMStorageItemsCleared",
     101    DOMStorageItemRemoved: "DOMStorageItemRemoved",
     102    DOMStorageItemAdded: "DOMStorageItemAdded",
     103    DOMStorageItemUpdated: "DOMStorageItemUpdated"
    100104}
    101105
     
    113117     * @param {DOMStorageAgent.StorageId} storageId
    114118     */
    115     _domStorageUpdated: function(storageId)
    116     {
    117         this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageUpdated, this._storages[storageId]);
     119    _domStorageItemsCleared: function(storageId)
     120    {
     121        var domStorage = this._storages[storageId];
     122        var storageData = {
     123            storage: domStorage
     124        };
     125        this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageItemsCleared, storageData);
     126    },
     127
     128    /**
     129     * @param {DOMStorageAgent.StorageId} storageId
     130     * @param {string} key
     131     */
     132    _domStorageItemRemoved: function(storageId, key)
     133    {
     134        var domStorage = this._storages[storageId];
     135        var storageData = {
     136            storage: domStorage,
     137            key: key
     138        };
     139        this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageItemRemoved, storageData);
     140    },
     141
     142    /**
     143     * @param {DOMStorageAgent.StorageId} storageId
     144     * @param {string} key
     145     * @param {string} newValue
     146     */
     147    _domStorageItemAdded: function(storageId, key, newValue)
     148    {
     149        var domStorage = this._storages[storageId];
     150        var storageData = {
     151            storage: domStorage,
     152            key: key,
     153            newValue: newValue
     154        };
     155        this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageItemAdded, storageData);
     156    },
     157
     158    /**
     159     * @param {DOMStorageAgent.StorageId} storageId
     160     * @param {string} key
     161     * @param {string} oldValue
     162     * @param {string} newValue
     163     */
     164    _domStorageItemUpdated: function(storageId, key, oldValue, newValue)
     165    {
     166        var domStorage = this._storages[storageId];
     167        var storageData = {
     168            storage: domStorage,
     169            key: key,
     170            oldValue: oldValue,
     171            newValue: newValue
     172        };
     173        this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageItemUpdated, storageData);
    118174    },
    119175
     
    167223     * @param {string} storageId
    168224     */
    169     domStorageUpdated: function(storageId)
    170     {
    171         this._model._domStorageUpdated(storageId);
    172     }
     225    domStorageItemsCleared: function(storageId)
     226    {
     227        this._model._domStorageItemsCleared(storageId);
     228    },
     229
     230    /**
     231     * @param {string} storageId
     232     * @param {string} key
     233     */
     234    domStorageItemRemoved: function(storageId, key)
     235    {
     236        this._model._domStorageItemRemoved(storageId, key);
     237    },
     238
     239    /**
     240     * @param {string} storageId
     241     * @param {string} key
     242     * @param {string} newValue
     243     */
     244    domStorageItemAdded: function(storageId, key, newValue)
     245    {
     246        this._model._domStorageItemAdded(storageId, key, newValue);
     247    },
     248
     249    /**
     250     * @param {string} storageId
     251     * @param {string} key
     252     * @param {string} oldValue
     253     * @param {string} newValue
     254     */
     255    domStorageItemUpdated: function(storageId, key, oldValue, newValue)
     256    {
     257        this._model._domStorageItemUpdated(storageId, key, oldValue, newValue);
     258    },
    173259}
    174260
  • trunk/Source/WebCore/inspector/front-end/DOMStorageItemsView.js

    r139404 r142161  
    11/*
    22 * Copyright (C) 2008 Nokia Inc.  All rights reserved.
     3 * Copyright (C) 2013 Samsung Electronics. All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    2829 * @extends {WebInspector.View}
    2930 */
    30 WebInspector.DOMStorageItemsView = function(domStorage)
     31WebInspector.DOMStorageItemsView = function(domStorage, domStorageModel)
    3132{
    3233    WebInspector.View.call(this);
    3334
    3435    this.domStorage = domStorage;
     36    this.domStorageModel = domStorageModel;
    3537
    3638    this.element.addStyleClass("storage-view");
     
    4345    this.refreshButton = new WebInspector.StatusBarButton(WebInspector.UIString("Refresh"), "refresh-storage-status-bar-item");
    4446    this.refreshButton.addEventListener("click", this._refreshButtonClicked, this);
     47
     48    this.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageItemsCleared, this._domStorageItemsCleared, this);
     49    this.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageItemRemoved, this._domStorageItemRemoved, this);
     50    this.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageItemAdded, this._domStorageItemAdded, this);
     51    this.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageItemUpdated, this._domStorageItemUpdated, this);
    4552}
    4653
     
    5360    wasShown: function()
    5461    {
    55         this.update();
     62        this._update();
    5663    },
    5764
     
    6168    },
    6269
    63     update: function()
     70    /**
     71     * @param {WebInspector.Event} event
     72     */
     73    _domStorageItemsCleared: function(event)
     74    {
     75        if (!this.isShowing())
     76            return;
     77
     78        this._dataGrid.rootNode().removeChildren();
     79        this._dataGrid.addCreationNode(false);
     80        this.deleteButton.visible = false;
     81        event.consume(true);
     82    },
     83
     84    /**
     85     * @param {WebInspector.Event} event
     86     */
     87    _domStorageItemRemoved: function(event)
     88    {
     89        if (!this.isShowing())
     90            return;
     91
     92        var storageData = event.data;
     93        var rootNode = this._dataGrid.rootNode();
     94        var children = rootNode.children;
     95
     96        event.consume(true);
     97
     98        for (var i = 0; i < children.length; ++i) {
     99            var childNode = children[i];
     100            if (childNode.data.key === storageData.key) {
     101                rootNode.removeChild(childNode);
     102                this.deleteButton.visible = (children.length > 1);
     103                return;
     104            }
     105        }
     106    },
     107
     108    /**
     109     * @param {WebInspector.Event} event
     110     */
     111    _domStorageItemAdded: function(event)
     112    {
     113        if (!this.isShowing())
     114            return;
     115
     116        var storageData = event.data;
     117        var rootNode = this._dataGrid.rootNode();
     118        var children = rootNode.children;
     119
     120        event.consume(true);
     121        this.deleteButton.visible = true;
     122
     123        for (var i = 0; i < children.length; ++i)
     124            if (children[i].data.key === storageData.key)
     125                return;
     126
     127        var childNode = new WebInspector.DataGridNode({key: storageData.key, value: storageData.newValue}, false);
     128        rootNode.insertChild(childNode, children.length - 1);
     129    },
     130
     131    /**
     132     * @param {WebInspector.Event} event
     133     */
     134    _domStorageItemUpdated: function(event)
     135    {
     136        if (!this.isShowing())
     137            return;
     138
     139        var storageData = event.data;
     140        var rootNode = this._dataGrid.rootNode();
     141        var children = rootNode.children;
     142
     143        event.consume(true);
     144
     145        for (var i = 0; i < children.length; ++i) {
     146            var childNode = children[i];
     147            if (childNode.data.key === storageData.key) {
     148                childNode.data.value = storageData.newValue;
     149                childNode.refresh();
     150                this.deleteButton.visible = true;
     151                return;
     152            }
     153        }
     154    },
     155
     156    _update: function()
    64157    {
    65158        this.detachChildViews();
     
    75168        this._dataGrid.show(this.element);
    76169        this._dataGrid.autoSizeColumns(10);
    77         this.deleteButton.visible = true;
     170        this.deleteButton.visible = (this._dataGrid.rootNode().children.length > 1);
    78171    },
    79172
     
    121214    _refreshButtonClicked: function(event)
    122215    {
    123         this.update();
     216        this._update();
    124217    },
    125218
     
    132225
    133226            domStorage.setItem(newText, editingNode.data.value);
    134         } else {
     227        } else
    135228            domStorage.setItem(editingNode.data.key, newText);
    136         }
    137 
    138         this.update();
    139229    },
    140230
     
    146236        if (this.domStorage)
    147237            this.domStorage.removeItem(node.data.key);
    148 
    149         this.update();
    150238    },
    151239
  • trunk/Source/WebCore/inspector/front-end/ResourcesPanel.js

    r141574 r142161  
    22 * Copyright (C) 2007, 2008, 2010 Apple Inc.  All rights reserved.
    33 * Copyright (C) 2009 Joseph Pecoraro
     4 * Copyright (C) 2013 Samsung Electronics. All rights reserved.
    45 *
    56 * Redistribution and use in source and binary forms, with or without
     
    118119    WebInspector.domStorageModel.storages().forEach(this._addDOMStorage.bind(this));
    119120    WebInspector.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this);
    120     WebInspector.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageUpdated, this._domStorageUpdated, this);
    121121}
    122122
     
    470470        view = this._domStorageViews.get(domStorage);
    471471        if (!view) {
    472             view = new WebInspector.DOMStorageItemsView(domStorage);
     472            view = new WebInspector.DOMStorageItemsView(domStorage, WebInspector.domStorageModel);
    473473            this._domStorageViews.put(domStorage, view);
    474474        }
     
    571571        }
    572572        database.getTableNames(tableNamesCallback);
    573     },
    574 
    575     /**
    576      * @param {WebInspector.Event} event
    577      */
    578     _domStorageUpdated: function(event)
    579     {
    580         var storage = /** @type {WebInspector.DOMStorage}*/ (event.data);
    581         var view = this._domStorageViews.get(storage);
    582         if (this.visibleView && view === this.visibleView)
    583             view.update();
    584573    },
    585574
Note: See TracChangeset for help on using the changeset viewer.