To expand on it a little bit, it works with integers here because they are referentially equal in JS.
div [] [
lazy viewSomething 1
,lazy viewSomething 2
]
That is, 1 === 1
and 2 === 2
in JS, you can also do it with strings and booleans if you are passing them around because "somestring" === "somestring"
. What you can’t do is use it with objects or arrays because they are not the same reference:
{ a : 1 } === { a : 1}
// False
So if you were to change the code to this, it would break
div [] [
lazy viewSomething { val = 1 }
,lazy viewSomething { val = 2 }
]
You could maintain the reference equality if you declare them at the top level
something =
{ val = 1 }
anotherSomething =
{ val = 2 }
view =
div [] [
lazy viewSomething something
,lazy viewSomething anotherSomething
]
A common gotcha with lazy rendering is that it is very easy to break in your update
function, you have to make sure that you keep reference equality unless the value really changed, like say you have
type alias Model = { count: Int }
And you were trying to use lazy viewSomething model
. In you update function you’d have to be careful to not change the Model
reference unless the value is really changing.
UpdateCount count ->
{ model | count = count }
The code above always returns a new model
, so lazy will never work even if the new count and the old count are the same, instead you have to do
UpdateCount count ->
if count == model.count then
model
else
{ model | count = count }
In this example lazy wouldn’t do much, but if you are creating a ton of nodes it can make a big difference.
If you are using the lazy2
, lazy3
, lazyN
variants it can be hard to know what parameter is preventing lazy rendering from happening, in 0.18 I used to use a patched version of virtual-dom to print it out, the important bits of code are here https://github.com/elm/virtual-dom/blob/master/src/Elm/Kernel/VirtualDom.js#L738 where it checks for reference equality.