Open Bug 1537903 Opened 6 years ago Updated 2 years ago

DOM Style : jQuery - .hide(): extremely slow when run from the harness (due to page being loaded in a display: none iframe)

Categories

(Core :: CSS Parsing and Computation, defect, P3)

66 Branch
x86_64
Linux
defect

Tracking

()

People

(Reporter: linuxcbon, Unassigned)

References

(Depends on 1 open bug)

Details

(Keywords: perf)

Attachments

(1 file)

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0

Steps to reproduce:

run http://dromaeo.com/?jslib
in chrome and firefox

Actual results:

FIREFOX 66.0
jQuery - .hide(): 94.57runs/s ±74.84%
CHROME 73.0.3683.75
jQuery - .hide(): 732.94runs/s ±3.79%

Expected results:

jQuery - .hide(): should be much faster

Component: Untriaged → DOM: Core & HTML
Keywords: perf
OS: Unspecified → Linux
Product: Firefox → Core
Hardware: Unspecified → x86_64

This about many different things, bindings, JS and styling.

Component: DOM: Core & HTML → DOM: Bindings (WebIDL)

Is there a way to only run one subtest?

Has STR: --- → yes

Running only one subtest off the site itself is not trivial. You can use http://dromaeo.com/?jslib-style-jquery (or http://dromaeo.com/?jslib-style-jquery&numTests=1 to run each test only once, not 5 times) to run just the tests that include hide(), but there's still lots of other stuff in there.

That said, you can grab http://dromaeo.com/tests/jslib-style-jquery.html and edit it a bit to get things running, I think. http://dromaeo.com/webrunner.js has the definitions of prep() and test() that's using.

I did just try this locally, simply running div.hide() in a loop on that page. The numbers I get in Firefox are much higher (4x or so) than what the Dromaeo site itself reports, which itself is about 4x higher than what comment 0 lists. For Chrome, my local test is showing numbers about comparable to the website and 2x higher than comment 0.

I wonder how much of the time here is just harness overhead getting dates or something like that...

Emilio, do you plan to dig into this more?

Flags: needinfo?(emilio)

Anyway, profile of my cut-down testcase is at https://perfht.ml/2FZ24Dn

Status: UNCONFIRMED → NEW
Ever confirmed: true

Yes, I'm poking a bit at least at the style system bits.

Attached file The test-case I'm using. (deleted) —

(Just wait to see the number)

Boris, I was poking at this (identified some bits that should be inline in the style system, and some potential optimizations). But I'm not seeing the numbers you see even in Nightly.

This is the test-case slightly tweaked with:

  • Image URLs replaced by # so that the load event fires ASAP.
  • A tweak to not run while the throbber is spinning (gonna file a WR bug about the test-case taking almost double the time if WR is enabled and the throbber is spinning in a sec). Will upload the throbber-spinning test-case there.

I see Gecko doing numbers about 6s both in my regular profile and in a pristine profile, and I see Chromium doing numbers around 10s (14 in the throbber-spinning test-case). This is raw time, so lower is better.

This obviously doesn't match either the numbers in comment 0 or yours, so I'm a bit baffled.

Can you see the same numbers in my test-case? Do you know what differs from the one you constructed?

Flags: needinfo?(emilio) → needinfo?(bzbarsky)

(My Chrome version is 73.0.3683.86 (Developer Build) Fedora Project (64-bit), fwiw)

I'm seeing slightly better numbers in the official Chrome Dev build, around 8s (75.0.3753.4 (Official Build) dev (64-bit)).

I'll look at the harness stuff now too, fwiw.

(I just realized that you didn't explicitly mentioned us being slower in comment 4, but anyhow worth taking a look if you reproduce the same numbers roughly)

Using the testcase from comment 6, the numbers I see are:

  • Firefox nightly from today: 5328, 4753, 4677.
  • Chrome dev 75.0.3759.4: 5693, 5462, 5495.

These are both on Mac. The overall conclusion is the same as the numbers from my attempt at a testcase: we're not slower than Chrome. The question then becomes why we end up slower on the test as run on the site.

Flags: needinfo?(bzbarsky)

(In reply to Emilio Cobos Álvarez (:emilio) from comment #9)

I'll look at the harness stuff now too, fwiw.

now is going to have to end up being tomorrow :)

Flags: needinfo?(linuxcbon)
Summary: DOM Style : jQuery - .hide(): extremely slow → DOM Style : jQuery - .hide(): extremely slow when run from the harness

Err, this was going to be for myself.

Flags: needinfo?(linuxcbon) → needinfo?(emilio)

So, this is just because the <iframe> the harness loads the test in is display: none. All the extra time is just recomputing the style of the element hierarchy over and over with the style sheets of the parent document.

If I change the iframe { display: none } rule to be iframe { position: absolute; visibility: hidden } or such, then the score gets quadrupled.

Our situation in terms of computing styles in display: none iframes is not great (and has never been). We could avoid flushing the parent document in a bunch more situations than we do now, and I got a patch for that running through try.

That wouldn't help much here, but may help in other real-world pages. We're in a better situation to compute styles in display: none iframes these days (now that bug 1535788 is fixed, we could get the appropriate data). That wouldn't help a lot without some caching though.

The only way to fix this soundly IMO is a combination of:

  • Being able able to compute styles in display: none iframes (bug 1471231). That allows us to always return the style from the document the element is in.

  • Being able to cache styles in display: none subtrees / undisplayed subtrees (bug 1381071). We'd need to presumably always track restyles in display: none iframes, which is quite more annoying. I'm fighting some of those issues already in bug 1381071 though.

Component: DOM: Bindings (WebIDL) → CSS Parsing and Computation
Depends on: 1471231, 1381071
Flags: needinfo?(emilio)
Priority: -- → P3
Summary: DOM Style : jQuery - .hide(): extremely slow when run from the harness → DOM Style : jQuery - .hide(): extremely slow when run from the harness (due to page being loaded in a display: none iframe)

So the issue is that hide() is checking whether display is already "none" before setting it to "none", instead of just letting us optimize it out?

Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: