I have a big markdown file to parse in the browser, and it takes 100% of the CPU to parse it, and in the process my animations become frozen.
Is it possible to somehow yield to the event loop every once in a while?
https://codesandbox.io/embed/qvrw2ywwww
I made this project to reproduce the issue, after the timeout you can see that the animation stops in the middle for a moment.

The image is me running the profiler in my app.
Yield to the event loop every once in a while.
The parsing is done asynchronously blocking the main thread and freezing animations in the page.
Is it possible to somehow yield to the event loop every once in a while?
@fcostarodrigo where during the render cycle are you expecting it to pause?
blocking the main thread
One resolution would be to process off main thread using a web worker.
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
There are also some web worker abstractions that may help simplify the process:
https://github.com/GoogleChromeLabs/clooney
https://github.com/developit/stockroom
I could be wrong, but it looks like the library ReactMarkdown is exporting a single stateless component and the parsing is being done there. So I guess it is on the render phase in React. In the app, this happens when the user pushes a button, while the button is going away the markdown is being parsed and the button freezes mid animation sometimes.
@fcostarodrigo right, where in remark-parse's cycle would yield?
@ChristianMurphy looking at the profiler, I am guessing between calls to tokenise.
@remarkjs/core Thoughts? :thought_balloon:
I feel this is something you鈥檒l run into for every big task in JavaScript. Parsing anything (such as markdown, but also for example syntax highlighting) is a heavy task. And it鈥檒l take up 100% of the CPU. And for big documents that鈥檒l be noticeable. It鈥檚 fastest that way, and I don鈥檛 think it鈥檚 a good idea to build something in to throttle (note: if micromark will become streaming, it would be build in though).
Another thing that may be of interest is, in this case, by using React, you are making good use of the syntax tree. However, syntax trees will always have a big memory footprint compared to a string.
JavaScript already has a system for dealing with this: workers, as @ChristianMurphy mentioned, and unified is pluggable enough to let you parse in a worker, or transform in a worker, or stringify in a worker. I think that鈥檚 the route to take here!
I tried on my side to lazily use react-dom/server in a webworker to make a wrapper for ReactMarkdown but failed miserably since I couldn鈥檛 just make it work from inside a create-react-app 馃槩it looks like it needs to be built outside to be able to use it.
@fazouane-marouane the ongoing discussion in https://github.com/facebook/create-react-app/issues/3660 may offer some pointers and ideas.
Web workers would be added at a higher level of abstraction than remark-parse, https://github.com/rexxars/react-markdown/issues/289 is a good place to discuss the possibility of adding web workers to the react-markdown integration layer.
Most helpful comment
I feel this is something you鈥檒l run into for every big task in JavaScript. Parsing anything (such as markdown, but also for example syntax highlighting) is a heavy task. And it鈥檒l take up 100% of the CPU. And for big documents that鈥檒l be noticeable. It鈥檚 fastest that way, and I don鈥檛 think it鈥檚 a good idea to build something in to throttle (note: if micromark will become streaming, it would be build in though).
Another thing that may be of interest is, in this case, by using React, you are making good use of the syntax tree. However, syntax trees will always have a big memory footprint compared to a string.
JavaScript already has a system for dealing with this: workers, as @ChristianMurphy mentioned, and unified is pluggable enough to let you parse in a worker, or transform in a worker, or stringify in a worker. I think that鈥檚 the route to take here!