Web Inspector: when scrolling a virtualized TreeOutline, only update the DOM periodically
authordrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Aug 2018 21:27:58 +0000 (21:27 +0000)
committerdrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Aug 2018 21:27:58 +0000 (21:27 +0000)
https://bugs.webkit.org/show_bug.cgi?id=188960

Reviewed by Brian Burg.

After each `updateVirtualizedElements` call, remember the `WI.TreeElement` that is located
halfway within the visible list. When handling each "scroll", only regenerate the
`WI.TreeOutline` DOM if the user has scrolled `extraRows` distance.

* UserInterface/Views/TreeOutline.js:
(WI.TreeOutline):
(WI.TreeOutline.prototype.registerScrollVirtualizer):
(WI.TreeOutline.prototype.updateVirtualizedElements):
(WI.TreeOutline.prototype._calculateVirtualizedValues): Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235401 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Views/TreeOutline.js

index 5196d05..b4c6581 100644 (file)
@@ -1,5 +1,22 @@
 2018-08-27  Devin Rousso  <drousso@apple.com>
 
+        Web Inspector: when scrolling a virtualized TreeOutline, only update the DOM periodically
+        https://bugs.webkit.org/show_bug.cgi?id=188960
+
+        Reviewed by Brian Burg.
+
+        After each `updateVirtualizedElements` call, remember the `WI.TreeElement` that is located
+        halfway within the visible list. When handling each "scroll", only regenerate the
+        `WI.TreeOutline` DOM if the user has scrolled `extraRows` distance.
+
+        * UserInterface/Views/TreeOutline.js:
+        (WI.TreeOutline):
+        (WI.TreeOutline.prototype.registerScrollVirtualizer):
+        (WI.TreeOutline.prototype.updateVirtualizedElements):
+        (WI.TreeOutline.prototype._calculateVirtualizedValues): Added.
+
+2018-08-27  Devin Rousso  <drousso@apple.com>
+
         Web Inspector: provide autocompletion for event breakpoints
         https://bugs.webkit.org/show_bug.cgi?id=188717
 
index cad8ad8..4a1bfeb 100644 (file)
@@ -55,6 +55,7 @@ WI.TreeOutline = class TreeOutline extends WI.Object
         this._customIndent = false;
         this._selectable = selectable;
 
+        this._vritualizedCurrentMiddleItem = NaN;
         this._virtualizedScrollContainer = null;
         this._virtualizedTreeItemHeight = NaN;
         this._virtualizedTopSpacer = null;
@@ -659,7 +660,10 @@ WI.TreeOutline = class TreeOutline extends WI.Object
         this._virtualizedBottomSpacer = document.createElement("div");
 
         this._virtualizedScrollContainer.addEventListener("scroll", (event) => {
-            this.updateVirtualizedElements();
+            let {numberVisible, extraRows, firstItem} = this._calculateVirtualizedValues();
+
+            if (Math.abs(firstItem + (numberVisible / 2) - this._vritualizedCurrentMiddleItem) >= extraRows)
+                this.updateVirtualizedElements();
         });
     }
 
@@ -693,10 +697,7 @@ WI.TreeOutline = class TreeOutline extends WI.Object
             return {count, shouldReturn};
         }
 
-        let numberVisible = Math.ceil(this._virtualizedScrollContainer.offsetHeight / this._virtualizedTreeItemHeight);
-        let extraRows = Math.max(numberVisible * 5, 50);
-        let firstItem = Math.floor(this._virtualizedScrollContainer.scrollTop / this._virtualizedTreeItemHeight) - extraRows;
-        let lastItem = firstItem + numberVisible + (extraRows * 2);
+        let {numberVisible, extraRows, firstItem, lastItem} = this._calculateVirtualizedValues();
 
         let shouldScroll = false;
         if (focusedTreeElement && focusedTreeElement.revealed(false)) {
@@ -709,7 +710,9 @@ WI.TreeOutline = class TreeOutline extends WI.Object
                 lastItem = index + extraRows;
             }
 
-            shouldScroll = index < firstItem || index > lastItem;
+            // Only scroll if the `focusedTreeElement` is outside the visible items, not including
+            // the added buffer `extraRows`.
+            shouldScroll = (index < firstItem + extraRows) || (index > lastItem - extraRows);
         }
 
         let totalItems = walk(this, ({parent, treeElement, count}) => {
@@ -731,6 +734,8 @@ WI.TreeOutline = class TreeOutline extends WI.Object
 
         if (shouldScroll)
             this._virtualizedScrollContainer.scrollTop = (firstItem + extraRows) * this._virtualizedTreeItemHeight;
+
+        this._vritualizedCurrentMiddleItem = firstItem + (numberVisible / 2);
     }
 
     // Protected
@@ -808,6 +813,20 @@ WI.TreeOutline = class TreeOutline extends WI.Object
         document.head.appendChild(WI.TreeOutline._styleElement);
     }
 
+    _calculateVirtualizedValues()
+    {
+        let numberVisible = Math.ceil(this._virtualizedScrollContainer.offsetHeight / this._virtualizedTreeItemHeight);
+        let extraRows = Math.max(numberVisible * 5, 50);
+        let firstItem = Math.floor(this._virtualizedScrollContainer.scrollTop / this._virtualizedTreeItemHeight) - extraRows;
+        let lastItem = firstItem + numberVisible + (extraRows * 2);
+        return {
+            numberVisible,
+            extraRows,
+            firstItem,
+            lastItem,
+        };
+    }
+
     _handleContextmenu(event)
     {
         let treeElement = this.treeElementFromEvent(event);