0

In my frontend I have an input-field that sends an ajax request on every character typed in (using vue.js) to get realtime-filtering (can't use vue filter because of pagination).

Everything works smooth in my test environment, but could this lead to performance issues on (a bigger amount of) real data and if so, what can I do to prevent this?

F.M.F.
  • 1,929
  • 3
  • 23
  • 42
  • 1
    Quick optimization: only send a request to the server a small delay after the last keystroke. If a new keystroke comes in before the delay expires, start it over. The longer the delay, the worse the user experience but the less you'll send useless queries when user types a bit slowly. 400ms should be good balance, but adjust at will. The point being: you won't send queries as long as the user keeps typing, just one when he pauses, which should be the moment he needs suggestions. – spectras Jun 22 '17 at 14:45

3 Answers3

2

I actually discuss this exact scenario in my Vue.js training course. In short, you may want to wait until a user clicks a button or something of that nature to trigger sending the request. Another approach to consider is to use the lazy modifier, which will delay the event until the change event is fired.

It's hard to know the correct approach without knowing more about the goals of the app. Still, the options listed above are two options to consider.

I hope this helps.

tony19
  • 125,647
  • 18
  • 229
  • 307
Chad Campbell
  • 927
  • 7
  • 15
2

Is it problematic?

Yes.

  • The client will send a lot of requests. Depending on the network connection and browser, this could lead to a perceptible feeling of lag by the client.
  • The server will receive a lot of requests, potentially leading to degraded performance for all clients, and extra usage of resources on the server side.
  • Responses to requests have a higher chance of arriving out of order. If you send requests very fast, it has increased chances of being apparent (e.g. displaying autocomplete for "ab" when the user has already typed "abc")

Overall, it's bad practice mostly because it's not necessary to do that many requests.

How to fix it?

As J. B. mentioned in his answer, debouncing is the way to go.

The debounce function (copied below) ensures that a certain function doesn't get called more than once every X milliseconds. Concretely, it allows you to send a request as soon as the user hasn't typed anything for, say, 200ms.

Here's a complete example (try typing text very fast in the input):

function debounce(func, wait, immediate) {
 var timeout;
 return function() {
  var context = this, args = arguments;
  var later = function() {
   timeout = null;
   if (!immediate) func.apply(context, args);
  };
  var callNow = immediate && !timeout;
  clearTimeout(timeout);
  timeout = setTimeout(later, wait);
  if (callNow) func.apply(context, args);
 };
}

var sendAjaxRequest = function(inputText) {      
    // do your ajax request here
    console.log("sent via ajax: " + inputText);
};

var sendAjaxRequestDebounced = debounce(sendAjaxRequest, 200, false); // 200ms

var el = document.getElementById("my-input");
el.onkeyup = function(evt) {
    // user pressed a key
    console.log("typed: " + this.value)
    sendAjaxRequestDebounced(this.value);
}
<input type="text" id="my-input">

For more details on how the debounce function works, see this question

Aurélien Gasser
  • 3,043
  • 1
  • 20
  • 25
0

The mechanism I was searching for is called debouncing.

I used this approach in the application.

tony19
  • 125,647
  • 18
  • 229
  • 307
F.M.F.
  • 1,929
  • 3
  • 23
  • 42