elm-css
elm-css copied to clipboard
Potential Html.Styled.map performance improvements?
VirtualDom.map is O(1) operation. On the other hand, Html.Styled.map traverses the entire tree converting all nodes and attributes. Moreover, view |> map A |> map B requires traversing the tree twice and so on. And in the end it'll be traversed one more time during the toUnstyled call. There should be a smarter way to do this!
A potential solution might be to model the Node with functions:
type Node msg
= Node
{ unstyle : () -> ( VirtualDom.Node msg, Dict Classname (List Style) )
, unstyleAsRoot : () -> VirtualDom.Node msg
}
node : String -> List (Property msg) -> List (Node msg) -> Node msg
node tag props children =
Node
{ unstyle = unstyle tag props children
, unstyleAsRoot = unstyleAsRoot tag props children
}
unstyle tag props children () =
-- Accumulate styles and build a `VirtualDom.Node`, return it all as a tuple.
...
unstyleAsRoot tag props children () =
-- Accumulate and compile styles, insert a `style` element,
-- build a `VirtualDom.Node` and return it.
...
-- This becomes O(1).
map : (a -> b) -> Node a -> Node b
map transform (Node node) =
Node
{ unstyle = node.unstyle >> Tuple.mapFirst (VirtualDom.map transform)
, unstyleAsRoot = node.unstyleAsRoot >> VirtualDom.map transform
}
toUnstyled : Node msg -> VirtualDom.Node msg
toUnstyled (Node node) =
node.unstyleAsRoot ()
I don't think that putting functions inside Node can be problematic since it can contain functions anyway.
Also, there might be another solution, this is just something that came to my mind.
Thoughts?
This is good to think about, but there are a few other performance improvements I want to try first.
The main reason is that my goal is for Html.Styled to become ultimately unnecessary, if we get a way to do "virtual CSS" that does insertRule behind the scenes. At that point, css could be return a plain old elm-lang/virtual-dom attribute and still work the same way as it does now.
I don't know for sure if this is how it will work out, but it's what I'm aiming for, so in the meantime I want to prioritize other performance improvements over Html.Styled-specific ones!
The main reason is that my goal is for Html.Styled to become ultimately unnecessary, if we get a way to do "virtual CSS" that does insertRule behind the scenes. At that point, css could be return a plain old elm-lang/virtual-dom attribute and still work the same way as it does now.
Yeah, this is exactly how I imagined it. But it may take a while before we get support for insertRule, so please consider my ideas as a short-term solution after you're done with other optimizations!