Re: [csswg-drafts] [css-highlight-api][css-contain] static ranges and css-contain (#4598)

I’ve been looking through Chomium’s range-related paint invalidation code to see if would help articulate some of the points being made here more precisely.

We’ve argued that conceptually, painting for both live ranges and static ranges should be considered as happening independently of CSS contain, because ranges can span arbitrary sections of the tree and are therefore unsuited for optimizations like CSS contain that are applied to specific subtrees.

This turns out to be true in the Chromium range invalidation code, which happens at a document-wide level without regard for scoping into individual subtrees.

For Selection, backed by a live range, [LayoutSelection::Commit](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/editing/layout_selection.cc;bpv=1;bpt=1;l=873?q=resetoldselectednodes&ss=chromium) is called prior to painting. LayoutSelection remembers the set of nodes that had selection styles last time a paint was performed. It calculates the set of nodes that should have selection styles given the current position of the selection range. Then, paint is invalidated for the nodes whose selection state has changed.

This operation is triggered independently of CSS containment, and it’s difficult to see how taking paint containment into account could make it significantly faster. The operation just isn’t tree-based in a way that could take advantage of knowledge of contained subtrees.

Highlight invalidation for StaticRanges is performed in a different part of the codebase but uses a similar technique. The [DocumentMarkerController]( https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/editing/markers/document_marker_controller.h;drc=5d96a3f35a87c9314a8219d174d2fff03dd3387b;bpv=1;bpt=1;l=55) has a [map]( https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/editing/markers/document_marker_controller.h;l=231;drc=5d96a3f35a87c9314a8219d174d2fff03dd3387b;bpv=1;bpt=1) containing all Text nodes currently being painted with any highlight style. During pre-paint, a StaticRange validation step walks registered highlights and checks the validity of each StaticRange backing these Highlights. The StaticRanges that are no longer valid will be removed from the DocumentMarkerController. Removing a StaticRange in this way causes the DocumentMarkerController to invalidate paint for each Text node spanned by that range.

This whole operation is performed without regard for CSS contain boundaries. It’s difficult to see what optimization could be added to this StaticRange painting invalidation that would take advantage of paint-contain information. In @frivoal’s stock picker example, when a stock price is updated (offscreen or otherwise), we'll detect if a static range is no longer valid and invalidate all affected nodes by consulting the DocumentMarkerController’s record of which nodes were previously covered by highlights. The invalidation can be done precisely, only invalidating the nodes that need repainting, which could then be limited to on-screen nodes. CSS contain doesn't influence this type of range based invalidation.

Thus, we’re not giving up any important performance opportunities by painting StaticRange highlights across contain boundaries.


-- 
GitHub Notification of comment by dandclark
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/4598#issuecomment-1023759263 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Friday, 28 January 2022 00:14:48 UTC