Lets say we have a simple example as below.
<input id="filter" type="text" />
<script>
function reload() {
// get data via ajax
}
$('#filter').change($.debounce(250,reload));
</script>
What we're doing is introducing a small delay so that we reduce the number of calls to reload
whilst the user is typing text into the input.
Now, I realise that this will depend on a case by case basis but is there an accepted wisdom of how long the debounce delay should be, given an average (or maybe that should be lowest common denominator) typing/interaction speed. I generally just play around with the value until it "feels" right, but I may not represent a typical user. Has anyone done any studies on this?
As you hinted at, the answer depends on a number of factors - not all of them subjective.
In general the reason for making use of a debounce operation can be summed up as having one of two purposes:
One important number to keep in mind is 250ms - this represents the (roughly) median reaction time of a human and is generally a good upper bound within which you should complete any user interface updates to keep your site feeling responsive. You can view some more information on human reaction times here.
In the former case, the exact debounce interval is going to depend on what the cost of an operation is to both parties (the client and server). If your AJAX call has an end to end response time of 100ms then it may make sense to set your debounce to 150ms to keep within that 250ms responsiveness threshold.
On the other hand, if your call generally takes 4000ms to run, you may be better off setting a longer debounce on the actual call and instead using a first-layer debounce to show a loading indicator (assuming that your loading indicator doesn't obscure your text input).
$('#filter').change($.debounce(250, show_loading));
$('#filter').change($.debounce(2000, reload));
It is also important to keep in mind the performance cost of these requests on your backend. In this case, a combination of average typing speed (about 44 words per minute, or roughly 200 characters per minute) and knowledge of your user base size and backend capacity can enable you to select a debounce value which keeps backend load manageable.
For example: if you have a single backend capable of handling 10 requests per second and peak active user base of 30 (using this service), you should select your debounce period such that you avoid exceeding 10 requests per second (ideally with a margin of error). In this case, we have 33.3% of the capacity required to handle one input per user per second, so we ideally would serve at most one request per user every 3 seconds, giving us our 3000ms
debounce period.
The final aspect to keep in mind is the cost of processing on the client side. Depending on the amount of data you're moving and the complexity of your UI updates, this may be negligible or significant. One thing you want to try and ensure is that your user interface remains responsive to user input. That doesn't necessarily mean that it always needs to be able to react, however while a user is interacting with it, it should react rapidly to them (60FPS is generally the objective here).
In this case, your objective should be to debounce at a rate which prevents the user interface from becoming sluggish or unresponsive while the user is interacting with it. Again, statistics are a good way to derive this figure, but keep in mind that different types of input require different amounts of time to complete.
For example, transcribing a sentence of short words is generally a lot faster than entering a single long and complex word. Similarly, if a user has to think about what they are entering they will tend to type slower. The same applies for the use of special characters or punctuation.
In practice, I've used debounce periods which range from 100ms
for data that is exceptionally quick to retrieve and presents very little impact on performance through to 5000ms
for things that were more costly.
In the latter case, pairing a short, low-cost debounce period to present the user with feedback and the longer period for actual computational work tends to strike a good balance between user experience and the performance cost of wasted operations.
One notable thing I try to keep in mind when selecting these values is that, as someone who works with a keyboard every day, I probably type faster than most of my user base. This can mean that things which feel smooth and natural to me are jarring for someone who types slower, so it's a good idea to do some user testing or (better yet) gather metrics and use those to tune your interface.