I am reading about optimization in the Elm Guide. It talks about keyed nodes, using US Presidents as an example:
import Html exposing (..)
import Html.Keyed as Keyed
import Html.Lazy exposing (lazy)
viewPresidents : List President -> Html msg
viewPresidents presidents =
Keyed.node "ul" [] (List.map viewKeyedPresident presidents)
viewKeyedPresident : President -> (String, Html msg)
viewKeyedPresident president =
( president.name, lazy viewPresident president )
viewPresident : President -> Html msg
viewPresident president =
li [] [ ... ]
Then give this as an explanation:
Now the Virtual DOM implementation can recognize when the list is resorted. It first matches all the presidents up by key. Then it diffs those. We used lazy for each entry, so we can skip all that work. Nice! It then figures out how to shuffle the DOM nodes to show things in the order you want. So the keyed version does a lot less work in the end.
My confusion is this: If I don't use lazy
inside the keyed nodes, the Virtual DOM still has to diff every entry of the list, even if it can match some keys. It seems keyed nodes' usefulness really depends on the lazy
inside. Is my understanding correct?
Let's consider an example:
Now let's imagine that the user sorts by price:
without keyed nodes, the diffing is going to look like this:
which is going to issue in this example 9 replaceElement
operations with 9 createTextElement
operations (for example, the exact semantics might work slighly differently, but I think the point stands).
The keyed version will understand that the order changed and will issue a single removeChild
and appendChild
for the apple node.
Hence all the performance savings are on the DOM side. Now this is not just for performance, if those lists had input elements, keeping them keyed if you had your cursor in the Apple input, it would stay in the apple input, but if they weren't keyed, it would now be in the banana input.
You are correct that without lazy the diffing still happens, but the diffing is generally the cheap part, the more expensive part is actually patching the DOM, which is what keyed helps prevent.