Open aliak00 opened 3 years ago
Err. Maybe this should be moved to the discussions and not issues 😬
One more observation. When I tab one of the leaf Text nodes, it results in a wrapNodes
call, and then it looks like the entire tree is re-rendered.
Not a direct answer but we can see "Element (Memo)" meaning that it's using React.memo
to memoize the unchanged elements. See MemoizedElement. However in a huge document the performance gets affected by the Children component:
ThIs happens for 2 related reasons:
In slate, an element is composed of its properties which includes the children array. Therefore when any child element or text node changes, a new array is created breaking memoization for that element's tree. Sibling elements are unaffected.
But even if you forced the root node to memoize, then no children rerender. That's how react works. Bailing on parent rerender implicitly means that its children have also not changed. Therefore react can only realistically memoize the lowest unchanged node in the tree.
The only way around this would be to let the browser handle the text insertion if the text node properties have not changed. And that would require more intimate knowledge of the text formatting, e.g bold, italics, etc which are currently deferred to the consumer of this library
Problem Changing the text value of a nested block causes all the parents to be re-rendered. Ref this image:
I added the capital 'A' to the 'i' block and the render tree performance looks like:
There seems to be a lot of possibly unnecessary rendering of unchanged leaves/blocks happening. Is there anyway around this?
The editor tree is organized like:
Solution Changing one character in a deeply nested structure should just render that one leaf node? I'm not familiar with the slate core so I'm not sure what a viable solution is. I'm just opening this up for a discussion and ideas (or maybe I'm just using slate/react wrong?? 🤷♂️ )
Maybe using something like mobx inside slate to handle rendering changes could help here?