Why does simply using Ctrl+Home/Ctrl+End cause the entire editor to repaint?

I noticed that’s not the case with some other projects - Lexical and Quill do repaint sporadically in these cases. Plain contentEditable never does. SlateJS never does (unless the page scrolls?)

I’m wondering if this is something that can be resolved? I’ve noticed that repaints are pretty heavy in ProseMirror compared with some other rich text editors and that that’s become the limiting factor on our editor’s performance. Unfortunately we’ve already implemented all the CSS optimizations we can and it seems there’s nothing else we can do about it.

The behavior isn’t present in all ProseMirror demos, but it can be seen in this one: ProseMirror basic example

I tested with Chrome DevTools >> Rendering >> Paint flashing

The editor doesn’t re-render anything in this situation (you can verify that the exact same DOM nodes remain in place). I’m not sure why Chrome would repaint the document (or whether devtools is somehow reporting this incorrectly).

Thanks for your reply and your amazing work @marijn!

Apparently this is less straightforward than it had intially seemed.

It’s not a reflow or anything, but it does repaint in a way I can’t reproduce in a plain contentEditable. I’m pretty confident (can never be entirely sure) this is not just a bug in the repaint detection because on very long documents we get a lot of lag even without reflows and the performance profiler also attributes this solely to repaints. The slowdown is definitely real, and it doesn’t attribute the slowdown to anything else (for example scripting or layout.)

Originally I had tested on MDN and thought I couldn’t reproduce this in a plain contentEditable - but it turns out I can (they use an iframe and I hadn’t realized)

But the issue I see is that these actions, clicking around, and (very importantly) using the spacebar cause massive repaints of the editor. The spacebar in particular causes the entire editor to repaint under many circumstances, even though other characters limit the repaints to the local node. Unfortunately the spacebar issue in particular leads to massive lag. It’s sporadic in the ProseMirror examples, which makes this harder still to document fully - in our editor it seems persistent though I’ve yet to identify why.

I have noticed that two editors do not suffer from this - SlateJS (which uses React and obviously isn’t that comparable) - but also Lexical seems spared from this behavior (even sporadically) whereas in ProseMirror it does occur at times, although I cannot find the pattern.

Example:

I wonder what they might be doing that prevents repaints upon spacebar usage. It seems like there’s potential to massively improve ProseMirror’s performance on longer documents if that single behavior could be prevented.

I’m happy to do more investigation or provide more info to clarify upon request.

Thank you again @marijn <3

I’ve confirmed that, if you turn off the menu, the editor doesn’t touch the DOM at all when you do ctrl-home/end (except for a classList.add of a class that’s already there, but commenting that out doesn’t change the outcome), yet the browser does usually repaint the entire content. Disabling our CSS doesn’t affect this either. So it really look as if the browser will repaint based on cursor position. As you found, plain editable elements exhibit the same behavior.

I’m actually seeing the same in Lexical, when I test at https://playground.lexical.dev/—it often will flash the entire editor green when moving the cursor around. Though possibly less often than native editable and ProseMirror.