Post

Preact Signals just got a huge performance boost: Signals rendered as text/props & effects only "pull" as fast as needed for rendering. Since computeds run as-needed, they now only re-run as often as their downstream DOM output can be painted. H/t to @jovidecroock.com for making this happen.

To be clear, Svelte 5 used to have something like this with our scheduling but we had to back out of it due to some issues that surfaced due to the sequencing of some things not happening soon enough. However, we're going to look into re-enabling some form of it again in the future.

Looking at back why we reverted it, it was because of things like the `disabled` attribute. If you don't apply that in a microtask, then the next event coming in will read the stale value and do the incorrect thing. Flushing template effects on events just gets us back to where we started.

Yes, we had this as well. Effects are scheduled rAF debounced while DOM properties/Text nodes are scheduled in a double microtask so it can slot in with the normal Preact rendering cycle, this prevents the issue.

So the video above is no longer accurate? Unless I’m not following correctly.

0 reposts1 like

Hey Jovi, I'm really intrigued by this double microtask and the necessity of two kinds of deferment. Do you have documentation about this?

Now, signals before these changes were just doing synchronous updates, which isn't great as a signal could synchronously update a prop and then have a Preact component rerender which could be seen as tearing due to these updates not being in lock-step.

I have no idea what you're implying, sorry. I also don't have access to the code of Jason, I am just clarifying that <x disabled=someSignal /> updates differently from useSignalEffect(() => {})