`mjx-row > *` CSS style has impact on large documents
Issue Summary
When very large documents which include mathjax are edited the mjx-row > * contributes to the high cost of style recalculation.
Most of the CSS selectors in MathJax are neatly scoped, use child combinator (>), and avoid using universal selector (*), which altogether makes recent versions of MathJax quite performant when it comes to style calculation. However this one rule stands out:
'mjx-row > *': { display: 'table-cell' }
https://github.com/mathjax/MathJax-src/blob/1a2ef74c0ac0620e7b8de46402c9dce3b95ade52/ts/output/chtml.ts#L150
I see that elsewhere mjx-row > mjx-cell is used. Is the use of the universal selector here intentional, or was it just a placeholder when the code was initially written?
For context, this rule was initially added in https://github.com/mathjax/MathJax-src/pull/50
Steps to Reproduce:
- Create an HTML document with deep nesting and high number of DOM nodes
- Load MathJax
- Enable CSS statistics collection in Chrome/Edge Performance tab
- Start Chrome profiler
- Make any modification to the DOM
- See that a few ms can be spent in "Recalculate Styles" on matching
mjx-row > *
Technical details:
- MathJax Version: 3.0+
- Browser: Chrome and Edge 141
Supporting information:
Irrelevant
Looking at the code, I think the solution to preserve the functionality would be something like:
mjx-row > mjx-cell,
mjx-row > mjx-over, // maybe? not sure
mjx-row > mjx-base,
mjx-row > mjx-under {
display: table-cell;
}
but I don't know enough about MathJax internals to be confident if this covers all the potential children of mjx-row row.
I think there is on other situation missing from your list, which is mjx-row > mjx-den (used in fractions). Otherwise, I think you have found the full list. I will do some more testing, but I think that is correct.
There are also some * rules for multi-character stretchy assemblies (like really large parentheses, or really wide overbraces); are those causing problems, too?
Hmm that's interesting, the other rules with * do not show up in profiling in my environment. I think they are not causing problems as of now, but it would be ideal to have as few rules as possible include *.
I have made a PR that removes the * CSS rules, as suggested.