nteract / semiotic

A data visualization framework combining React & D3
https://semioticv1.nteract.io/
Other
2.43k stars 133 forks source link

Eliminate infinite requestAnimationFrame cycle in VisualizationLayer #547

Closed alexeyraspopov closed 2 years ago

alexeyraspopov commented 2 years ago

Whenever VisualizationLayer is used, it spawns renderQueue which handles non-blocking canvas rendering by slicing the data collection into chunks and feeding them to a rendering function. The way how renderQueue is designed right now, the rendering cycle can be aborted via invalidate() method, which is used in componentDidMount in order to stop existing rendering if new data have been received. However, if no update happened and renderQueue went through all the datapoints, there is no termination condition for requestAnimationFrame() calls. Thus, whenever VisualizationLayer is used, the web page will be spawning infinite rAF cycles on each data update which quickly start throttling the rest of the things in main thread just by the number of calls.

This PR adds termination condition to avoid the case where an infinite cycle can be created. Alternative solution would be to properly use invalidate() method when the rendering is done, but it would require some additional places to be updated and tested. I also used forEach for data chunk rendering calls to avoid unnecessary memory allocation caused by Array::map().