elm / virtual-dom

The foundation of HTML and SVG in Elm.
https://package.elm-lang.org/packages/elm/virtual-dom/latest
BSD 3-Clause "New" or "Revised" License
209 stars 80 forks source link

node removal in `_VirtualDom_diffKeyedKids` when prepending items #175

Open sqwishy opened 3 years ago

sqwishy commented 3 years ago

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 commented 3 years ago

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 commented 2 years ago

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

sqwishy commented 2 years ago
  • 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.