We are experiencing extreme decreased performance when deleting multiline content at the top of a page with lots of content below it since prosemirror@1.20.2. We have debugged the code and noticed that the culprit seems to be in the findNodeMatch in the ViewTreeUpdater. It seems when we delete the rows, the findNodeMatch exits early when looping to find a matching node. This causes all the content below to have its NodeView’s recreated again instead of updating them which is extremely slow.
That change to the lookahead does seem suspicious (it makes it pointless to have a loop at all there, and I don’t remember why I made it) and might be an accidentally committed debugging change.
However, removing the threshold seems like it will make updates where the children are completely replaced with different children quadratic to update, since each child will scan through all the nodes after it.
In the situation you describe, a multi-node deletion at the start of a big node, findNodeMatch should be able to match all the nodes after the deletion, making updating cheap. I set up a simple test case and verified that, at least in my test, this is working.
So, though I’m definitely open to bumping the lookahead back up to 5, I would like to get to the bottom of the performance problem you’re having, since there may be another bug involved. Can you create a simple stand-alone script that produces the problem?
Thanks for getting the threshold PR merged so quickly
We have spent the past few days looking into the issue. It turns out that we were not entering into the preMatch path of the reconcilliation algorithm. We noticed that it was failing as soon as we were doing the if (node != frag.child(fI - 1)) { break } which is obviously a quick memory check. To test we changed it to if (!node.eq(frag.child(fI - 1)) { break } and saw that the performance was restored, but obviously this is not a good fix as its slow. This led us to believe that there was something not right with our code.
It turns out that the issue is actually on our side were we are doing are replacing a node with itself when we shouldn’t be. Once we stopped that from happening, performance was restored