6

I am designing basic software for smart wireless lighting systems. The software is GUI based, and I have a slider for the brightness setting of a light in my GUI. The lighting system has a RESTful API so I can listen to changes on the slider value and make an HTTP request with the value to the system. The thing is, it seems utterly naïve to make new HTTP requests with every single change of value.

For example, if the user changes the slider value from 70 to 20, the software would make 50 HTTP requests.

How do people tackle this kind of problem? Do I wait after each request for a defined duration? What is the best practice to overcome making almost a hundred requests?

  • 1
    What does a user expect to happen when they move the slider? Is this a physical slider you interface with or a GUI slider in software? – JPhi1618 Sep 7 '17 at 16:43
  • GUI slider in software sorry for not clarfying that. – Eralp Şahin Sep 7 '17 at 16:48
  • This would be better on UX than here. – Blrfl Sep 7 '17 at 17:15
  • 2
    @Blrfl, I'm not sure about that. This question is about preventing unnecessary traffic, which is a software development concern. Less about whether a slider is the right control for the job. – Berin Loritsch Sep 7 '17 at 17:25
  • 1
    If you click the slider to begin and release to end, you could make the mouse-up action the trigger for a request. It wouldn't work with keyboard input, but you could make pressing enter do the same thing. – Andrew Piliser Sep 7 '17 at 21:59
9

It really depends on how you intend to provide feedback and how quickly your hardware controller can respond. There is more than one way to handle this, and the correctness of the solution really depends on what your users expect. In fact, the potential solutions are not mutually exclusive.

  • Send request after n milliseconds of a stable value
  • Send request every n milliseconds during change
  • Send request after a value change of n

For the nominal case, 100ms feels immediate to most users. However, if your light controller takes 250ms to respond, that's really your limiting factor. That time frame is not too bad and still feels responsive.

The problem you are facing is actually common to sliders in general. Because they can cause a lot of events to be sent, your UI can get bogged down listening to them--particularly if there are other on screen updates.

Since you are controlling a lighting system, I would take a few measurements:

  • How quickly does the lighting system respond? (time to visible change)
  • What is the threshold of change that is actually noticeable? (how many increments before I notice the change of light intensity)

Given that information, you can come up with a sufficient plan so that the lighting system feels responsive, but you aren't bombarding your device with requests faster than it really can respond.


The reason I said that it depends on how you intend to provide feedback is because the different solutions have an implication on how your software is perceived:

  • Debounce (after n milliseconds of no change): there is no visible feedback until the user stops playing with the slider
  • Time Rate Limiting (every n milliseconds during change): there is continual feedback at a rate the system can handle
  • Value Rate Limiting (after value change of n): feedback comes at a rate that is actually noticeable

If you combine all three options, it would work like this:

  • While the slider is being controlled:
    • We send no updates before "n" milliseconds
    • We only send a request if there is a delta of "x" between last request and now
  • When the slider is steady:
    • We send one last update after "n" milliseconds of rest

Again, it's important to know now the different options affect your users and what they would expect.

1

The term you're thinking of is "debounce". That is performing an action only once within a timeframe or after a certain time of inactivity where that action is requested multiple times.

In Javascript performing the action after a time of inactivity would look like:

var timer = null;
var action = () =>
{
    clearTimeout(timer);
    timer = setTimeout(() =>
    {
        // Do http request with current value
    }, 500);
};

action();
setTimeout(action, 300);
setTimeout(action, 600);

So you'd see one http request. In your example of a slider the user could drag around for a while and never see an update until they pause for 500 ms. If you instead start a timeout like:

var timer = null;
var action = () =>
{
    if (timer == null)
    {
        timer = setTimeout(() =>
        {
            // Do http request with current value
            timer = null;
        }, 500);
    }
};

action();
setTimeout(action, 300);
setTimeout(action, 600);

You'd see two http requests because the timeout waits 500 ms before starting an http request assuming the user is dragging a little bit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.