Please help me understand why the process of rendering on an HTML canvas in a 2D context takes so long with several frames falling out of the animation with a large number of points. Moreover, the execution time of the javascript code falls within the allotted 16ms by a large margin, and the main animation time is occupied by the work of the GPU, according to the Performance tab of the developer tools. I will indicate in advance that I am testing on the Google Chrome v122.0.6261.111 browser.
Here I have visualized the problem. In short, there are several datasets (7 to be specific). In each subsequent frame, I draw all data sets with a Y-axis offset of one pixel below the previous frame.
The code is quite primitive – no matrices or path objects. However, the use of matrices, etc. does not affect the problem – the time it takes to send data for rendering by javascript code is reduced, but the operating time of the GPU has almost no correlation with this fact.
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)
ctx.beginPath()
for (let dataset of datasets) {
for (let i = 0; i < dataset.length; i++) {
if (!i) ctx.moveTo(dataset[i][0], dataset[i][1] + count)
else ctx.lineTo(dataset[i][0], dataset[i][1] + count)
}
}
ctx.stroke()
I’ll give you a few screenshots to help you understand what we’re talking about.
Here is a performance measurement on the first frame. Please note that the javascript code execution time barely exceeds 1ms, and the GPU loading time is already more than 50ms! Naturally, several animation frames are dropped.
The situation changes as the data sets go beyond the canvas – the execution time of the javascript code does not change, and the GPU load time decreases accordingly. For example, here is the last frame with one data set on the canvas and the subsequent frames again with all the data sets shown. As you can see, as soon as we have to draw all the data sets in the visible area again, the graphics processor immediately falls under load, again leading to frame drops.
Several facts add interest to the problem:
- In Mozilla, animation is much smoother without such a colossal load on the GPU.
- If you reduce the range of Y values without reducing the number of points for a line, then the animation is smoother. (That is, when the depicted data set tends to a straight line in shape)
In this regard, I have several questions for the community:
- Why does the GPU come into play?
- Is there somewhere a detailed description of the canvas rendering process under the browser hood?
- It seems that the data being drawn is sent to the GPU and sending this data takes a very long time. If this is at least partly true, then is it possible to somehow cache this data in the GPU and update only the transformation matrix? (Let me remind you that other methods known to me to optimize the rendering process (matrices, path objects) do not affect the problem in any way)
- On the other hand, the improvement in animation smoothness with a decrease in the range of Y values indicates that the more pixels are covered on the canvas, the longer the rendering process takes. That is, the amount of data sent to the GPU has little effect on the operating time of the GPU. But if the GPU draws several pixels in parallel, then does it matter how long the line is…?
Thank you in advance, and I really hope that there will be people who can help me figure out at least some of the issues raised.



