javascript – How to avoid getting "stalled" by multiple browser requests?

Question:

My problem is that I have multiple ajax (total 10) to make requests to certain resources.

According to chrome (it also happens in other browsers):

Tail. (Queuing) The browser queues requests when:

  • There are higher priority requests.
  • There are already six TCP connections open for this source, which is the limit. Applies only to HTTP / 1.0 and HTTP / 1.1.
  • The browser is briefly allocating disk cache space.

Stuck. (Stalled) The request could be stopped for any of the reasons described in the queue .

In my case it is because there are more than 6 connections (10), "stalled" is added to the last 4, and the added time is equivalent (more or less) to the time of the 4 fastest queries that are sent in the first block of 6.

To look at it another way, there is a block of 6 requests and a queue of 4, and when a query for this block finishes, one of those that were in the queue is executed, like this until there are no queued requests.

Grouping ajax requests is not an option since the idea is to use JS asynchrony so that all requests are made at the same time and thus reduce times.

I am interested in a solution that can be compatible with IE9 +, but any answer that is only for more modern browsers is also welcome.


In the backend, the requests arrive at a serveResource method (from liferay) that I have overwritten, and depending on the type of resource that is requested by parameter, one resource or another is returned.

@Override
public void serveResource(ResourceRequest resourceRequest, ResourceResponse resourceResponse) {
    String recurso = ParamUtil.getString(resourceRequest, "recurso");
    switch(recurso){
        ...
    }
}

My ajax are something like this:

$.ajax({
    type: "POST",
    url: "/miPortlet?recurso=tartas&masParametros=todosIguales",
    dataType: 'json',
    beforeSend: funcionAntesDeAjax,
    success: function(data){
        ...
    },
    error:function(xhr,textstatus,message){
        ...
    }
});

The url of the ajax varies only in one parameter recurso=tartas in each one is a different resource.

I have read the following thread in English: Chrome stalls when making multiple requests to the same resource? . Where it is said that this behavior is due to Chrome blocking the cache and waiting to see the result of a request before requesting the same resource again.

I have tried with different solutions commenting on that thread like:

  • Add headers to the request ( Cache-Control: no-cache, no-store or Cache-Control: no-store ) through headers and through the beforeSend .
  • Add cache: false with the ajax in post / get method
  • Add a random number as a parameter to differentiate the URL (it was already different)

Answer:

A possible solution is to group the requests in groups of 6. In jQuery the $.ajax function returns a promise, which allows you to group and wait for all of them to be resolved, using the $.when method, before continuing to execute the code. Example:

var request1 = $.get("https://jsonplaceholder.typicode.com/todos/1");
var request2 = $.get("https://jsonplaceholder.typicode.com/todos/2");
var request3 = $.get("https://jsonplaceholder.typicode.com/todos/3");
var request4 = $.get("https://jsonplaceholder.typicode.com/todos/4");
var request5 = $.get("https://jsonplaceholder.typicode.com/todos/5");
var request6 = $.get("https://jsonplaceholder.typicode.com/todos/6");

$.when(
  request1,
  request2,
  request3,
  request4,
  request5,
  request6
).done(function (response1, response2, response3, response4, response5, response6) {

  console.log("GROUP 1");
  console.log(response1[0].title);
  console.log(response2[0].title);
  console.log(response3[0].title);
  console.log(response4[0].title);
  console.log(response5[0].title);
  console.log(response6[0].title);

  var request7 = $.get("https://jsonplaceholder.typicode.com/todos/7");
  var request8 = $.get("https://jsonplaceholder.typicode.com/todos/8");
  var request9 = $.get("https://jsonplaceholder.typicode.com/todos/9");
  var request10 = $.get("https://jsonplaceholder.typicode.com/todos/10");

  $.when(
    request7,
    request8,
    request9,
    request10
  ).done(function (response7, response8, response9, response10) {
    console.log("GROUP 2");
    console.log(response7[0].title);
    console.log(response8[0].title);
    console.log(response9[0].title);
    console.log(response10[0].title);
  });
});

In this article you can see a step by step of using $.ajax with $.when : https://www.arquitecturajava.com/jquery-promise-y-ajax/

Here you can also find the documentation for those methods:

Finally, I want to tell you that if your platform receives many requests in parallel, you may run into a bottleneck on the side of your http server or your pool of connections to the database. In that case you should find some way to scale your backend .

Scroll to Top