Very long delay between textInput and input events

Hello, We have noticed lately using our editor with a very large document that we are experiencing massive delay between the textInput and input events. The profiler image below is for chrome. It seems that chrome has the biggest issue out of all the browsers we test with. It seems to be less severe in Safari, and possibly non-existent in Firefox based on our testing.

I have not been able to determine why this is happening, there appears to be no interference from plugins or even prosemirror.

I’m curious if anyone has ran into this or has any ideas. The replication is pretty strange too. It seems to happen more easily when you type into a blank <p></p> at the end of the visible writing area. I partially wonder if some sort of selection handler is taking up time here since there are hidden elements surrounding the writing area that become visible depending on which element the user is focused. There is a plugin with creates a class on the top of the tree structure which makes that writing area visible. There are many writing areas before/after the selected writing area.

Very hard to explain but, the overall issue is there. If I need to explain something further I can.

At some document size, the DOM (especially editable DOM) just becomes really slow and there’s not a lot we can do about that. The profile doesn’t look like the issue is code-related, but maybe make sure you’re using prosemirror-view 1.18.2 or up, which fixes a performance issue in large flat documents.

I know we are not using 1.18.2+, I’ll get this updated come back here with the results.

Excuse my terrible writing with a mouse. I have done the prosemirror-view update, along with updating the rest of the packages that would be relevant to prosemirror. This is the profiler after that. I have also highlighted in the image ‘a’ and ‘Return’ keystrokes.

It does not seem to have helped much, My feeling is that the browser is possibly blocking the page under the hood, but, it is really hard to say.

1 Like

I agree that the way those flame graphs look suggest that the time is spent in the browser’s code, not ProseMirror (when the library is being slow you’d see much deeper stacks, with library-related function names near the bottom)

I’ve decided to report my findings. It turns out that in chrome, it is very very very bad at handling DOM elements which are hidden, and a lot of them at that. I’m not claiming to be knowledgeable on CSS, but, it seems like the proper way to handle rendering in chrome is to just make the elements invisible using other methods, such as height/width and so on. Using display: none; in chrome seems to come at a cost that you would never expect. It seems to be related to user selection in any case.

1 Like

The application I work on (https://scripto.live) handles a lot of large documents, and we noticed a major performance hit in Chrome past a certain threshold a year or two ago that was much less apparent in Safari and Firefox.

After a lot of profiling and investigating and guessing, we tried turning off spellcheck for the root ProseMirror element. For us, this made a huge difference. On each keystroke, we could observe an enormous amount of garbage collector activity. Turning off spell check reduced the delay significantly.

It seems to affect all versions after Chrome 76. The last time I checked it wasn’t resolved. We have a very simple check in a view plugin:

      if (browser.mac && browser.chrome && browser.chromeVersion > 76) {
        console.warn('spellcheck deactivated due to chrome 77 bug')
        view.dom.spellcheck = false
      }

It’s not ideal (would be nice to just support native spell check in Chrome), but it seems like on every DOM redraw Chrome’s spellcheck reevaluates the entire document after some kind of timeout, possibly just next tick.

Note that any other operations that cause GC thrash (throwing out a large array of objects and recreating the same objects, rather than mutating or selectively deleting and recreating affected nodes) will cause slowdown as well.

Hope this helps! Let me know if just setting spellcheck to false does anything for your problem.

1 Like

I was having the same issue with Chrome using a Mac. Even a modest size document of 1000 lines would bring the editor to an unusable state.

It has nothing to do with ProseMirror, however.

It was AppleSpell taking nearly nearly 100% of my CPU. I tried a bunch of fixes and had some success with content visibility but it came with it’s own set of problems.

The solution I finally came up with was to set spellcheck=false on the main editor. Then I set spellcheck=true for the currently active node, disabling it again when I left the node.

Not a perfect solution but I can again have thousands of lines with basically no lag and spellcheck while you type active. I tested it on Chrome and Safari (Mac only).