What is the best way to implement several concurrent Ajax request in one view/page?

Viewed 133

In a data-driven web application, I have several razor views which contain tables that were created using tabulator, and are updated using self calling ajax functions on an interval. In most of the views, the number of tables is no more than three, and network performance and lag between updates is fairly quick. I am currently creating a view that houses over six tables, and am seeing an uptick in dropped request, stagnation in the data, and general slowness that seems to be directly attributable to the increased number of concurrent requests on the page. I am by no means a JavaScript or MVC expert, and am trying to investigate whether my code is just inefficient, or if the approach itself is wrong.

Essentially, each tabulator table has an ajax function that will hit an endpoint at the MVC layers, which routes to a WebApi2 endpoint to retrieve the latest data, and finally, use one of tabulators loading functions to load the data into the table. The data end is SQL using Entity Framework. I have tried several implementations built around this process, but below is the approach I am currently using.

    // Function for waiting in between calls
    function sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
    // Function for getting data from endpoint
    async function fetch() {
        $.ajax({
            type: "GET",
            url: www.mydata.com,
        }).done(async function (data) {
            // Tabulator function for replacing existing data with new
            table.replaceData(data);
            await sleep(10000);
            fetch();
            }).fail(async function () {
                await sleep(10000);
                fetch();
        })
    }
    // Call the fetch function the first time, self calls afterwards
    fetch();

Each table in the view runs a version of the code snippet above. I added the sleep functions, hoping to introduce some delay between request. It is also worth pointing out that at the ASP.NET MVC layer, there is also increased congestion. It takes longer to service request made by the user to create a new entity, due to the all the other request flying back and forth.

1 Answers

To Spread out the request to the server you could choose to change the way your tables are configured.

Im assuming at the moment you are using the ajaxURL property to set the tables url, which will cause the table to make the request on load.

var table = new Tabulator("#example-table", {
    ajaxURL:"http://www.getmydata.com/now", //ajax URL
});

This would result in all six tables making the request at the same time.

There are a couple of different approaches you could take

Delay Requests

You could instead leave this field out of your table definition (causing it to have an empty table on load, and then load the data later using the setData function. You could wrap this in a setTimeout function:

//wait one second before loading data
setTimeout(function(){
    table.setData("http://www.getmydata.com/now");
}, 1000);

If you set each table with a different time out they will load in a staggered fashion.

Bundle Requests

Instead of allowing the tables to retrieve their data, you could retrieve it yourself in a single ajax request to the server that retrieve all the data, and then bundle it out to the tables using the setData function.

Although if you are loading significant amounts of data this could cause you delays.

Progressive Loading

If you are trying to transfer large amounts of data, this would certainly slow down the requests.

In these cases using the ajaxProgressiveLoad functionality of tabulator allows you to paginate your data and send it to the table in smaller chunks one after the other, which wont tie up your server continuously for so long:

var table = new Tabulator("#example-table", {
    ajaxURL:"http://www.getmydata.com/now", //ajax URL
    ajaxProgressiveLoad:"load", //sequentially load all data into the table
});

More details on this option can be found in the Progressive Ajax Loading Documentation

Related