I'm running a simple viewbox animation in raphael using requestAnimationFrame in chrome. I'm noticing all scripting and rendering tasks are completed yet I still see anywhere between 30 and 60ms of "dead space" where it looks like the browser is sitting there doing nothing. Any insight into this?
I went on this question looking for the same answer and as it seems nobody provided a response, here is what I found.
According to the Chrome DevTools documentation about the Clear and Light Grey Frame, the blank space is the time your browser was idle.
Why is it idle?
The short version is that a hollow frame means one of two things: your javascript main thread was busy doing other stuff that the Chrome Dev Team forgot to show in DevTools or you were bottlenecked on your GPU.
To tell the difference, you can enable "Timeline: Show CPU Activity on the Ruler" inside DevTools' settings (you know, the cog in the bottom right hand corner).
You will end with something like this:
See the little dark grey blocks on the "Records" row? Those are dark when the renderer thread was busy. If the renderer thread is mostly idle, e.g. no dark block, as is the case the screenshot I yanked for this post, it is a very good signal that you are GPU bound.
Here's the full explanation from Chrome Engineer Nat Duca.
https://plus.google.com/+NatDuca/posts/BvMgvdnBvaQ
Related
I was first looking at this post from MDN where it says:
"In the painting or rasterization phase, the browser converts each box calculated in the layout phase to actual pixels on the screen... everything occupying the main thread, including calculating styles, along with reflow and paint"
So clearly rasterization happens on the main thread.
However I am looking at this post from Chrome where it defined the Paint step differently:
"Paint: compute a display list that describes how to raster GPU texture tiles from the DOM"
According to this, the Paint step, the MDN post referred to earlier, which comes after recalculating style and layout, is not where rasterization actually happens. According to this Chrome post, it happens on viz process. It seems like it is even a completely different process.
So my question is where exactly did rasterization happen in recent Chrome versions?
Chrome introduced splash-screens as a PWA feature to make it look and feel more like native apps. It generates the splash-screen from name, icon and bg_color in the web app manifest. More details here:
https://developers.google.com/web/updates/2015/10/splashscreen
https://developers.google.com/web/tools/lighthouse/audits/custom-splash-screen
While all of that is fine, there is no proper documentation on how long Chrome decides to keep the splash-screen visible.
Ideally I'd imagine that it should be till the point something is meaningful painted on the screen (just the above-the-fold stuff) but in my experience it seems like Chrome keeps this splash-screen for a quite long time (might as well be till page load?)
This is pretty bad for people browsing my website from slow connections - previously at least they could see something working and happening on the screen, now they just see a static image (splash-screen with icon and name) - they don't know how long it will take to open the web app, can easily get bored and drop-off. This is very risky.
Can I control when the splash-screen goes away or even disable it altogether?
You can register an event of DOMContentLoaded, which is the first event fired, even before your other stuff like images, css and all are still getting loaded. Using this, you can fade out / remove the splash screen even (may be) before when your first paint happens (depending on your site requirements/implementation). Check out an example here, where he tries to add an animation to the fading of the splash screen rather than a simple transition. You can definitely try removing the splash screen earlier on similar grounds.
P.S.: Couldn't find anything to disable/time out splash screen. Hence the work around!
It seems that your first page is taking too long to be ready (first paint), maybe you have:
A big HTML file
Loading stylesheets synchronously
Javascript take long time to settle
Check these things see if resolving each one could help.
You can see other PWA apps, like twitter how they are loading pretty much fast in webAPK and learn from them using chrome dev-tool on your desktop.
Sometimes when I Inspect Element in Google Chrome I find that I have some large frames, but they are filled with white space. Anyone know what often causes such large amounts of empty space? I have seen timers cause issues with extending the frames length but in the example below I am unsure why a frame would be so large.
Would love some help minimizing these
This is documented here, see the 'About clear or light-gray frames' section. 'Clear frames' in question are described there as
Idle time between display refresh cycles.
According to this video, clear bar indicates browser waiting for a CPU or a GPU. There is nothing that developers can do to fix this when working on a 'standard' website.
I found some interesting relations and i hope it will save time for someone (I spent lot of time before figure out all of this)
Most important - chrome devtools cost a lot. A mean A LOT, even if it says nothing about it. For example:
"Screenshots" in performance monitor increases frametime from 16ms to 66ms in my case and just fills it with empty space in timeline - without screenshots and with screenshots. (Now i see long operations on GPU with screenshots, but there's no any info about what exactly particular operation did)
Things in "rendering" tools like "paint flashing" or "fps meter" greatly increase painting operations time. Just be sure that you disabled all of this before analyze performance!
Very strange things happens with "other" segment(Grey color on timeline). It suppose to be devtools cost itself, but sometimes it can randomly be around zero with lot of calculations or be on 100% wile idle. My advice - there's new "performance monitor" tool in new chrome versions (Not simple "performance"). It is better to toggle it on and keep an eye on "CPU usage" timeline. If you see unexpected behavior of gray curve just reload page or whole chrome - it may save lot of time for you.
Some extensions may cause random effects on timeline. It better to disable it too.
Actually any thing in tools or extensions may ruin your measuring. Toggle all of it off before start search out issues in you code, dom, or styles
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!
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.
From my own experience it renders whatever you tell it to render regardless of position on screen.
An example is if you draw tiles, that exceeds the canvas size, you will still see the performance drop unless you optimize the script.
Try your function with a performance demanding animation, and see if you still get the same results.
looking at the resource tracking in chrome. There is a lot of purple instance called
Paint (179x40)
and then when you hover over it it says
Re-calculated style - details
Duration 0 (at 7.14s)
Used Heap size 8.77mb of 11.37mb
And there are hundreds of them. Can someone please explain?
Based on how most GUI programs work, that is the function used to redraw the screen. Any time anything changes on the screen in a GUI program, Paint() is called. I assume that Chrome is following a similar paradigm.