Codemirror v6.0.1 leaks

I’ve been investigating memory leaks on my application and have realized that Codemirror leaks. Tested on v5, then moved to v6.0.1, and still the leaks occur.

I’ve created the most basic test to check the leak:

To replicate:

  • Open the stackblitz, wait for the application to show.
  • Click Open Preview in New Tab, then connect.
  • Open Chrome DevTools on Memory tab.
  • Select Heap Snapshot and select the profile that ends with .webcontainer.io: Main.
  • Click on Destroy in the web page.
  • Click Take Snapshot from Memory.
  • Instead of All objects, look at “Objects retained by detached DOM nodes”.
  • You will find the following objects:

As seen all of those objects have leaked, even though the corresponding editor.destroy() function was used. It does not seem that the EditorView can be destroyed completely in v5 or v6.

Are there any plans to resolve those leaks?

That script looks like it is still holding on to the editor variable when you’re doing this measurement. That’s obviously going to hold on to the structures linked from that object.

I’ve modified the script to nullify editor. Still there are lots of detached nodes.

export function destroy() {
  editor.destroy();
  editor = null;
}

An example of the Detached EditContext:

An example of the first Detached HTMLDivElement:

Note that before clicking Destroy, if you take a heap snapshot, there are 0 detached nodes.

I can reproduce this. Seems Chrome’s new EditContext feature leaks cyclic event handlers. I’ve reported Chrome issue 353650038, and added a CodeMirror patch to work around the issue.

3 Likes

I can confirm that by overriding @codemirror/views to 6.28.5 version which you have just published with the fix above, there a 0 detached views left :white_check_mark: Thank you!


Any chance you could port this into Codemirror v5 latest as well?

Reproduction: Codemirror v5 Leak - StackBlitz

There are already few detached nodes when the editor is created:

And they remain after toTextArea is called and editor is nullified.

Examples of the nodes:

  • Detached HTMLPreElement:
    image

  • Detached Text: The text nodes seem to all have value x for some reason

  • Detached HTMLBRElement, first one has parent pre.CodeMirror-line-like.

That code doesn’t use EditContext, so I don’t think it has the same issue that this patch fixes.

I understand that it’s not the same patch/fix. If you’re still maintaining v5, I’d be happy to open up another discussion here.

You’ll have to show that version 5 actually leaks though, because I don’t really see any evidence of that.

I’m not sure what you mean by you don’t see evidence.

In the stackblitz provided above, before CodeMirror instance is created, there are 0 detached nodes. Once it is created, there are 100 detached nodes. Even after it is destroyed, there are 100 detaches nodes.

The Detached HTMLPreElement is actually a pre.CodeMirror-line-like element, and it is retained by CodeMirror.

The other detached elements also show that they are retained by CodeMirror.

In any case, there’s nothing else on the page that could create or retain nodes as it only has CodeMirror imported.

Right, there’s a single <pre> element with some <br> children, being preserved by a cache. Creating more editors will not cause more such elements to be allocated. I don’t think that’s going to take down your website though. This is a wontfix.

2 Likes

You are right, the detached nodes number does not increase with every creation. Thank you!