Skip to content

fix!: Wait for children added in onLoad before marking a component as loaded - #3999

Open
spydon wants to merge 1 commit into
fix/wait-for-full-tree-loadfrom
fix/gate-component-load-on-children
Open

fix!: Wait for children added in onLoad before marking a component as loaded#3999
spydon wants to merge 1 commit into
fix/wait-for-full-tree-loadfrom
fix/gate-component-load-on-children

Conversation

@spydon

@spydon spydon commented Aug 14, 2026

Copy link
Copy Markdown
Member

Description

Stacked on #3998.

Previously, when a component was added to a running game and its onLoad added children of its own, the component was marked as loaded (and could mount) as soon as its own onLoad future completed, while its children were still loading. The children then mounted one or more ticks later, so the component was visible and updating with an incomplete subtree.

With this PR a component only counts as loaded once every child that was loading when its own onLoad settled has finished loading too, recursively (children gate the same way, so grandchildren added in a child's onLoad are covered). Concretely:

  • Component._finishLoading now waits, through the internal loadSettled future of each loading child, until no child is loading anymore, before completing loaded/isLoaded. Everything stays fully synchronous when there are no loading children.
  • Since the whole subtree is loaded by the time the component mounts, the children mount in the same lifecycle processing pass as their parent: once the parent's mounted future resolves, the subtree is mounted.
  • A child that fails to load does not block its parent; it is dropped when the parent mounts, exactly like a failing child of an already-mounted parent, and its error reporting through Component.loaded/the current Zone is unchanged.
  • Removing a child that never finishes loading from a still-loading parent re-evaluates the wait and unblocks the parent.
  • Children that are not loading yet when the parent finishes its own onLoad (for example children passed to the constructor of a detached component) keep the existing behavior of loading when the parent mounts.

Checklist

  • I have followed the Contributor Guide when preparing my PR.
  • I have updated/added tests for ALL new/updated/fixed functionality.
  • I have updated/added relevant documentation in docs and added dartdoc comments with ///.
  • [-] I have updated/added relevant examples in examples or docs.

Breaking Change?

  • Yes, this PR is a breaking change.
  • No, this PR is not a breaking change.

Migration instructions

A component's loaded future and isLoaded getter now also wait for the children that were added during its onLoad:

  • If you relied on a component mounting while its children were still loading (for example to show a placeholder while a child streams in assets), add such children after the component has mounted (for example in onMount) instead of in onLoad.
  • A child's onLoad must not await its parent's loaded future, since the parent now waits for the child, that would deadlock.

Related Issues

Related to #3997

@spydon
spydon marked this pull request as ready for review August 14, 2026 22:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant