hexops / vecty

Vecty lets you build responsive and dynamic web frontends in Go using WebAssembly, competing with modern web frameworks like React & VueJS.
BSD 3-Clause "New" or "Revised" License
2.79k stars 144 forks source link

Explicit no-change render node #262

Open undeconstructed opened 4 years ago

undeconstructed commented 4 years ago

(This overlaps with #217 and similar.)

I've only just found Vecty, and maybe I'm getting ahead of myself, but I'm wondering about the amount of work involved in creating and comparing the render trees for big pages that don't significantly change between renders.

E.g. if I have 1000 elements in my page, there's a good chance that 990 don't change ever, and also that these elements are grouped together.

Is there a method (or would a change be considered) of allowing explicit no-change render nodes, maybe something like:

func NewPageView() *PageView {
    p := &PageView{}

    p.header = memoise(p.renderHeader())
    p.child = &ChildView{}
    p.footer = memoise(p.renderFooter())

    return p
}

func (p *PageView) Render() vecty.ComponentOrHTML {
    return elem.Body(
        p.header,
        child,
        p.footer,
    )
}

The explicit storage of the subtree would avoid accidental changes, and also shortcut the tree comparison by allowing a version id to be embedded in the real DOM.

Thoughts? Thanks!

pdf commented 4 years ago

You generally shouldn't be triggering a re-render of the entire page unless an element at the top level changes - when you submit a vecty.Rerender(Component) to add a component to the render queue, only that component and its sub-tree are updated.

During re-render, an in-memory representation of the elements is diff'd against the desired state, and DOM operations are only performed when necessary, so rendering should already be relatively cheap in any case, unless there are actual changes required.

slimsag commented 2 years ago

Also note the RenderSkipper interface allows a component to decide for itself if rerendering should not occur: https://pkg.go.dev/github.com/hexops/vecty#RenderSkipper