Roblox’s UI renderer fails to batch drawcalls for batchable UI elements (ImageLabels of the same texture, TextLabels, etc) if the Instances aren’t parented one after the other. If another UI element is parented in between (such as a Frame, or an ImageLabel with a different texture as seen below) then it will not batch. In practice, this means that images are rarely (if ever) batched, especially when using a declarative framework like React or Fusion since the elements are being created and destroyed in arbitrary order.
Here’s a repro place (uncopylocked) that uses two textures of icon spritesheets, with a button in the top left to switch between alternating and ordered parenting of their ImageLabels.
Here’s what the drawcalls for this place looks like (see bottom left, Draw UI #)
In this RenderDoc recording, you can clearly see that the spritesheets get batched to a single drawcall when their ImageLabels are parented one after the other and do not batch at all when their ImageLabels are parented alternating between the two asset ids.
I can’t upload RenderDoc Captures directly since the filetype isn’t supported, so here’s a share link instead. https://file.io/FiTwdEOfNIVo
Expected behavior
The developer should not have to worry about parenting things in any specific order for the Roblox renderer to work efficiently.
After further testing, I’ve found that this is the case for any batching. TextLabels do not batch if you parent a Frame between them, for example. It appears the renderer’s batching logic is simply a greedy check using the iteration order of parenting. I’ve updated OP to reflect that this is not specific to Images.
Thanks for your dedicate findings and feedback. The UI system takes tree-insertion order into account for backward compatibility. We would not simply batch everything from the same asset id as if you make them semi-transparent/overlapping with each other, the render result would be wrong if we batch them instead of rendering them in the original order. Similar for the text situation, alpha composition and overlapping cases would have wrong render result if we batch glyphs rendering in TextLabel - Frame - TextLabel render order. However if you have two Text items with transparent background that has render order next to each other as sibling(not considering the global zindex sorting cases), we would try to batch it. Here is a visualization for the render order Beautiful World - Roblox, and we would always look into improvements.