Per Paul Irish: "inside ve.dm.MWBlockImageNode.static.toDataElement is some call that ends up calling jQuery.filter... I'm not sure what the filtering is for but because the DOM is SO HUGE this takes a long time.". Later: "yep, the cost is enormous".
Description
Details
Related Objects
Event Timeline
This seems to be due to several .children() calls:
$imgWrapper = $figure.children( 'a, span' ).eq( 0 ), $img = $imgWrapper.children( 'img' ).eq( 0 ), $caption = $figure.children( 'figcaption' ).eq( 0 ),
Why is this so expensive? Surely the DOM being huge shouldn't matter for .children()? Or does the <figure> in question have an insane number of direct children? I checked the Parsoid DOM for Barack Obama, and all of the <figure>s on that page have exactly 2 children. This seems like a bug in jQuery / Sizzle perhaps?
Ori tells me this is due to a bug in Sizzle where setDocument is called and expensive processing is performed pretty much every time jQuery is used on a document that isn't window.document. I'll tally how often setDocument is called and try to reduce this number by reducing jQuery usage on foreign documents in VE.
Change 186795 had a related patch set uploaded (by Catrope):
dm.MWBlockImageNode: Use DOM methods rather than jQuery
Change 186796 had a related patch set uploaded (by Catrope):
Use DOM rather than jQuery for <base> resolution
Change 186797 had a related patch set uploaded (by Catrope):
ce.GeneratedContentNode: Import DOM elements into target document early
These three patches reduce the number of setDocument calls in my test case from 79 to 1. (1 is the minimum since setDocument is needed for initialization.)
Change 186795 merged by jenkins-bot:
dm.MWBlockImageNode: Use DOM methods rather than jQuery
Change 186796 merged by jenkins-bot:
Use DOM rather than jQuery for <base> resolution
Change 186797 merged by jenkins-bot:
ce.GeneratedContentNode: Import DOM elements into target document early