There's a memory leak in the hyper-link extension which will reliably crash a Chrome tab. To reproduce, go to to the documentation page in Chrome and paste in https://www.npmjs.com/package/@uiw/react-codemirror 3000-4000 times. You can paste them all at once or a couple hundred at a time.
The issue here is that when doc.toString() is in the while loop, a new string is created of the entire document, and Chrome creates a sliced string when running defaultRegexp.exec. That sliced string has a parent reference back to the string created by doc.toString(). That sliced string, with the giant parent reference, gets set as the url state on the HyperLinkIcon widget. The result is that Chrome has in-memory a copy of the entire document for each of the links in the document, and runs out of memory as the document gets large.
Here's what it looks like in a Chrome memory snapshot:
Doing the toString() once outside of the loop creates a single sliced string, and each widget will have a reference to that single string.
I was able to verify locally that this change resolves the memory leak. I was able to paste 100,000 links in my app that uses the hyperlink extension without issue.
There's a memory leak in the
hyper-link
extension which will reliably crash a Chrome tab. To reproduce, go to to the documentation page in Chrome and paste inhttps://www.npmjs.com/package/@uiw/react-codemirror
3000-4000 times. You can paste them all at once or a couple hundred at a time.Here's a recording of the crash:
https://github.com/user-attachments/assets/9b6550a4-7a83-4a26-bad1-a17087a22ec7
The issue here is that when
doc.toString()
is in the while loop, a new string is created of the entire document, and Chrome creates a sliced string when runningdefaultRegexp.exec
. That sliced string has aparent
reference back to the string created bydoc.toString()
. That sliced string, with the giantparent
reference, gets set as theurl
state on theHyperLinkIcon
widget. The result is that Chrome has in-memory a copy of the entire document for each of the links in the document, and runs out of memory as the document gets large.Here's what it looks like in a Chrome memory snapshot:
Doing the
toString()
once outside of the loop creates a single sliced string, and each widget will have a reference to that single string.I was able to verify locally that this change resolves the memory leak. I was able to paste 100,000 links in my app that uses the hyperlink extension without issue.