New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Starred by 1 user

Issue metadata

Status: Duplicate
Merged: issue 350785
Owner:
Last visit > 30 days ago
Closed: Mar 2014
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 2
Type: Bug



Sign in to add a comment
link

Issue 351118: Adding an style element to a shadowRoot inside a custom element is slow

Reported by sorvell@chromium.org, Mar 10 2014 Project Member

Issue description

Version: 35.0.1882.0 canary
OS: X 10.9.2

What steps will reproduce the problem?
Include a <style> element inside a shadowRoot inside a custom element.

See the attached test case.


What is the expected output? What do you see instead?

This shouldn't be a big performance hit, but it's currently about a 5-10x performance hit in the above test.


Please use labels and text to provide additional information.
 
input-wstyle.html
1.5 KB View Download

Comment 1 by sorvell@chromium.org, Mar 10 2014

Labels: hotlist-toolkit

Comment 2 by esprehn@chromium.org, Mar 10 2014

Owner: tasak@chromium.org
Status: Assigned
StyleSheetContents::checkLoaded is doing something crazy expensive:

Running Time	Self		Symbol Name
3261.0ms  100.0%	1.0	 	WebCore::Node::appendChild(WTF::PassRefPtr<WebCore::Node>, WebCore::ExceptionState&)
3257.0ms   99.8%	3.0	 	 WebCore::ContainerNode::appendChild(WTF::PassRefPtr<WebCore::Node>, WebCore::ExceptionState&)
3252.0ms   99.7%	4.0	 	  WebCore::ContainerNode::updateTreeAfterInsertion(WebCore::Node&)
3227.0ms   98.9%	3.0	 	   WebCore::ChildNodeInsertionNotifier::notify(WebCore::Node&)
3146.0ms   96.4%	0.0	 	    WebCore::HTMLStyleElement::didNotifySubtreeInsertionsToDocument()
3145.0ms   96.4%	8.0	 	     WebCore::StyleElement::processStyleSheet(WebCore::Document&, WebCore::Element*)
3033.0ms   93.0%	4.0	 	      WebCore::StyleElement::createSheet(WebCore::Element*, WTF::String const&)
2945.0ms   90.3%	2588.0	 	       WebCore::StyleSheetContents::checkLoaded()
176.0ms    5.3%	176.0	 	        WTF::Vector<WebCore::CSSStyleSheet*, 0ul, WTF::DefaultAllocator>::Vector(WTF::Vector<WebCore::CSSStyleSheet*, 0ul, WTF::DefaultAllocator> const&)
172.0ms    5.2%	2.0	 	        WebCore::CSSStyleSheet::sheetLoaded()
7.0ms    0.2%	2.0	 	        WTF::partitionFreeSlowPath(WTF::PartitionPage*)
2.0ms    0.0%	2.0	 	        WebCore::HTMLStyleElement::notifyLoadedSheetAndAllCriticalSubresources(bool)
27.0ms    0.8%	1.0	 	       WebCore::MediaQueryEvaluator::MediaQueryEvaluator(char const*, bool)
21.0ms    0.6%	6.0	 	       WebCore::StyleEngine::createSheet(WebCore::Element*, WTF::String const&, WTF::TextPosition, bool)
19.0ms    0.5%	2.0	 	       WebCore::ContentSecurityPolicy::allowStyleHash(WTF::String const&) const
10.0ms    0.3%	0.0	 	       <Unknown Address>
2.0ms    0.0%	1.0	 	       non-virtual thunk to WebCore::HTMLStyleElement::type() const
1.0ms    0.0%	1.0	 	       WebCore::ContentSecurityPolicy::allowStyleNonce(WTF::String const&) const
1.0ms    0.0%	1.0	 	       WebCore::MediaQuerySet::create(WTF::String const&)
1.0ms    0.0%	1.0	 	       non-virtual thunk to WebCore::HTMLStyleElement::media() const
1.0ms    0.0%	1.0	 	       DYLD-STUB$$WTF::fastMalloc(unsigned long)
1.0ms    0.0%	0.0	 	       WebCore::CSSStyleSheet::setMediaQueries(WTF::PassRefPtr<WebCore::MediaQuerySet>)
88.0ms    2.6%	2.0	 	      WebCore::StyleEngine::addStyleSheetCandidateNode(WebCore::Node*, bool)

Specifically it appears that the issue is that it's iterating all the clients:

Vector<CSSStyleSheet*> clients(root->m_clients);
    for (unsigned i = 0; i < clients.size(); ++i) {
        // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run via
        // ScriptableDocumentParser::executeScriptsWaitingForResources().
        RefPtr<CSSStyleSheet> protectClient(clients[i]);

        if (clients[i]->loadCompleted())
            continue;

        // sheetLoaded might be invoked after its owner node is removed from document.
        if (RefPtr<Node> ownerNode = clients[i]->ownerNode()) {
            if (clients[i]->sheetLoaded())
                ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur);
        }
    }

which is n^2 since each <style> is calling checkLoaded(), and all of them have loaded already, so we keep going through the list over and over again noticing that there's no work to do.

This is probably why the stylesheet caching seems to not be working very well. Once you have lots of sharing this loop starts to beat down on your app.

Comment 3 by esprehn@chromium.org, Mar 10 2014

Mergedinto: 350785
Status: Duplicate

Comment 4 by sorvell@chromium.org, Mar 11 2014

This may be a separate bug, but if I include a large stylesheet inside the custom element, the paint time (as measured via requestAnimationFrame) goes up dramatically (~4500ms). This does not occur if the stylesheet it outside the custom element.
input-wbigstyle.html
97.5 KB View Download

Comment 5 by esprehn@chromium.org, Mar 11 2014

@sorvell: That looks like another bug, filed it  http://crbug.com/351145 

Sign in to add a comment