A lot of topics in the internet say that static UI elements should be moved to their own canvas, while dynamic UI elements should have their own canvas, because it allows to not redraw static elements in each frame. Perhaps I got smth wrong, because I have tried this but Frame Debugger shows that elements from both canvases are redrawn in each frame.
My canvas structures(‘Dynamic’ image have simple script to rotate it in z axis, ‘StaticElementsCanvas’ have simple images only):
Unchanged canvases are redrawn, everything on the screen is redrawn every frame. They’re not recalculated, though - ie. layout groups are not handled and meshes are not rebuilt etc. So it’s a CPU saving thing to move them to their own canvas.
Oh, and note that having several canvases isn’t cost free, things on different canvases can’t get batched together. So if you have very many elements that change independently, but they change very rarely, then it’s probably not going to be worth it to split each of them into their own canvas.
This is one of the points where you shouldn’t listen to somebody saying “don’t optimize prematurely”, because rebuilding the hierarchy of a canvas is an impressive amount of work, and by following a bunch of performance common practices, you’re probably going to save a bunch of time.
I have tried to achieve and see by my own effect from youtube guides, where author move dynamic object to another canvas and get +100-200 fps. And I ahve though that it should be displayed in ‘Frame debug’ in some way, but all ‘Draw Mesh’ calls looks the same for elements from static and dynamic canvases
So is advice move every UI window to its own canvas its a bad advice?
Because while waiting for answers I have tried different approach to lower ‘Draw Mesh’ calls, by moving different screens of ui to different canvases and then disabling them if they are not visible. And ‘Frame Debug’ says it works and displays only visible on the screen elements, as you say, but not displays elements from not active canvases
Here is my manager to control which canvas will be rendered. As for me it looks effective, because it resolved my other issue when overlayed screens are keep being rendered, but I need your opinion to be sure I havent created some trash. Perhaps it overkill and disabling screens inside same canvas by ‘SetActive(false)’ is enough?
Canvases that are not supposed to be visible should be SetActive(false). The canvas group alpha is more for fading in/out entire canvas parts.
If you have entirely different UIs (like a shop and an in-game menu) that are not going to be visible at the same time, I’d for sure have them on different canvases - there’s no reason to have them share a canvas.
One more thing, it’s better to do someCanvas.enabled = false than setting the whole game object as inactive. Because canvas will do the whole rebuild when you go with SetActive(true), while just enabling it will not.