Bug 69464 - Browser update slowed down massively by specific (constant-speed) jQuery code
Summary: Browser update slowed down massively by specific (constant-speed) jQuery code
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL: http://phrogz.net/tmp/webkit-jquery-b...
Depends on:
Reported: 2011-10-05 14:24 PDT by Gavin Kistner
Modified: 2011-10-07 02:19 PDT (History)
3 users (show)

See Also:

Test case showing the problem. (114.67 KB, text/html)
2011-10-05 14:24 PDT, Gavin Kistner
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Gavin Kistner 2011-10-05 14:24:07 PDT
Created attachment 109863 [details]
Test case showing the problem.

Visit http://phrogz.net/tmp/webkit-jquery-browser-update-slowdown.html and follow the instructions there to test the slowdown.

Specifically, there are two distinct sets of jQuery objects, once with 100 <p> ("classes") and the other with 1500 <p> ("methods"). 

Calling methods.hide() followed by classes.filter(":visible") results in the web browser taking 40-400x longer to render the updates versus reversing the order of those statements. In both cases the amount of time seen in the JavaScript function is identical, as is the resulting effect on the DOM.

This slowdown is seen on both Safari and Chrome. It is not present on Firefox v7.
This was reproduced on Windows 7; it is unknown if this affects other OS or not.
This slowdown is not present when using a different jQuery filter with the same effect (e.g. classes.filter(".shown")). It is specific to the jQuery/Sizzle code surrounding the :visible pseudo-class selector.
Comment 1 Antti Koivisto 2011-10-06 23:38:40 PDT
Looks like a potential regression from some of the NodeRenderingContext refactoring:

Running Time	Self		Symbol Name
7152.0ms   72.1%	7152,0	 	WebCore::NodeRenderingContext::previousRenderer() const
7152.0ms   72.1%	0,0	 	 WebCore::Text::rendererIsNeeded(WebCore::NodeRenderingContext const&)
7152.0ms   72.1%	0,0	 	  WebCore::NodeRendererFactory::createRendererIfNeeded()
7152.0ms   72.1%	0,0	 	   WebCore::Node::attach()
7152.0ms   72.1%	0,0	 	    WebCore::Element::attach()
7152.0ms   72.1%	0,0	 	     WebCore::Element::recalcStyle(WebCore::Node::StyleChange)
7152.0ms   72.1%	0,0	 	      WebCore::Element::recalcStyle(WebCore::Node::StyleChange)
7152.0ms   72.1%	0,0	 	       WebCore::Element::recalcStyle(WebCore::Node::StyleChange)
2184.0ms   22.0%	2184,0	 	WebCore::Node::isContentElement() const
2165.0ms   21.8%	0,0	 	 WebCore::NodeRenderingContext::previousRenderer() const
2165.0ms   21.8%	0,0	 	  WebCore::Text::rendererIsNeeded(WebCore::NodeRenderingContext const&)
2165.0ms   21.8%	0,0	 	   WebCore::NodeRendererFactory::createRendererIfNeeded()
Comment 2 Antti Koivisto 2011-10-06 23:40:38 PDT
Ih didn't mean to change the state.
Comment 3 Antti Koivisto 2011-10-06 23:45:34 PDT
Uh oh

    // FIXME: We should have the same O(N^2) avoidance as nextRenderer does
    // however, when I tried adding it, several tests failed.
Comment 4 Gavin Kistner 2011-10-07 01:04:16 PDT
@Antti, that a comment from code you just added, or a comment you just found? If the latter, in what file?