revery-ui / revery

:zap: Native, high-performance, cross-platform desktop apps - built with Reason!
https://www.outrunlabs.com/revery/
MIT License
8.06k stars 196 forks source link

Performance: Cache LayoutNodes #220

Open bryphe opened 5 years ago

bryphe commented 5 years ago

Today, we regenerate our 'LayoutTree' that we pass to @jordwalke 's flex library. We do this every render frame.

This is bad for performance for a couple reasons:

We should optimize this pipeline by keeping layout nodes around, and just updating their style properties between renders.

A good place to start is here: https://github.com/revery-ui/revery/blob/e92692897f0e5dbec6a03f5695076125f6069c1e/src/UI/Node.re#L195

This method, toLayoutNode, recreates a node every time. We should store it instead with the Node, and update it when the styles change. Special care will need to be taken to make sure we handle the 'measure' cases correctly.

wokalski commented 5 years ago

In Brisk, every node has a layout node associated to it as part of the OutputTree's node type.

bryphe commented 5 years ago

I think that makes sense for revery too 👍

jordwalke commented 5 years ago

Unfortunately it's a very imperative mutable API, yeah. Is layout performed in a completely separate pass, in a separate tree?

bryphe commented 5 years ago

@jordwalke - yep, layout is performed in a separate pass (using flex). The issue with revery is we're regenerating the layout tree every frame, which is very inefficient. Especially since flex can use the results of previous computations in some cases.

jordwalke commented 5 years ago

Oh wow! Is this easy to fix? I really do wish everything could be completely immutable and I wish someone would build an immutable version of flex layout! That sounds pretty challenging though.

IwanKaramazow commented 5 years ago

@jordwalke why challenging?

jordwalke commented 5 years ago

@IwanKaramazow Because flexbox is such an edge-case ridden dirty algorithm. Or - maybe it only seems so because all the implementations are imperative and mutative? I would love for an efficient immutable version of Flex that would produce a new version of the absolute position tree given the previous absolute position tree, the previous style tree, and an update command.