Skip to content

Simplified UI tree navigation without ghost_nodes #17143

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

ickshonpe
Copy link
Contributor

@ickshonpe ickshonpe commented Jan 4, 2025

Objective

There is a large performance regression in the UI systems in 0.15 because the UiChildren and UiRootRootNodes system params (even with ghost_nodes disabled) are really inefficient compared to regular queries and can trigger a heap allocation with large numbers of children.

Solution

Replace the UiChildren and UiRootRootNodes system params with simplified versions when the ghost_nodes feature is disabled.

Testing

yellow this PR, red main

cargo run --example many_buttons --features "trace_tracy" --release

ui_stack_system
stack

ui_layout_system
unghosted

update_clipping_system
clipping

@ickshonpe ickshonpe added C-Performance A change motivated by improving speed, memory usage or compile times A-UI Graphical user interfaces, styles, layouts, and widgets S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Jan 4, 2025
@BenjaminBrienen BenjaminBrienen added the D-Straightforward Simple bug fixes and API improvements, docs, test and examples label Jan 4, 2025
@alice-i-cecile alice-i-cecile added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Jan 6, 2025
@alice-i-cecile
Copy link
Member

FYI @cart @viridia :)

@viridia
Copy link
Contributor

viridia commented Jan 6, 2025

Yeah I noticed this but didn't comment earlier.

Here's my take: right now ghost nodes are in this kind of quantum superposition state where we haven't committed to keeping them or not. There are three possible outcomes as I see it:

  1. Ghost nodes are rejected, in which case there may not be a need for UiChildren at all, we can just go back to doing things the old way. However, this also means that the reactive strategies developed in bevy_reactor and thorium_ui are dead ends, and we'll need to come up with some other strategy for handling dynamic-conditional and dynamic-iterative children. I've written about this too much already, so I'm not going to elaborate further here.

  2. Ghost nodes get used by BSN for reactivity, which pretty much requires that they be enabled always, in which case the optimizations here will be irrelevant.

  3. Child nodes get reimplemented as relations, in which case all bets are off; any optimizations we do now may or may not be useful in that new world.

The only world in which this PR is really helpful is one in which ghost nodes continue to be supported as an optional feature, and honestly I hope that won't be the case, that we make up our minds one way or another. I'm taking a "wait and see" attitude for now.

That being said, the instant that cart's new relations spawning API drops, I'll be providing an update to thorium_ui which uses the new API and which offers a new and better developer experience, and this will be using ghost nodes. I've been deliberately holding off on promoting any of my ideas until this happens.

@alice-i-cecile
Copy link
Member

alice-i-cecile commented Jan 6, 2025

Yep, I agree with that analysis. I definitely like this as a "merge for now" solution. I suspect we can optimize ghost node performance quite a bit in the future, one way or another, assuming we decide to keep them around. This PR makes sure we have a good target for that work :)

@ickshonpe
Copy link
Contributor Author

ickshonpe commented Jan 6, 2025

I'm not adding any complex optimisations here, I'm just replacing the ghost nodes system param stuff with regular queries for the Children and Parent components when the feature is disabled.

I mostly agree otherwise ghost nodes are needed and shouldn't be optional. The current implementation is really bad though, it doesn't need to be this expensive or allocate and the feature-gate is broken. It there is a 0.15.2 release maybe this could be included, users shouldn't be paying the cost for a disabled ghost nodes feature.

@alice-i-cecile alice-i-cecile added this to the 0.15.2 milestone Jan 6, 2025
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Jan 6, 2025
Merged via the queue into bevyengine:main with commit 17e3b85 Jan 6, 2025
28 checks passed
@UkoeHB
Copy link
Contributor

UkoeHB commented Jan 6, 2025

Btw the ghost-enabled iterator can be optimized by using the design of TextSpanIter.

mrchantey pushed a commit to mrchantey/bevy that referenced this pull request Feb 4, 2025
# Objective

There is a large performance regression in the UI systems in 0.15
because the `UiChildren` and `UiRootRootNodes` system params (even with
`ghost_nodes` disabled) are really inefficient compared to regular
queries and can trigger a heap allocation with large numbers of
children.

## Solution

Replace the `UiChildren` and `UiRootRootNodes` system params with
simplified versions when the `ghost_nodes` feature is disabled.

## Testing

yellow this PR, red main

cargo run --example many_buttons --features "trace_tracy" --release

`ui_stack_system`
<img width="494" alt="stack"
src="https://github.com/user-attachments/assets/4a09485f-0ded-4e54-bd47-ffbce869051a"
/>

`ui_layout_system`
<img width="467" alt="unghosted"
src="https://github.com/user-attachments/assets/9d906b20-66b6-4257-9eef-578de1827628"
/>

`update_clipping_system`
<img width="454" alt="clipping"
src="https://github.com/user-attachments/assets/320b50e8-1a1d-423a-95a0-42799ae72fc5"
/>
@mockersf mockersf removed this from the 0.15.2 milestone Feb 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-UI Graphical user interfaces, styles, layouts, and widgets C-Performance A change motivated by improving speed, memory usage or compile times D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants