Fix updateNodes() (mostly vdom diffing logic). #2021
Edit: this is done AFAICT
The logic in updateNodes will still need some love for fragments (the last commit is actually sub-optimal, skipping
Few lines of
No formal review requested now since there will be future changes. If @starsolaris and @purplecode want to test the waters, there's a build at https://github.com/pygy/mithril.js/blob/fix-updateNodes-build/mithril.js
How Has This Been Tested?
So far, mostly manually in Flems, I'll have to cook up test cases. There were quite a few bugs.
Types of changes
Just a thought, and I don't want to pile more tasks on top of the great work you're already doing, but I think it would be great if you could sprinkle a few more comments/notes in the code, especially now that you've got a map of it in your head and it's still fresh.
I know that when I'm writing some tricky procedural logic I need to make notes otherwise it'll fade from memory very quickly. Plus I think it would make it more approachable for others to get involved.
There you have it! Rendered here:
This function diffs and patches lists of vnodes, both keyed and unkeyed.
The updateNodes() function:
The lists are only iterated over once, with an exception for the nodes in
There's first a simple diff for unkeyed lists of equal length that eschews the pool.
It is followed by a small section that activates the recycling pool if present, we'll
Then comes the main diff algorithm that is split in four parts (simplifying a bit).
The first part goes through both lists top-down as long as the nodes at each level have
The second part deals with lists reversals, and traverses one list top-down and the other
The third part goes through both lists bottom up as long as the keys match.
The first and third sections allow us to deal efficiently with situations where one or
The fourth section does keyed diff for the situations not covered by the other three. It
If there are still nodes in the new
Then some pool business happens.
It should be noted that the description of the four sections above is not perfect, because those
While this is optimal for unkeyed diff and map-based keyed diff (the fourth diff part),
To determine if a vnode was brought back from the pool, we look at its position in the
At the very end of
The pool eligibility and
DOM node operations
In most cases
The fourth part of the diff currently inserts nodes unconditionally, leading to issues
Edit: Thanks for the offer BTW, please note that this is a v2 build, with different mount/route/redraw timings. I'll backport the changes to the v1 branch once we merge this (and add #1675) and the new events thing to release v1.2, it would probably be less risky to base your testing on that branch.
The Flems env wasn't properly set up (I wasn't removing
@StephanHoyer what's the "random" version? It should be sorted out with the ivi-like diffing I'll add in the coming days anyway (mostly, ivi doesn't support fragments, minimizes the DOM operation based on the sequence of vnodes, that all map to one DOM element... I think I'll ignore that for a start).
@isiahmeadows what do you mean by false negative? The tests in the Flems? The real test suite uses a distinct root for each test, but the Flems is reusing
The tests are fine, don't worry, it was just a bad harness.
…odes in unkeyed lists when old and vnodes don't have the same length Fix #2003 partim 2
…ject that's brought back from the pool
…with actual fragments (fix #1991 partim 2)