bevyengine / bevyengine/bevy

Use UiTransform in interactive ui widgets to avoid costly ui layout recalculations

Open
#22,914 0 comments 0 reactions 0 assignees View on GitHub
A-UI C-Performance D-Modest S-Ready-For-Implementation X-Uncontroversial
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 16h
Merged PRs (30d)
171

Description

During research of `ui_layout_system` slow execution (https://github.com/bevyengine/bevy/issues/22909), it was noted that interactive ui widgets that emulate some kind of animation using Node properties like top, left, etc. trigger ui layout recalculation.

Currently layout change invalidates all cached taffy layout until ui root node, which can be costly. So interactive widgets should avoid triggering layout changes if possible.

[In discord discussion](https://discord.com/channels/691052431525675048/743663673393938453/1471192425195241696)
> @nicoburns : I definitely think UiTransform should be used where appropriate (e.g. just animating position). It's always going to be cheaper to avoid layout entirely.

We should evaluate if interactive widgets should use UiTransform in their implementation and update them.

We should provide examples to users of how to build performant widgets.

## Alternative solution

We could wait for taffy layout engine improvements that would reduce the impact of this problem:

[Discord comment by @nicoburns :](https://discord.com/channels/691052431525675048/743663673393938453/1471194949545627831)
> > Improve the layout engine (Taffy) so that it avoids full layout recalculation when it is not necessary.
>
> However, I also think this would be possible. There are two optimisations that come to mind as being relatively easy to implement:
>
> * Implement support for the CSS [contain](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/contain) property. This is a CSS property specifically designed to create the sort of "isolation boundaries" we want. In particular I think contain: size which turns off "content-based sizing" for a node would help a lot here.
> * Scope dirty marking to `position: absolute` nodes, such that changes within the node don't escape out of it (so long as the `position:absolute` node has at least one `left`/`right` inset and at least one `top`/`bottom` inset specified).

Contributor guide

Open the contributing guide

Research direction

Start by tracing the ui_layout_system work and the implementations of interactive UI widgets that animate Node properties such as top and left. Compare those behaviors with UiTransform, identify cases where layout recalculation can be avoided, and update the relevant widgets and user-facing examples; done means the appropriate widgets use UiTransform without changing their intended behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
frontend, performance
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.