wrong1man
wrong1man

Reputation: 333

Fetch vs ajax vs XMLHttpRequest why is Fetch so much more incredibly fast?

Okay so these last couple of days i have been optimizing a client table.

There are a lot of clients 10k+ and obviously the table took ages to load. Front-end team did the pagination + filters + reordering and i was wanting to keep it that way.

So i started by trying to inject rendered HTML via AJAX, which obviously sucked. was acceptably fast, but gigantic memory hog, table was very slow after.

So after that, i tried loading the data in via AJAX in JSON format and appending to the table with javascript.

I tried multiple methods of doing this, the best one was 500-1000 clients at a time, but it took more than 30 seconds to complete the table, and the page in the meantime was slow.

I soldiered on, and managed to shave off some seconds on the backend, but still, if i simply loaded the API on the browser the results appeared instantly and didn't take 10+s per call.

This is when i tried XMLHttpRequest which yielded more or less the same resutls. And then i found out fetch, which is amazing. with fetch it now takes under 3 seconds to fully load the table.

So my question is, why? yes i could probably find out why if i deep dive the docs, but i simply am very busy and super curious, surely someone already knows this.

PS if anyone is curious on the code i am using:

Best solution (fetch)

for (var jj of {{ ret|safe }}) {
          fetch("/clients/table/build1/?start="+String(jj)).then(function (response) {
              response.json().then(function (request) {
                  for (let i = 0; i < request['results'].length; i++) {
                  $("#myAllClient_1").DataTable().row.add(<<CLIENT DATA>>)
                  }
            $("#myAllClient_1").DataTable().draw(false);
            <<bit more code>>

slow ajax code:

$.ajax({
          method: "GET",
          dataType: "JSON",
          url: "/clients/table/build1/?start=" + snum,
          success: function (data) {
              for (let i = 0; i < data['results'].length; i++) {
                  $("#myAllClient_1").DataTable().row.add(<<CLIENT DATA>>);
              }
              $("#myAllClient_1").DataTable().draw(false);
              <<bit more code>>
      })

PS2: next step for optimization is ditching the "row.add" loop and just getting the data already organized and ready to be inputted on that add function without the loop

Upvotes: 15

Views: 21730

Answers (1)

Eric Grange
Eric Grange

Reputation: 6211

The answer can be found in this tweet from Alex Russel (Google Chrome Team):

fetch() will be the same as XHR at the network level, but for things like decoding JSON, it can do that work off-thread because the API contract is promise-based up-front.

So it comes down to a better multi-threading support on the browser-side for fetch + json, while the ajax implementation will be doing the request, and then the (synchronous) json parsing in the JavaScript thread.

This also probably means that fetch could be "worse" than ajax in the very oddball case where you would call a json API, but never actually parse the json (treating it like plaintext instead f.i.). Though this may not even show in timings, and just in increased CPU usage (json parsing happening in another thread, but never used).

Upvotes: 26

Related Questions