Layout Groups + Templates = "Layout Shift"

In my project I am building quite complex hierarchies of UI where I use Layout Groups inside other Layout Groups. I’ve noticed that in some instances I get a “layout shift”, where the layouts render one frame in an “incorrect position” before resolving itself the next frame.

I’ve isolated the problem to having a Layout Group that controls the size of a child, which in turn has a Layout Group. If the child in question is created dynamically with cloning or instantiating, the elements inside the child will show up incorrectly one frame. (See image below.)

I’ve followed the engine code to see how the reflow() and sync() functions are being called after the template is spawned:

I.
Outer Layout Group → reflow()
Inner Layout Group → reflow() (However, the “Template Without Layout Group” has not yet received its calculatedWidth & calculatedHeight) → Incorrect layout

II.
Scene is rendered and syncHierarchy() is called (“Template Without Layout Group” gets its calculatedWidth & calculatedHeight)

III.
Inner Layout Group → reflow() (This time the “Template Without Layout Group” has its calculatedWidth & calculatedHeight) → Correct layout

I’ve found a couple of ways to “work around” the issue, but I’m not really sure what the “proper” way of going about it would be.

  1. Add a Layout Group to “Template Without Layout Group” - This causes an additional reflow the first frame. This is possible in some of my cases, but not all of them. For example it doesn’t work for Scroll Views.
  2. Listen to the “reflow” event on the parent layout group in “Template Without Layout Group” and manually call syncHierarchy() on itself - Could work, but I’m a bit afraid of the performance implications and risk of recursion. This is currently my best solution.
  3. “Design around” the problem by not having nested Layout Groups - I don’t want to do this as it severely limits what I can do with templated and dynamic UI.
  4. Other solution that I haven’t found - Maybe the community has a better way of solving this type of issues. :smile:

I understand that it is possible to “design around” a problem like this, but that severely limits what I can do. My project is quite large and complex and it would be great to understand what the best practices are for the engine. For example you might want to do something like this:

A high score list of player results (using a vertical layout group) in a scroll view. The high score list is displayed in a popup that uses layout groups to position a header, the scroll view, and a footer (using another vertical layout group). The high score popup is dynamically spawned into a popup system that yet again uses a layout group to position and scale the popup properly.

I’ve created a small project showcasing the issue:
Layout Shift - PlayCanvas Project