Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

node removal in _VirtualDom_diffKeyedKids when prepending items #175

Open
sqwishy opened this issue Jun 10, 2021 · 3 comments
Open

node removal in _VirtualDom_diffKeyedKids when prepending items #175

sqwishy opened this issue Jun 10, 2021 · 3 comments

Comments

@sqwishy
Copy link

sqwishy commented Jun 10, 2021

Hi. I noticed that if I had a sequence of keyed items and, in an update, more than one element was inserted at the start of the sequence, the existing dom nodes would be removed and readded by the vdom diff/patch thing.

That is; if my keys are ...

["foo0", "foo1"]

... and after an update they become ...

["bar0", "bar1", "foo0", "foo1"]

Then the nodes for "foo0" & "foo1" will be removed and reinserted into a new fragment or something. They end up losing any state they had such as text selection and animation state. I would expect instead that the patch just insert "bar0" & "bar1" into foo's parent. (This is the behaviour when items are appended, so if the two bars came after the two foos instead of before.)

Also, this does not happen if there is only one item inserted at the beginning, since _VirtualDom_diffKeyedKids seems to peek ahead one to check for this case explicitly.

I really believe the current behaviour is incorrect, even if it's more efficient or something somehow. Moreover, this behaviour makes Elm unsuitable for me to use for my project. And this saddens me greatly since I am quite fond of Elm.

Is there something that can be done about this? Either some escape hatch for me in my project so I can manage the dom modifications for these nodes explicitly? Or the possibility of changing the behaviour of VirtualDom? I am open to helping in the implementation of a solution or any other way I can.

@sqwishy
Copy link
Author

sqwishy commented Jun 19, 2021

I made a snippet to reproduce the issue and Peter on elmlang.slack.com made an Ellie for it so it's easy to see and play around with.

@voneiden
Copy link

Well blimey, I just stumbled upon the same thing. Did you come up with any neat tricks for a workaround? Off the top of my head

  • If rendering rows in a list, use css to flip the order of rows (display: flex, flex-direction: column-reverse)
  • Route every list update Msg first out of elm via a port, and then one by one (requestAnimationFrame?) route them back in. Mildly insane, but it might just work.

@sqwishy
Copy link
Author

sqwishy commented Sep 18, 2021

  • If rendering rows in a list, use css to flip the order of rows (display: flex, flex-direction: column-reverse)

I wound up doing something along these lines. I gave up on using Elm on my project shortly thereafter, so I didn't try using the implementation very much to determine whether or not there were any unforeseen caveats.

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

No branches or pull requests

2 participants