Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

State change debounce and supression #46

Open
efpage opened this issue Jun 3, 2023 · 5 comments
Open

State change debounce and supression #46

efpage opened this issue Jun 3, 2023 · 5 comments

Comments

@efpage
Copy link
Contributor

efpage commented Jun 3, 2023

For my understanding, state management in VanJS is event driven. The event is triggered by the state setter and prpagated to all event listeners:

s.listeners.forEach(l => l(v, curV))

For frequent updates this may cause too many calls. A common way to prevent this is a timeout, that prevents retriggering before the timeout has fired.

It may also be useful to have an option to globally disable all events (e.g. during page update or deletion) programmatically with frunctions like van.inhibitUpdate() and van.restoreUpdate().

@Tao-VanJS
Copy link
Member

I feel that the suppression logic can be implemented in event handlers instead of VanJS library.

@efpage
Copy link
Contributor Author

efpage commented Jun 5, 2023

Not sure how to do this. Any suggestion welcome.

Let assume, there are 50 state objects, each changed 500 times per second on an irregular basis. But we want the UI to update only once per second. So we need to inhibit the event propagation, but still remember that the state object was changed. After one second, we want all state objects to fire, if the state was changed in the meantime.

I agree that it is not desired to put this in the core library, but maybe there could be an entry point to apply this kind of logic externally? Something like a event-function (onStateChanged)?

@Tao-VanJS
Copy link
Member

I think the following design pattern can solve your problem:

const appState = ...
const viewState = {
  prop1: van.state(...),
  prop2: van.state(...),
  ...
}

setInterval(() => {
  <Sync `appState` to `viewState`>
}, 1000)

const App = div(
  ...
  // Inside your application, we bind DOM nodes to `viewState`, but only mutate `appState`
  // to handle the state changes.
)

@efpage
Copy link
Contributor Author

efpage commented Jun 5, 2023

It seems, VanJS already contains all it needs:

18:  if (s.oldVal === curV)
19:     changedStates = addAndScheduleOnFirst(changedStates, s, updateDoms,  updateRate);

I added "updateRate" here with an initial value of zero. If I change this to a larger value, updates slow down, but are not skipped. So, adding this value and a setter could simply be enough to prevent event blocking.

@efpage
Copy link
Contributor Author

efpage commented Jun 6, 2023

I made a demo to show the issue with state blocking. This creates 1000 div´s showing different states. This is updating every 1/100 second which may run fluently on a fast machine. But if you increase the number n to 10.000, this starts to slow down your machine.

You can use a slider to reduce the update rate so see the effect.

This demo uses a modified version of VanJS including the simple solution mentioned above.

Check out on flems.io

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants