Phoenix_live_view: Stateful live view component re-renders even though the assigns have not changed

Created on 13 Apr 2020  路  4Comments  路  Source: phoenixframework/phoenix_live_view

Environment

  • Elixir version (1.10.1):
  • Phoenix version ("~> 1.4.14") :
  • Phoenix LiveView version ("~> 0.11.0"):
  • NodeJS version (v12.7.0):
  • NPM version (6.13.7):
  • Operating system: Mac OS
  • Browsers you attempted to reproduce this bug on (chrome 80.0.3987.163):
  • Does the problem persist after removing "assets/node_modules" and trying again? Yes:

Actual behavior

I have this sample project called tweet_comment which basically displays an editable comment box. If the comment contains a link to a tweet the comment box is able to unfurl the tweet url and display an oembed styled with twitter widgets. At the moment the comment box is a state-full live view component and all events related to the comment box are handle inside this component. The issue that I am facing is that while editing the comment the tweet widgets seems to reload on every key stroke even though the url hasn't changed. This is because I have implemented a hook to this component which reloads the twitter widgets every time the comment box component is updated. To avoid this, In the part of the code where I handle the phx-change event, I tried to return the same socket back if the url inside the comment has not changed hoping that the live view component will not be re-rendered, if the assigns haven't changed. However this doesn't seem to be the case.

Expected behavior

Changing the live view component to just a live view , I was able to see that if the assigns of the socket have not changed, the live view will not be re-rendered and this doesn't seem to be the case for state full live view components. My question is, is this a design decision for state full live view components to always re-render even though the assigns to the socket have not changed or is there a way to avoid this?

Most helpful comment

Thanks. I could not see it because Firefox was blocking the content.

In your case, you have client controlled markup, so you need to add both an id and phx-update="ignore" to the embedded tweet container. If you want to refresh the content, then you can give it a new ID (by using a counter).

We will optimize LV to not apply a DOM patch in the cases you mentioned, but as soon as you have any other assign that changes, you will see it blinking too. So phx-update="ignore" is the way to go.

All 4 comments

@chrismccord I鈥檓 working with @myak2h on this. In case it鈥檚 not clear we believe this may be a bug in LiveView. @myak2h extracted the relevant code into a repository and we鈥檙e hoping you can find some time to take a quick look because we鈥檙e stuck on this. Let us know if there鈥檚 anything we can do to make it easier on you. Thanks!

The issue that I am facing is that while editing the comment the tweet widgets seems to reload on every key stroke even though the url hasn't changed.

How do you detect that the widget is reloading? I have tried it on Firefox and I could not see any issue.

Can you please:

  1. Expand on the reloading behaviour. Maybe use LICEcap to show the bug.
  2. Can you try other browsers and let us know if the behaviour is consistent?
  3. Also, please try master. Maybe I could not reproduce it because it is fixed in master. Make sure to nuke "assets/node_modules" after updating

@josevalim Here is a GIF of the tweet reloading issue https://s4.gifyu.com/images/tweet-reload.gif and I tried using master, reinstalling node_modules, and also with different browsers (Chrome, Safari, Firefox) but the issue seems to still be there.

Thanks. I could not see it because Firefox was blocking the content.

In your case, you have client controlled markup, so you need to add both an id and phx-update="ignore" to the embedded tweet container. If you want to refresh the content, then you can give it a new ID (by using a counter).

We will optimize LV to not apply a DOM patch in the cases you mentioned, but as soon as you have any other assign that changes, you will see it blinking too. So phx-update="ignore" is the way to go.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alexgaribay picture alexgaribay  路  4Comments

morgz picture morgz  路  5Comments

jamilabreu picture jamilabreu  路  5Comments

tmepple picture tmepple  路  4Comments

lukaszsamson picture lukaszsamson  路  5Comments