4

I'm doing some basic ajax requests for changing pages, example:

$(document.body).on('click', ".paging a", function (e) {
    $.ajax({
        type: "GET",
        url: $this.attr('href'),
        success: function (data) {
            $("#main-content").html(data);
        }
    });
    e.preventDefault();
    return true;
});

The URL the ajax request calls to returns HTML, sometimes this HTML contains 30-40 <img> images.

The problem I'm hitting is if you click two pages in quick succession there is a delay while the browser waits until it has loaded all the images in the HTML of the previous ajax request until it makes the next XHR call.

Is there a way to prioritise the XHR request ahead of the images? Basically if another page is clicked I want all current requests to stop and the XHR request to execute immediately. As far as I've seen this is occurring because browsers have a limit to how many asynchronous requests it'll make to one domain (i.e. 6 for chrome) and if I changed the images to use a sub-domain it would probably fix it, but I'm trying to find a way to do it without having to resort to sub-domains.

Zak123
  • 113
  • 1
  • 6
  • Just abort the first XHR call when that second click occurs with the **[`.abort()`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/abort)** method. – Scott Marcus Apr 27 '18 at 15:57
  • 1
    Thanks for your reply. The xhr request has already finished so it's not the actual xhr call I need to abort, the problem is the browser loading the assets in the html/content returned in the response of the xhr request, which there doesn't seem to be a way to abort? – Zak123 Apr 27 '18 at 16:07
  • You should try to lazy image loading, which is not to introduce `src` for all the tags. Can you change the html that is returned by the ajax call? Do you have control over the same? – Tarun Lalwani Apr 30 '18 at 19:29
  • You can load the images only when XHR call is done. – giggi__ May 02 '18 at 12:42

3 Answers3

1

When the user clicks on a new page, you could

  • Store the html of "#main-content" element in a variable
  • Empty the all src attributes of tags in "#main-content"
  • Make your XHR request
  • Reset the settings of "#main-content"

This way the img http connections are aborted, the XHR request is fired and finally your image requests resume from where they were left. (this can vary on the cache settings for your images)

$('#goto-page-2').click(function (e) {
    var mainContentHTML = $("#main-content").html();
    $("#main-content").find('img').attr('src', ''); //clear images
    $.ajax({
        type: "GET",
        url: $this.attr('href'),
        success: function (data) {

        }
    });
    $("#main-content").html(mainContentHTML); // reset images
    e.preventDefault();
    return true;
});

References

How to cancel an image from loading

Jannes Botis
  • 10,614
  • 3
  • 18
  • 35
  • This will stop the images from loading but will start loading again immediately, even before completing the AJAX call as you're not waiting for AJAX to finish. – 31piy May 04 '18 at 04:04
  • To OP: Please read the implications of unsetting `src` [in this post](https://stackoverflow.com/a/6974878/2019247) before proceeding with this solution. – 31piy May 04 '18 at 04:08
  • @31piy, for your 1st comment, that is exactly what is desired. Prioritise the request over the images, not wait till it is done. As for the 2nd comment, I think the implications are no longer the case in chrome or firefox at the latest releases that I tested. The answer is 7 years old and the link in it is 9 years. I do not think that empty src of an img is anymore presumed to either the homepage or the current page. – Jannes Botis May 05 '18 at 15:23
1

Using XMLHttpRequest you can load images and abort.

var xhrAr = Array(); 
function abortXhr(){
    for(var key in xhrAr)
        xhrAr[key].abort();
    xhrAr = Array(); 
}
function startXhr(dataObj){
    var imgObj = dataObj.find('img');
    imgObj.each(function(){
        var thisObj = $(this);
        var src = $(this).attr('src');
        $(this).attr('src', ''); //prevent loading
        var xhr = new XMLHttpRequest();
        xhr.open("GET", src, true);
        xhr.responseType = "blob";
        xhr.onload = function(){
            var imageUrl = (window.URL || window.webkitURL).createObjectURL(this.response);//Creating blob ul
            thisObj.attr('src', imageUrl);
        }
        xhr.send();
        xhrAr.push(xhr);
    });
}
$(document.body).on('click', ".paging a", function (e) {
    abortXhr(); //abort
    $.ajax({
        type: "GET",
        url: $this.attr('href'),
        success: function (data) {
            var dataObj = $(data);
            startXhr(dataObj);//Start
            $("#main-content").append(dataObj);
        }
    });
    e.preventDefault();
    return true;
});
iXs
  • 546
  • 4
  • 4
0

In this case you are changing your page content and that content is having images so images is taking time. so in this case you can do one thing if you know which image you are using on those page then load them all images on main page when first time your page is loading.you can have these all image in a hidden div. and when your page content is changes that have these images then it will start showing very quickly becuase they are already in browser memory.

Anil Yadav
  • 11
  • 5