Open Bug 1911633 Opened 7 months ago Updated 18 days ago

[meta] Slower HTML parsing in Firefox relative to Chrome in TodoMVC-JavaScript and TodoMVC-jQuery (set innerHTML, DOMParser.parseFromString)

Categories

(Core :: DOM: HTML Parser, enhancement)

enhancement

Tracking

()

People

(Reporter: jlink, Unassigned)

References

(Blocks 1 open bug)

Details

(Keywords: meta, Whiteboard: [sp3])

Several TodoMVC tests show higher costs in Firefox vs Chrome in parsing related functionality:

DOMParser.parseFromString

TodoMVC-JavaScript-ES5

6131 vs 2476 samples (diff: 3655, 2.48x): Firefox profile vs Chrome profile

Making Firefox as fast as Chrome on this function would reduce its time by 11.2%.

set Element.innerHTML

TodoMVC-JavaScript-ES6-Webpack-Complex-DOM

8222 vs 5765 samples (diff: 2457, 1.43x): Firefox profile vs Chrome profile

Making Firefox as fast as Chrome on this function would reduce its time by 5.4%.

TodoMVC-jQuery

21898 vs 12421 samples (diff: 9477, 1.76x): Firefox profile vs Chrome profile

Making Firefox as fast as Chrome on this function would reduce its time by 14.1%.

HTML Element creation

TodoMVC-JavaScript-ES5

2359 vs 1235 samples (diff: 1124, 1.91x): Firefox profile + Firefox profile + Firefox profile + Firefox profile + Firefox profile + Firefox profile + Firefox profile + Firefox profile + Firefox profile vs Chrome profile + Chrome profile + Chrome profile + Chrome profile + Chrome profile + Chrome profile + Chrome profile + Chrome profile + Chrome profile

Making Firefox as fast as Chrome on this function would reduce its time by 3.4%.

Summary: Slower Firefox parsing relative to Chrome in TodoMVC-JavaScript and TodoMVC-jQuery → [meta] Slower HTML parsing in Firefox relative to Chrome in TodoMVC-JavaScript and TodoMVC-jQuery (set innerHTML, DOMParser.parseFromString)

Some observations from looking at the Firefox profile for DOMParser.parseFromString / TodoMVC-JavaScript-ES5 above:

6.1% of the total (3.1% + 3.0%) is coming from locking (entering/exiting critical sections) and essentially all of those locks are memory allocation-related. About half of those allocations are coming from mozilla::StringBuffer::Alloc().

  • Parsing is going to be string-heavy but it might be beneficial to review the usage to ensure that no unnecessary allocations are being triggered. Cutting out a few allocations could have an outsized impact on overall performance.

4.4% of the time is being spent in memcmp(), mostly called from nsAtom::Equals() which is called from nsHtmlPortability::localEqualsBuffer().

4.0% of the total time is spent in nsHtml5Tokenizer<nsHtml5FastestPolicy>::stateLoop().

  • I haven't looked closely to see where time is spent but that feels a little bit on the high side to me.

While looking at this in the debugger a bit, I noticed a bunch of strings being memcmp'd there that should not have gotten there (because their hashes should not have matched). Digging around a bit, I found that the AtomCache being used there does not seem to check the hashes at all before doing the deep string comparisons.

I've put together a quick patch to add hash checking where I think it should happen. Locally that seems to prevent the excessive memcmp()'s but I'll see what CI says about its impact on performance.

Depends on: 1912367
Depends on: 1912908

Attaching a recent profile https://share.firefox.dev/4eUbn6W (while this is not from Firefox profiler but lower level profiling).

You need to log in before you can comment on or make changes to this bug.