Open Bug 1406622 Opened 3 years ago Updated 11 months ago
stylo: use invalidation framework to handle restyles needed in response to content insertion/removal
Currently we respond to content modifications needing to restyle elements due to slow selector flags by posting restyles. For example, when we append a new element to a parent that is marked as having a child that needs :last-child matched, we'll post an eRestyle_Subtree on the old last child. It seems like we should be able to use invalidations to do more targeted restyling.
Yes, indeed! I thought about this before, and this would allow us to avoid the selector_flags_map, and the flags_setter, which is nice.
So I thought a bit more about how to do this, and of course it's not an easy fix, but it's not impossible either. The problem is that we can't invalidate style synchronously during the DOM mutation, because that can get out of sync with class changes and what not. So the proper way to fix this, I think, is to teach the snapshot stuff about positional pseudo-classes. For that, we could make the snapshots have an "old next / prev" sibling, that would allow us to reconstruct the old sibling chain. So it'd be something like, for positional pseudo-classes, snapshot the prev and next siblings on DOM insertion / removal. Then the invalidation machinery would take over and invalidate other stuff if needed as it does for attribute changes. For :empty / :-moz-only-whitespace it's a bit more annoying, because we need to snapshot the parent, but I think it's not much harder than that / making the snapshot aware of whether it was empty.
(In reply to Emilio Cobos Álvarez [:emilio] from comment #2) > For :empty / :-moz-only-whitespace it's a bit more annoying, because we need > to snapshot the parent, but I think it's not much harder than that. Hmm, well, it might, because we'd need to compute accurately whether :empty / :-moz-only-whitespace have changed...
I think the only way to fix this in a sane way is either snapshotting previous parent / siblings of the DOM element, or just ditching the "invalidate during the traversal" stuff and do it sync. But that's kind of a pity.
A somewhat mixed alternative would be to collect the invalidations sync, and invalidate during the traversal... That may be a good trade-off I guess.
I have better ideas I think...
https://treeherder.mozilla.org/#/jobs?repo=try&revision=134f68176227a35007c081873dc34abbbf6caee7 is the try run. https://treeherder.mozilla.org/perf.html#/compare?originalProject=mozilla-central&newProject=try&newRevision=025022534e4252dd20852d76af2a7ef161e6ea2a&framework=1&selectedTimeRange=172800 is the talos push. I didn't remove the selector flags setters and stuff but I should... I left them just in case they were needed to make stuff faster, though so far talos hasn't showed anything ridiculous. This should fix bug 1480477 & co. There's a bunch of tricky invalidation test-cases I want to land. Also I think I haven't handled :empty invalidation yet, but that should be trivial compared to :nth-child & co.
Assignee: nobody → emilio
Also, some more cleanup can be done too afterwards.
https://treeherder.mozilla.org/#/jobs?repo=try&revision=78f86787b8caaf894c478a32636e4998aa521fec has a couple more fixes, still not 100% right.
Looks like I have some perf work to do if I really want to get rid of the slow selector flags... Stylebench isn't happy about this: https://treeherder.mozilla.org/perf.html#/comparechooser?newProject=try&newRevision=e0bc980ed752fdc00a810ad09ac942351f35cd22
Boris, friendly ping regarding your feedback on the style invalidation? Let me know if you don't have cycles to look into it and I'll just write patches :P
(Adjusting priority since it blocks bug 1480477)
Priority: P4 → P2
Sorry, I've been on unexpected PTO most of this week... I won't really be back to work until Tuesday morning. I will definitely try to look at this then.
Whiteboard: [qf:p1:f64] → [qf:p2:responsiveness]
You need to log in before you can comment on or make changes to this bug.