perf(core): only fire RecalcUniforms on dimension changes, not every transform#90
Merged
Merged
Conversation
…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>
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.
What
Stops raising
UpdateType.RecalcUniformson 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) invokedshader.update()every frame just to hit the value-key cache and return. Shader uniforms are a function ofresolvedProps+ nodew/honly — 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
RecalcUniformsis removed from the unconditional Global-update OR inCoreNode.update()and raised at everyprops.w/props.hmutation point instead (verified exhaustive by grep acrosssrc/core):CoreNodeset w/set hAutosizer.applyDimensions(directprops.w/hwrite that bypasses the setters)CoreTextNodelayout application (same)set shaderalready raised it — this covers initial assignment, including constructor-passed shaders which route through the setterShader prop setters already raise the flag themselves (
CoreShaderNode.defineProps), and theupdateShaderUniformsboolean persists across frames, so a flag raised while a node is off-screen still applies on its first renderable frame.Testing
CoreNode.test.ts("RecalcUniforms scoping"): translation does not set the flag or invoke the shader updater;w/hchanges 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 buildpasses;CoreNode.test.tspasses (65/65).🤖 Generated with Claude Code