Full re-render on any tracked property change
See original GitHub issueI’ve noticed that if I change any tracked property all the tracked properties seem to be updated. This only happens with @glimmer/application >= 0.7.0.
This demo expresses the problem by rendering an audio element.
When getMetaData or onCanPlay gets called then setting this.duration = this.audio.duration; or this.canPlay = true; causes the fileUrl on the audio element to also be changed, which triggers getMetaData and onCanPlay again.
Reverting to @glimmer/application 0.6.0 fixes the issue. Also just making the audio elements src static mitigates the issue (not really a solution though).
Issue Analytics
- State:
- Created 6 years ago
- Reactions:2
- Comments:10 (8 by maintainers)
Top Results From Across the Web
Ember Octane, Tracked property not rerendering template
It only works when I go to another page and then come back. But there is no rerender of the page. Can someone...
Read more >React Tracked: Manage state and prevent excessive re ...
Each component re-rendered regardless of whether the state was updated. Ideally, the component should re-render only when the state is changed.
Read more >Tracked Properties - Octane Upgrade Guide - Ember Guides
Tracked properties replace computed properties. Unlike computed properties, which require you to annotate every getter with the values it depends on, ...
Read more >Re-render a React Component on Window Resize | Pluralsight
Now we have set up some internal state, dimensions , that has height and width properties. Inside handleResize , we no longer simply...
Read more >4 options to prevent extra rerenders with React context
This is because useContext will trigger rerender whenever the context value is changed. This happens even if the part of the value is...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

@code0100fun First, thank you so much for the reproduction, it made looking into this easier than it should have been. 😛
You have uncovered a very bad bug that frankly I’m surprised we didn’t notice earlier. It looks like it actually has nothing to do with tracked properties or their invalidation at all.
Stepping through the reproduction, I verified that setting
durationorcanPlaytracked properties invalidated only those properties. Next, I set a breakpoint inside the tracked property getter so I could take a peek at the values when they were being consumed inside the main updating VM loop.We vend
CachedReferencesfor tracked properties, and I verified that the cache here was working correctly. Stepping through the reference for thefileUrl, it returned the cached result because its tag had not been invalidated.To my horror, I realized that we eagerly re-set every dynamic attribute even when the value has not changed. I believe we didn’t notice it until now because attribute sets tend to be idempotent—except, of course, in cases like setting an
<audio>element’ssrc.This seems like an oversight, because all
UpdatingOpcodes have a publictagproperty that could (and should) be validated before evaluating the opcode. I think the fix should be embarrassingly simple.Thank you to everyone who raised this issue and provided very actionable reproduction cases. We will get a fix out for this ASAP!
I am still seeing this problem (or at least I assume that it is the same problem) with 0.8.0-alpha.9.
I upgraded Glimmeroids which uses a canvas. The width and height attributes of the canvas get set in the template (https://github.com/t-sauer/Glimmeroids/blob/59eb5bb2cb0ab2d5dd00007a02b1ace407ca0d07/src/ui/components/Glimmeroids/template.hbs#L31).
The values for that come from a getter function(
canvasSize) which tracks thestateproperty of the component (the screen size is stored in there, https://github.com/t-sauer/Glimmeroids/blob/59eb5bb2cb0ab2d5dd00007a02b1ace407ca0d07/src/ui/components/Glimmeroids/component.ts#L96). Now when pressing an arrow key, thestateproperty gets set to a new value, which I assume invalidatescanvasSizeand sets the width and height on the canvas element again (which leads to visible flashing when playing the game).I guess in this case it can easily be solved in the app by moving the screen size out of the
stateproperty but it might be problematic in other cases.