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 withrequests
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
Advertisement
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.