Skip to content

Javascript Fetch is Slow (60ms vs 3ms)

Running Javascript fetch takes about 60ms per call on my machine. Compared to Python requests at 3ms, this is much slower.

Questions

  • Why is fetch so much slower?
  • Is there any way to speed it up? I am OK with answers that require me to reconfigure my browser.

Experiment

These are the details of my experiment.

System

  • Browser: Firefox 74.0 (64-bit)
  • Operating System: Ubuntu 18.04.4 LTS
  • Server: Django 3.0.3 (but since requests is much faster, this should not matter). Server and client are on the same machine.
  • For requests: Python 3.7.6 with requests 2.23.0
  • Processor: Intel(R) Core(TM) i5-6600K CPU @ 3.50GHz

Javascript Fetch

HTML that runs the Javascript below:

<!DOCTYPE html>
<html>
  <head>
    <script src="script.js"></script>
  </head>
  <body>
  </body>
</html>

Javascript that makes multiple fetch requests and reports the average time per request.

// record all times
const times = [];

function call() {
    // record starting time
    const startFetch = performance.now();
    fetch("http://127.0.0.1:8000/timer/time")
        .then((response) => {
            // compute fetch duration
            const elapsedFetch = performance.now() - startFetch;

            // record result
            console.log(elapsedFetch);
            times.push(elapsedFetch);

            if (times.length<100) {
                // start next call
                call();
            } else {
                // report statistics
                const totalFetch = times.reduce((a, b) => a + b, 0);
                const averageFetch = totalFetch/times.length;
                const standardDeviation = Math.sqrt(times.reduce((a, b) => a + (b-averageFetch) ** 2, 0)/times.length);
                const totalElapsed = performance.now() - startTime;
                console.log("Average fetch time:", averageFetch, '+-', standardDeviation);
                console.log("Percentage of overall elapsed:", totalFetch/totalElapsed)
            }
        });
}

var startTime = performance.now();
call();

Firefox console output when visiting the HTML page:

Average fetch time: 62.51 +- 31.450117646838777
Percentage of overall elapsed: 0.9993605115907274

Similar result for Google Chrome Version 80.0.3987.149 (Official Build) (64-bit)

Average fetch time: 49.93 +- 4.92596183501253
Percentage of overall elapsed: 0.9993995196156925

Using XMLHttpRequest instead of fetch:

xhr.open("GET", "http://127.0.0.1:8000/timer/time");
xhr.send();
xhr.onload = ...

yields similar results:

Average fetch time: 60.19 +- 26.325157169521326
Percentage of overall elapsed: 0.9993358791300017

Python requests

Code analogous to Javascript, but in Python:

import requests
import time
import numpy as np

times = []
start_time = time.time()

for i in range(100):
    start_get = time.time()
    response = requests.get('http://127.0.0.1:8000/timer/time')
    elapsed_get = time.time() - start_get
    times += [elapsed_get]

total_elapsed = time.time() - start_time

total_get = np.sum(times)
average_get = np.average(times)
standard_deviation = np.std(times)

print("Average get time:", average_get, '+-', standard_deviation)
print("Percentage of overall elapsed:", total_get/total_elapsed)

Output:

Average get time: 0.0025661182403564453 +- 0.0001961814487345112
Percentage of overall elapsed: 0.9994576986364464

Answer

While I still don’t really know why Javascript fetch is so slow, I have been able to switch to a faster option:

I now use WebSockets (on the client) and Django Channels (on the server), which are significantly faster.