Search code examples
javascriptjqueryajaxslick.jsjqxhr

Can I update DOM while XHR data is loading?


I am using Slick JS to create a slider, adding slides to it using AJAX and the slickAdd method as follows:

$.getJSON(url, function(r) {
  $.each(r, function(i, article) {
    var html = 'HTML string created with data and ' + article.variables +  ' from JSON';
    $('.element').slick('slickAdd', html);
  }
}

This AJAX works and the slides are successfully added to the slider after the browser has all the XHR data.

The fact that it's a Slick JS slider is simply context; I believe the question is more generic than that.

Main Question: Can I force the each loop to output the 'html' while the XHR data is still being loaded by AJAX, thus giving the user the experience of a more performant site as slides are added to the DOM as quickly as possible? If yes, how?

While the funciton is looping through the 'each', I can see discrete XHR data for each item returned, and I ideally wanted to start adding to the DOM (with a delay) before all the iterations are complete.

The site is primarily PHP, so if there isn't really a "clean" way to handle this in JS / jQuery on the front-end, I can do something server side with PHP ob_flush, but just wanted to beg some JS masters (opinionated) suggestions/criticisms first.

I don't necessarilly need a full code example, just a high-level explanation - I am just a bit noob with JS.

Many thanks ;P


Solution

  • TL:DR; Not with a single request.

    If you were to use the underlying XMLHttpRequest object to perform the AJAX request you would be able to get updates as the data is coming back from the server and potentially perform updates while the data is being loaded.

    However, the obvious problem with doing this, is that the JSON won't be valid until it has been completely loaded. Although you could parse it manually, it's unlikely to be worth the effort to do so.

    The only work-around to do what you want would be to send separate requests for each block of data and process them separately.