question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Full re-render on any tracked property change

See original GitHub issue

I’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:closed
  • Created 6 years ago
  • Reactions:2
  • Comments:10 (8 by maintainers)

github_iconTop GitHub Comments

4reactions
tomdalecommented, Sep 26, 2017

@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 duration or canPlay tracked 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 CachedReferences for tracked properties, and I verified that the cache here was working correctly. Stepping through the reference for the fileUrl, 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’s src.

This seems like an oversight, because all UpdatingOpcodes have a public tag property 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!

1reaction
t-sauercommented, Oct 12, 2017

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 the state property 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, the state property gets set to a new value, which I assume invalidates canvasSize and 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 state property but it might be problematic in other cases.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found