Log Message
Web Inspector: Canvas Recording loading goes significantly slower when "Frame" tree element is expanded https://bugs.webkit.org/show_bug.cgi?id=190497
Reviewed by Joseph Pecoraro.
Source/WebInspectorUI:
Save the `WI.TreeElement` that are in the DOM, and compare that with any `WI.TreeElement`
that would be added to the DOM. If all of the following are true, don't edit the DOM:
- no focused `WI.TreeElement` that isn't currently visible (we would scroll otherwise)
- the set of previously visible `WI.TreeElement`s (e.g. not used for scroll padding) has at
least one of the `WI.TreeElement`s that would be added from this update
- this means that the user hasn't scrolled beyond the padding `WI.TreeElement`
- there are no `WI.TreeElement`s that would be added from this update that were NOT added
in a previous update
- this covers the case that a `WI.TreeElement` is inserted in the visible area
* UserInterface/Base/Utilities.js:
* UserInterface/Views/TreeOutline.js:
(WI.TreeOutline):
(WI.TreeOutline.prototype.registerScrollVirtualizer):
(WI.TreeOutline.prototype.updateVirtualizedElements.walk):
(WI.TreeOutline.prototype.updateVirtualizedElements):
LayoutTests:
* inspector/unit-tests/set-utilities-expected.txt: Added.
* inspector/unit-tests/set-utilities.html: Added.
Modified Paths
- trunk/LayoutTests/ChangeLog
- trunk/Source/WebInspectorUI/ChangeLog
- trunk/Source/WebInspectorUI/UserInterface/Base/Utilities.js
- trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (237435 => 237436)
--- trunk/LayoutTests/ChangeLog 2018-10-25 23:55:12 UTC (rev 237435)
+++ trunk/LayoutTests/ChangeLog 2018-10-25 23:59:43 UTC (rev 237436)
@@ -1,3 +1,13 @@
+2018-10-25 Devin Rousso <[email protected]>
+
+ Web Inspector: Canvas Recording loading goes significantly slower when "Frame" tree element is expanded
+ https://bugs.webkit.org/show_bug.cgi?id=190497
+
+ Reviewed by Joseph Pecoraro.
+
+ * inspector/unit-tests/set-utilities-expected.txt: Added.
+ * inspector/unit-tests/set-utilities.html: Added.
+
2018-10-25 Dawei Fenton <[email protected]>
Layout Test compositing/iframes/display-none-subframe.html is a flaky failure.
Added: trunk/LayoutTests/inspector/unit-tests/set-utilities-expected.txt (0 => 237436)
--- trunk/LayoutTests/inspector/unit-tests/set-utilities-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/unit-tests/set-utilities-expected.txt 2018-10-25 23:59:43 UTC (rev 237436)
@@ -0,0 +1,18 @@
+
+== Running test suite: SetUtilities
+-- Running test case: Set.prototype.intersects
+PASS: an empty set should not intersect another empty set.
+PASS: a non-empty set should not intersect an empty set.
+PASS: a set should intersect another set with the same values.
+PASS: a set should not intersect another set with different values.
+PASS: a set should intersect another set with same and additional values.
+PASS: a set should intersect another set with same and different values.
+
+-- Running test case: Set.prototype.isSubsetOf
+PASS: an empty set should be a subset of another empty set.
+PASS: an empty set should be a subset of a non-empty set.
+PASS: a set should be a subset of another set with the same values.
+PASS: a set should not be a subset of another set with different values.
+PASS: a set should be a subset of another set with same and additional values.
+PASS: a set should not be a subset of another set with same and different values.
+
Added: trunk/LayoutTests/inspector/unit-tests/set-utilities.html (0 => 237436)
--- trunk/LayoutTests/inspector/unit-tests/set-utilities.html (rev 0)
+++ trunk/LayoutTests/inspector/unit-tests/set-utilities.html 2018-10-25 23:59:43 UTC (rev 237436)
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+function test()
+{
+ let suite = InspectorTest.createSyncSuite("SetUtilities");
+
+ suite.addTestCase({
+ name: "Set.prototype.intersects",
+ test() {
+ function testTrue(a, b, message) {
+ InspectorTest.expectThat((new Set(a)).intersects(new Set(b)), message);
+ }
+
+ function testFalse(a, b, message) {
+ InspectorTest.expectFalse((new Set(a)).intersects(new Set(b)), message);
+ }
+
+ const object1 = {a: 1};
+ const object2 = {b: 2};
+ const object3 = {c: 3};
+
+ testFalse([], [], "an empty set should not intersect another empty set.");
+ testFalse([1, "a", object1], [], "a non-empty set should not intersect an empty set.");
+ testTrue([1, "a", object1], [1, "a", object1], "a set should intersect another set with the same values.");
+ testFalse([1, "a", object1], [2, "b", object2], "a set should not intersect another set with different values.");
+ testTrue([1, "a", object1], [1, 3, "a", "c", object1, object3], "a set should intersect another set with same and additional values.");
+ testTrue([1, 2, "a", "b", object1, object2], [1, 3, "a", "c", object1, object3], "a set should intersect another set with same and different values.");
+
+ return true;
+ }
+ });
+
+ suite.addTestCase({
+ name: "Set.prototype.isSubsetOf",
+ test() {
+ function testTrue(a, b, message) {
+ InspectorTest.expectThat((new Set(a)).isSubsetOf(new Set(b)), message);
+ }
+
+ function testFalse(a, b, message) {
+ InspectorTest.expectFalse((new Set(a)).isSubsetOf(new Set(b)), message);
+ }
+
+ const object1 = {a: 1};
+ const object2 = {b: 2};
+ const object3 = {c: 3};
+
+ testTrue([], [], "an empty set should be a subset of another empty set.");
+ testTrue([], [2, "b", object2], "an empty set should be a subset of a non-empty set.");
+ testTrue([1, "a", object1], [1, "a", object1], "a set should be a subset of another set with the same values.");
+ testFalse([1, "a", object1], [2, "b", object2], "a set should not be a subset of another set with different values.");
+ testTrue([1, "a", object1], [1, 3, "a", "c", object1, object3], "a set should be a subset of another set with same and additional values.");
+ testFalse([1, 2, "a", "b", object1, object2], [1, 3, "a", "c", object1, object3], "a set should not be a subset of another set with same and different values.");
+
+ return true;
+ }
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onLoad_="runTest()">
+</body>
+</html>
Modified: trunk/Source/WebInspectorUI/ChangeLog (237435 => 237436)
--- trunk/Source/WebInspectorUI/ChangeLog 2018-10-25 23:55:12 UTC (rev 237435)
+++ trunk/Source/WebInspectorUI/ChangeLog 2018-10-25 23:59:43 UTC (rev 237436)
@@ -1,3 +1,28 @@
+2018-10-25 Devin Rousso <[email protected]>
+
+ Web Inspector: Canvas Recording loading goes significantly slower when "Frame" tree element is expanded
+ https://bugs.webkit.org/show_bug.cgi?id=190497
+
+ Reviewed by Joseph Pecoraro.
+
+ Save the `WI.TreeElement` that are in the DOM, and compare that with any `WI.TreeElement`
+ that would be added to the DOM. If all of the following are true, don't edit the DOM:
+ - no focused `WI.TreeElement` that isn't currently visible (we would scroll otherwise)
+ - the set of previously visible `WI.TreeElement`s (e.g. not used for scroll padding) has at
+ least one of the `WI.TreeElement`s that would be added from this update
+ - this means that the user hasn't scrolled beyond the padding `WI.TreeElement`
+ - there are no `WI.TreeElement`s that would be added from this update that were NOT added
+ in a previous update
+ - this covers the case that a `WI.TreeElement` is inserted in the visible area
+
+ * UserInterface/Base/Utilities.js:
+
+ * UserInterface/Views/TreeOutline.js:
+ (WI.TreeOutline):
+ (WI.TreeOutline.prototype.registerScrollVirtualizer):
+ (WI.TreeOutline.prototype.updateVirtualizedElements.walk):
+ (WI.TreeOutline.prototype.updateVirtualizedElements):
+
2018-10-25 Joseph Pecoraro <[email protected]>
JSContext Inspector: Broken frontend, DOMAgent is used but does not exist
Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Utilities.js (237435 => 237436)
--- trunk/Source/WebInspectorUI/UserInterface/Base/Utilities.js 2018-10-25 23:55:12 UTC (rev 237435)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Utilities.js 2018-10-25 23:59:43 UTC (rev 237436)
@@ -118,6 +118,35 @@
}
});
+Object.defineProperty(Set.prototype, "intersects",
+{
+ value(other)
+ {
+ if (!this.size || !other.size)
+ return false;
+
+ for (let item of this) {
+ if (other.has(item))
+ return true;
+ }
+
+ return false;
+ }
+});
+
+Object.defineProperty(Set.prototype, "isSubsetOf",
+{
+ value(other)
+ {
+ for (let item of this) {
+ if (!other.has(item))
+ return false;
+ }
+
+ return true;
+ }
+});
+
Object.defineProperty(Node.prototype, "enclosingNodeOrSelfWithClass",
{
value(className)
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js (237435 => 237436)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js 2018-10-25 23:55:12 UTC (rev 237435)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js 2018-10-25 23:59:43 UTC (rev 237436)
@@ -55,7 +55,8 @@
this._customIndent = false;
this._selectable = selectable;
- this._virtualizedCurrentMiddleItem = NaN;
+ this._virtualizedVisibleTreeElements = null;
+ this._virtualizedAttachedTreeElements = null;
this._virtualizedScrollContainer = null;
this._virtualizedTreeItemHeight = NaN;
this._virtualizedTopSpacer = null;
@@ -654,16 +655,16 @@
{
console.assert(!isNaN(treeItemHeight));
+ this._virtualizedVisibleTreeElements = new Set;
+ this._virtualizedAttachedTreeElements = new Set;
this._virtualizedScrollContainer = scrollContainer;
this._virtualizedTreeItemHeight = treeItemHeight;
this._virtualizedTopSpacer = document.createElement("div");
this._virtualizedBottomSpacer = document.createElement("div");
+ let throttler = this.throttle(1000 / 16);
this._virtualizedScrollContainer.addEventListener("scroll", (event) => {
- let {numberVisible, extraRows, firstItem} = this._calculateVirtualizedValues();
-
- if (Math.abs(firstItem + (numberVisible / 2) - this._virtualizedCurrentMiddleItem) >= extraRows)
- this.updateVirtualizedElements();
+ throttler.updateVirtualizedElements();
});
}
@@ -678,11 +679,7 @@
if (!child.revealed(false))
continue;
- shouldReturn = callback({
- parent,
- treeElement: child,
- count,
- });
+ shouldReturn = callback(child, count);
if (shouldReturn)
break;
@@ -701,7 +698,7 @@
let shouldScroll = false;
if (focusedTreeElement && focusedTreeElement.revealed(false)) {
- let index = walk(this, ({treeElement}) => treeElement === focusedTreeElement).count;
+ let index = walk(this, (treeElement) => treeElement === focusedTreeElement).count;
if (index < firstItem) {
firstItem = index - extraRows;
lastItem = index + numberVisible + extraRows;
@@ -715,27 +712,54 @@
shouldScroll = (index < firstItem + extraRows) || (index > lastItem - extraRows);
}
- let totalItems = walk(this, ({parent, treeElement, count}) => {
+ console.assert(firstItem < lastItem);
+
+ let visibleTreeElements = new Set;
+ let treeElementsToAttach = new Set;
+ let treeElementsToDetach = new Set;
+ let totalItems = walk(this, (treeElement, count) => {
if (count >= firstItem && count <= lastItem) {
- parent._childrenListNode.appendChild(treeElement.element);
- if (treeElement._childrenListNode)
- parent._childrenListNode.appendChild(treeElement._childrenListNode);
- } else
- treeElement.element.remove();
+ treeElementsToAttach.add(treeElement);
+ if (count >= firstItem + extraRows && count <= lastItem - extraRows)
+ visibleTreeElements.add(treeElement);
+ } else if (treeElement.element.parentNode)
+ treeElementsToDetach.add(treeElement);
return false;
}).count;
+ // Redraw if we are about to scroll.
+ if (!shouldScroll) {
+ // Redraw if all of the previously centered `WI.TreeElement` are no longer centered.
+ if (visibleTreeElements.intersects(this._virtualizedVisibleTreeElements)) {
+ // Redraw if there is a `WI.TreeElement` that should be shown that isn't attached.
+ if (visibleTreeElements.isSubsetOf(this._virtualizedAttachedTreeElements))
+ return;
+ }
+ }
+
+ this._virtualizedVisibleTreeElements = visibleTreeElements;
+ this._virtualizedAttachedTreeElements = treeElementsToAttach;
+
+ for (let treeElement of treeElementsToDetach)
+ treeElement.element.remove();
+
+ for (let treeElement of treeElementsToAttach) {
+ treeElement.parent._childrenListNode.appendChild(treeElement.element);
+ if (treeElement._childrenListNode)
+ treeElement.parent._childrenListNode.appendChild(treeElement._childrenListNode);
+ }
+
this._virtualizedTopSpacer.style.height = (Math.max(firstItem, 0) * this._virtualizedTreeItemHeight) + "px";
- this.element.parentNode.insertBefore(this._virtualizedTopSpacer, this.element);
+ if (this.element.previousElementSibling !== this._virtualizedTopSpacer)
+ this.element.parentNode.insertBefore(this._virtualizedTopSpacer, this.element);
this._virtualizedBottomSpacer.style.height = (Math.max(totalItems - lastItem, 0) * this._virtualizedTreeItemHeight) + "px";
- this.element.parentNode.insertBefore(this._virtualizedBottomSpacer, this.element.nextElementSibling);
+ if (this.element.nextElementSibling !== this._virtualizedBottomSpacer)
+ this.element.parentNode.insertBefore(this._virtualizedBottomSpacer, this.element.nextElementSibling);
if (shouldScroll)
this._virtualizedScrollContainer.scrollTop = (firstItem + extraRows) * this._virtualizedTreeItemHeight;
-
- this._virtualizedCurrentMiddleItem = firstItem + (numberVisible / 2);
}
// Protected
_______________________________________________ webkit-changes mailing list [email protected] https://lists.webkit.org/mailman/listinfo/webkit-changes
