Title: [94938] trunk
Revision
94938
Author
[email protected]
Date
2011-09-11 20:25:04 -0700 (Sun, 11 Sep 2011)

Log Message

REGRESSION (r87351): toggling display of lots (thousands) of elements with display:none is very slow
https://bugs.webkit.org/show_bug.cgi?id=67581

Reviewed by Darin Adler.

Source/WebCore:

Test: perf/show-hide-table-rows.html

* dom/NodeRenderingContext.cpp:
(WebCore::NodeRendererFactory::createRendererAndStyle): Moved style-creating code into createRendererIfNeeded, renamed
    to createRenderer.
(WebCore::NodeRendererFactory::createRendererIfNeeded): Re-arrange code to avoid unnecessary creation of renderers.

LayoutTests:

* perf/show-hide-table-rows-expected.txt: Added.
* perf/show-hide-table-rows.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (94937 => 94938)


--- trunk/LayoutTests/ChangeLog	2011-09-12 03:21:28 UTC (rev 94937)
+++ trunk/LayoutTests/ChangeLog	2011-09-12 03:25:04 UTC (rev 94938)
@@ -1,3 +1,13 @@
+2011-09-11  Dimitri Glazkov  <[email protected]>
+
+        REGRESSION (r87351): toggling display of lots (thousands) of elements with display:none is very slow
+        https://bugs.webkit.org/show_bug.cgi?id=67581
+
+        Reviewed by Darin Adler.
+
+        * perf/show-hide-table-rows-expected.txt: Added.
+        * perf/show-hide-table-rows.html: Added.
+
 2011-09-11  Fumitoshi Ukai  <[email protected]>
 
         Unreviewed, one more rebaseline for r94912

Added: trunk/LayoutTests/perf/show-hide-table-rows-expected.txt (0 => 94938)


--- trunk/LayoutTests/perf/show-hide-table-rows-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/perf/show-hide-table-rows-expected.txt	2011-09-12 03:25:04 UTC (rev 94938)
@@ -0,0 +1,3 @@
+Tests that hiding/showing of table rows is linear.
+PASS
+

Added: trunk/LayoutTests/perf/show-hide-table-rows.html (0 => 94938)


--- trunk/LayoutTests/perf/show-hide-table-rows.html	                        (rev 0)
+++ trunk/LayoutTests/perf/show-hide-table-rows.html	2011-09-12 03:25:04 UTC (rev 94938)
@@ -0,0 +1,39 @@
+<style>
+.hidden { display: none; }
+</style>
+<script src=""
+<body>
+<div></div>
+<script>
+
+function setupFunction(magnitude)
+{
+    var html = '<table>';
+    for (var i = 0; i < magnitude; ++i)
+        html += '<tr><td>A</td><td>B</td><td>C</td><td>D</td><td>E</td><td>F</td></tr>\n';
+    html += '</table>';
+    document.querySelector('div').innerHTML = html;
+}
+
+function forEachRow(what)
+{
+    Array.prototype.forEach.call(document.querySelectorAll("tr"), what);
+}
+
+function test(magnitude)
+{
+    forEachRow(function(tr) {
+        tr.className = 'hidden';
+    });
+    document.body.offsetWidth;
+    forEachRow(function(tr) {
+        tr.className = '';
+    });
+    document.body.offsetWidth;
+}
+
+Magnitude.description("Tests that hiding/showing of table rows is linear.");
+Magnitude.run(setupFunction, test, Magnitude.LINEAR);
+document.querySelector('div').textContent = '';
+</script>
+</body>

Modified: trunk/Source/WebCore/ChangeLog (94937 => 94938)


--- trunk/Source/WebCore/ChangeLog	2011-09-12 03:21:28 UTC (rev 94937)
+++ trunk/Source/WebCore/ChangeLog	2011-09-12 03:25:04 UTC (rev 94938)
@@ -1,3 +1,17 @@
+2011-09-11  Dimitri Glazkov  <[email protected]>
+
+        REGRESSION (r87351): toggling display of lots (thousands) of elements with display:none is very slow
+        https://bugs.webkit.org/show_bug.cgi?id=67581
+
+        Reviewed by Darin Adler.
+
+        Test: perf/show-hide-table-rows.html
+
+        * dom/NodeRenderingContext.cpp:
+        (WebCore::NodeRendererFactory::createRendererAndStyle): Moved style-creating code into createRendererIfNeeded, renamed
+            to createRenderer.
+        (WebCore::NodeRendererFactory::createRendererIfNeeded): Re-arrange code to avoid unnecessary creation of renderers.
+
 2011-09-11  Jeremy Moskovich  <[email protected]>
 
         [Chromium] Change OOP Font loading code to use CGFont*() APIs.

