Preempt

Preempt lets the browser update optimistically before the server responds, instead of waiting on the round trip.

The handler behind the first button sleeps for two seconds to simulate a slow operation; hlivekit.PreemptDisableOn disables the button in the browser immediately on click, before the event even reaches the server. The second button has no such binding, so it stays clickable — and quietly queues up multiple pending increments — for the full two seconds.

Click both buttons a few times to see the difference.

Live Demo

Source

package examples import ( "context" "time" l "github.com/SamHennessy/hlive" . "github.com/SamHennessy/hlive/hhtml" "github.com/SamHennessy/hlive/hlivekit" ) // PreemptDemo is a live, interactive instance of the Preempt example, served // for the "Live Demo" iframe. func PreemptDemo() *l.Page { page := l.NewPage() page.DOM().Title().Add("Preempt Example") page.DOM().Head().Add(Link(Rel("stylesheet"), Href("https://cdn.simplecss.org/simple.min.css"))) countWith := l.Box(0) // Forced to a Component (rather than the hhtml Button() tag builder) // because its click binding is attached after creation. btnWith := l.C("button", countWith) btnWith.Add(hlivekit.PreemptDisableOn(l.On("click", func(_ context.Context, _ l.Event) { time.Sleep(2 * time.Second) countWith.Lock(func(v int) int { return v + 1 }) btnWith.Add(l.AttrsOff{"disabled"}) }), )) countWithout := l.Box(0) btnWithout := l.C("button", countWithout) btnWithout.Add(l.On("click", func(_ context.Context, _ l.Event) { time.Sleep(2 * time.Second) countWithout.Lock(func(v int) int { return v + 1 }) }), ) page.DOM().Body().Add( Header( H1("Preempt - Client Side First Code"), P("Update the client side DOM before the server side."), ), Main( P("The handler will sleep for 2 seconds to simulate a long processing time. "+ "The first button will be disabled in the browser first to prevent extra clicks. Now click the "+ "buttons as many times as you can to see the difference"), "Clicks With: ", btnWith, Br(), "Clicks Without: ", btnWithout, ), ) return page }