Skip to content

perf(core): only fire RecalcUniforms on dimension changes, not every transform#90

Open
chiefcll wants to merge 1 commit into
mainfrom
perf/recalc-uniforms-on-resize-only
Open

perf(core): only fire RecalcUniforms on dimension changes, not every transform#90
chiefcll wants to merge 1 commit into
mainfrom
perf/recalc-uniforms-on-resize-only

Conversation

@chiefcll

Copy link
Copy Markdown
Contributor

What

Stops raising UpdateType.RecalcUniforms on every Global update and instead raises it only where shader uniforms can actually change: dimension writes and shader assignment.

Why

Any transform change — including pure translation — set RecalcUniforms, so during a row scroll every moving node with a custom shader (e.g. every Rounded/RoundedWithBorder card in a TV grid) invoked shader.update() every frame just to hit the value-key cache and return. Shader uniforms are a function of resolvedProps + node w/h only — that is exactly the shader value-key cache key (CoreShaderNode.createValueKey) — so transform-only changes can never affect them. Any shader that depended on position would already be broken by that cache, which makes this removal safe by the engine's own contract.

How

RecalcUniforms is removed from the unconditional Global-update OR in CoreNode.update() and raised at every props.w/props.h mutation point instead (verified exhaustive by grep across src/core):

  • CoreNode set w / set h
  • Autosizer.applyDimensions (direct props.w/h write that bypasses the setters)
  • CoreTextNode layout application (same)
  • set shader already raised it — this covers initial assignment, including constructor-passed shaders which route through the setter

Shader prop setters already raise the flag themselves (CoreShaderNode.defineProps), and the updateShaderUniforms boolean persists across frames, so a flag raised while a node is off-screen still applies on its first renderable frame.

Testing

  • New unit tests in CoreNode.test.ts ("RecalcUniforms scoping"): translation does not set the flag or invoke the shader updater; w/h changes do both; shader assignment computes uniforms once. The new describe uses a locally-scoped stage mock because the file-level shared mock's bound objects can be mutated by reference by earlier tests.
  • pnpm build passes; CoreNode.test.ts passes (65/65).
  • Visual verification deferred to CI's visual regression run — output should be pixel-identical since uniforms recompute at exactly the same observable points.

🤖 Generated with Claude Code

…transform

Every Global update (including pure translation) raised RecalcUniforms, so
each moving shaded node invoked shader.update() every frame of a scroll just
to hit the value-key cache and return. Shader uniforms are a function of
resolvedProps + node w/h only - that is exactly the shader value-key cache
key - so transform-only changes can never affect them.

RecalcUniforms is now raised exactly where it can matter:
- the w/h setters
- Autosizer.applyDimensions (direct props.w/h write)
- CoreTextNode layout application (direct props.w/h write)
- the shader setter (already did; covers initial assignment)

Shader prop setters already raise the flag themselves.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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