Modified: trunk/Source/WebCore/dom/NodeRenderingContext.cpp (94937 => 94938)


--- trunk/Source/WebCore/dom/NodeRenderingContext.cpp	2011-09-12 03:21:28 UTC (rev 94937)
+++ trunk/Source/WebCore/dom/NodeRenderingContext.cpp	2011-09-12 03:25:04 UTC (rev 94938)
@@ -286,29 +286,10 @@
 {
 }
 
-RenderObject* NodeRendererFactory::createRendererAndStyle()
+RenderObject* NodeRendererFactory::createRenderer()
 {
     Node* node = m_context.node();
-    Document* document = node->document();
-    ASSERT(!node->renderer());
-    ASSERT(document->shouldCreateRenderers());
-
-    if (!m_context.shouldCreateRenderer())
-        return 0;
-
-    Element* element = node->isElementNode() ? toElement(node) : 0;
-    if (element)
-        m_context.setStyle(element->styleForRenderer());
-    else if (RenderObject* parentRenderer = m_context.parentRenderer())
-        m_context.setStyle(parentRenderer->style());
-
-    if (!node->rendererIsNeeded(m_context)) {
-        if (element && m_context.style()->affectedByEmpty())
-            element->setStyleAffectedByEmpty();
-        return 0;
-    }
-
-    RenderObject* newRenderer = node->createRenderer(document->renderArena(), m_context.style());
+    RenderObject* newRenderer = node->createRenderer(node->document()->renderArena(), m_context.style());
     if (!newRenderer)
         return 0;
 
@@ -345,25 +326,38 @@
     if (!document->shouldCreateRenderers())
         return;
 
-    RenderObject* parentRenderer = m_context.parentRenderer();
-    RenderObject* nextRenderer = m_context.nextRenderer();
-    RenderObject* newRenderer = createRendererAndStyle();
+    ASSERT(!node->renderer());
+    ASSERT(document->shouldCreateRenderers());
 
-    if (m_context.hasFlowThreadParent()) {
-        parentRenderer = m_context.parentFlowRenderer();
-        // Do not call m_context.nextRenderer() here, because it expects to have 
-        // the renderer added to its parent already.
-        nextRenderer = m_context.parentFlowRenderer()->nextRendererForNode(node);
+    // FIXME: This side effect should be visible from attach() code.
+    m_context.hostChildrenChanged();
+
+    if (!m_context.shouldCreateRenderer())
+        return;
+
+    Element* element = node->isElementNode() ? toElement(node) : 0;
+    if (element)
+        m_context.setStyle(element->styleForRenderer());
+    else if (RenderObject* parentRenderer = m_context.parentRenderer())
+        m_context.setStyle(parentRenderer->style());
+
+    if (!node->rendererIsNeeded(m_context)) {
+        if (element && m_context.style()->affectedByEmpty())
+            element->setStyleAffectedByEmpty();
+        return;
     }
 
+    RenderObject* parentRenderer = m_context.hasFlowThreadParent() ? m_context.parentFlowRenderer() : m_context.parentRenderer();
+    // Do not call m_context.nextRenderer() here in the first clause, because it expects to have
+    // the renderer added to its parent already.
+    RenderObject* nextRenderer = m_context.hasFlowThreadParent() ? m_context.parentFlowRenderer()->nextRendererForNode(node) : m_context.nextRenderer();
+    RenderObject* newRenderer = createRenderer();
+
 #if ENABLE(FULLSCREEN_API)
     if (document->webkitIsFullScreen() && document->webkitCurrentFullScreenElement() == node)
         newRenderer = wrapWithRenderFullScreen(newRenderer, document);
 #endif
 
-    // FIXME: This side effect should be visible from attach() code.
-    m_context.hostChildrenChanged();
-
     if (!newRenderer)
         return;
 

Modified: trunk/Source/WebCore/dom/NodeRenderingContext.h (94937 => 94938)


--- trunk/Source/WebCore/dom/NodeRenderingContext.h	2011-09-12 03:21:28 UTC (rev 94937)
+++ trunk/Source/WebCore/dom/NodeRenderingContext.h	2011-09-12 03:25:04 UTC (rev 94938)
@@ -123,7 +123,7 @@
     void createRendererIfNeeded();
 
 private:
-    RenderObject* createRendererAndStyle();
+    RenderObject* createRenderer();
 
     NodeRenderingContext m_context;
 };
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to