Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do browsers render canvas elements that are not inside the viewport?

I have a page that has pretty heavy (mid-weight rather) canvas operations going on. To cater for users on mobile devices and older computers I was thinking I could implement a mechanism that will check if the canvas element is actually visible and decide if the constant calculations and canvas updates (animation running at 30fps) do have to be done or not.

This is working fine, yet when doing a performance test with the Chrome Dev Tools I noticed that even when I disable my visibility check and just let things render all the time the CPU usage of the function in question drops quite a bit when no part of the canvas element(s) is visible (although in theory it should still be performing the same tasks). So: at least on my computer running Chrome 17 it does not make a real difference if I check for the element's actual visibility.

To cut a long story short: Do I need to do this or are browsers smart enough to handle such a case without even telling them (and I can save the visibility checking)?


EDIT:

So I made some "research" on this topic and built this fiddle.

What happens is that it just generates noise at 30 frames per second. Not too pleasing to the eye but, well... The upper part is just a plain div to block the viewport. When I scroll down and have the canvas element in the viewport CPU Usage tells me it's taking up about 40%, so apparently the browser does have quite a lot to do here. When I scroll back up so that I just have the maroon colored div in my viewport and profile the CPU usage it drops to sth around 10%. When I scroll back down: usage goes up again.

So when I implement a visibility check like in this modified fiddle, I do see an increase (a tiny one to be honest) in CPU usage instead of a drop (as it has the additional task of checking if the canvas is inside the viewport).

So I am still wondering if this is some side effect of something that I am not aware of (or I am making some major mistake when profiling) or if I can expect browsers to be smart enough to handle such situations?

If anyone could shed a light on that I'd be very thankful!

like image 840
m90 Avatar asked Mar 22 '12 10:03

m90


People also ask

How browser rendering works behind the scenes?

A simple text and image are rendered on the screen. From previous explanations, the browser reads raw bytes of the HTML file from the disk (or network) and transforms that into characters. The characters are further parsed into tokens. As soon as the parser reaches the line with <link rel="stylesheet" href="style.

How does canvas work HTML?

The HTML <canvas> element is used to draw graphics, on the fly, via scripting (usually JavaScript). The <canvas> element is only a container for graphics. You must use a script to actually draw the graphics. Canvas has several methods for drawing paths, boxes, circles, text, and adding images.


1 Answers

I think you're confused between whether the logic is running and whether the rendering is happening. Many browsers now hardware-accelerate their canvases so all rendering happens on the GPU, so actual pixel pushing takes no CPU time anyway. However your tick function has non-trivial code to generate random noise on the CPU. So you're only really concerned over whether the tick function is running. If the canvas is offscreen, it certainly won't be rendered to the display (it's not visible). As for the canvas draw calls, it probably depends on the browser. It could render all draw calls to an off-screen canvas in case you suddenly scroll it back in to view, or it could just queue up all the draw calls and not actually do anything with them until you scroll the canvas in to view. I'm not sure what each browser does there.

However, you shouldn't use setInterval or setTimeout for animating Canvas. Use the new requestAnimationFrame API. Browsers don't know what you do in a timer call so will always call the timer. requestAnimationFrame on the other hand is designed specifically for visual things, so the browser has the opportunity to not call the tick function, or to reduce the rate it's called at, if the canvas or page is not visible.

As for how browsers actually handle it, I'm not sure. However, you should definitely prefer it since future browsers may be able to better optimise requestAnimationFrame in ways they cannot optimise setInterval or setTimeout. I think modern browsers also reduce the ordinary timers to 1 Hz if the page is not visible, but it's definitely much easier for the browser to optimise requestAnimationFrame, plus some browsers get you V-syncing and other niceness with it.

So I'm not certain requestAnimationFrame will mean your tick function is not called if the canvas is scrolled out of view. So I'd recommend using both requestAnimationFrame and the existing visibility check. That should guarantee you the most efficient rendering.

like image 170
AshleysBrain Avatar answered Sep 28 '22 06:09

AshleysBrain