Think of it this way:
A panel generates a 3d model of all the sprites and labels inside of it. A 3d model can't be modified run time - you have to destroy the old one and make a new one if a single little Quad needs to move.
This means for every panel, if anything moves inside of it, the model has to be recreated. The old model becomes garbage, which obviously needs to be GCed at some point.
If you wrap every single widget in a UIpanel, then you would essentially re-create the old GUITexture / GUIText system where it did just that. Every panel costs a single draw call , so to make things faster since draw calls are (relatively) expensive, we batch things together to the aforementioned 3d models.
The optimal way to do it is with these guidelines:
- Put everything that updates rarely or never in an overarching UIPanel
- Put things that need to change often( more than rarely), into their own panels (slide ins, notifications, scores).
- Where possible, animate the UIPanel instead of the widgets as this just means moving the 3dmodel which is cheap.
On mobile you can run 100 draw calls without breaking a sweat (on newer devices).