OS-83133: opt-in synchronous React mounts via flushSync predicate#3
Draft
ilyakogan wants to merge 3 commits into
Draft
OS-83133: opt-in synchronous React mounts via flushSync predicate#3ilyakogan wants to merge 3 commits into
ilyakogan wants to merge 3 commits into
Conversation
React 18's createRoot().render() yields between roots, so a template
that mounts many siblings via {{[name]}} produces a visible mount
cascade (each root's commit + paint + passive-effect completes before
the next root's render starts).
Host apps can now register a predicate via setSyncMountPredicate; when
it returns true for a resolved component name, that mount wraps the
.render() call in flushSync so all matching siblings mount in the same
task and the browser paints once.
shouldSyncMount was reading _reactComponent, which is only populated
for {{react-component foo}} positional invocations and is undefined
for the common resolver-driven path ({{my-react-comp}} /
DI-registered components). Stash parsedName.fullNameWithoutType as
_resolvedName on the wrapped subclass at resolution time, and prefer
it over _reactComponent at render time so the predicate sees a stable
name in every invocation style.
Explain at the call site why we have two render paths (concurrent yielding vs. single-task sync) and what _resolvedName is for, so a reader who hasn't internalised React 18's scheduler / Ember's resolver flow can follow what's happening without leaving the file.
ilyakogan
marked this pull request as ready for review
June 1, 2026 15:54
ilyakogan
marked this pull request as draft
June 4, 2026 11:57
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Jira ticket: https://optibus.atlassian.net/browse/OS-83133
setSyncMountPredicate(inaddon/utils/sync-mount.js) so host apps can opt specific components into synchronous React 18 mounts. When the predicate returns true for a resolved component name, that mount wrapsroot.render()influshSync, so all matching siblings mount in the same task and the browser paints once instead of producing a visible cascade across roots.parsedName.fullNameWithoutTypeas_resolvedNameon the wrappedReactComponentsubclass during resolution, and prefers it over_reactComponentat render time. Without this, the predicate only ever saw a name for{{react-component "foo"}}positional invocations; for the common resolver-driven path ({{my-react-comp}}, PascalCase, DI-registered components)_reactComponentis always undefined and the feature never engaged.Local results (chronos, optivelo)
Tooltip with 6 React roots (
WarningsSection,TripIdSection,ServiceIdSection,VehicleTypesSection,TaskTooltipLowerPart,TooltipButtons), measured via[tt-perf]per-component logs.Initial open — total time until last root committed
Add-trip mid-flow (3 roots appearing after route selection)
Trace excerpts (before / after) — last root's
committedtimestamps from the same tooltip:Numbers are from a local chronos dev build with optivelo.