We're developing an application that uses XMLHttpRequest for uploading files with drag&drop support. We're using a jQuery plugin for that, but it's not the issue here.
Our tester has reported that uploading files on localhost takes a serious amount of time, considering he's basically sending files to his own machine through the browser. 20 MB file was uploading about 30 seconds (!).
I was assigned to investigate the problem and I found out that the problematic thing is XMLHttpRequest. When I've forced a fallback mechanism (iframe, works but has no progress bar support), the same file our tester was uploading took less than a second.
I've written a simple testing script to see what's the deal is (it's very quick and dirty, don't judge me)
# var file was leaked from our jquery uploader, it's basically input.files[0] where input = <input type="file">
average = 0;
averages = [];
previous = 0;
previous_time = 0;
x = new XMLHttpRequest;
x.open("POST", "/something/accept_file?upload_param_name=file", true);
x.upload.onprogress = function(e) {
now = e.loaded;
now_time = Date.now();
diff = now - previous;
diff_time = now_time - previous_time;
console.log("speed", (diff / diff_time));
averages.push((diff / diff_time));
previous = now;
previous_time = now_time;
}
x.onreadystatechange = function() {
if (x.readyState == 4) {
for(i=0, l=averages.length; i < l; i++) {
average += averages[i]
}
console.log("AVG SPEED: ", average/averages.length)
}
}
x.setRequestHeader("X-Requested-With", "XMLHttpRequest");
x.setRequestHeader("X-File-Name", "test");
x.setRequestHeader("Content-Type", "application/octet-stream");
x.send(file);
- Average speed of uploading file to the same server: 488.3 KB/s
- Average speed of uploading file to the remote server: 801.7 KB/s (which sounds about right considering our office internet connection)
Now my question is: why is XMLHttpRequest with binary files so slow? It looks to me like it sends the file through all our network so it passes through our router again, but Networking section in Task Manager didn't register any network activity spike (it did when uploading to the remote server though) or I am doing something wrong.
edit: As I see, any mention of keywords "jQuery plugin" makes people think in wrong terms, so:
x = new XMLHttpRequest;
x.open("POST", "/something/accept_file?upload_param_name=file", true);
x.send(file);
This is enough to trigger the problem (slow upload). No jQuery, no fancy callbacks and progress bars, no chunking - three lines of code.