Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does 'file.size' take a lot of time, and how to reduce the time?

I am making an app that deals with songs being dragged to the app. When I use the file.size to get the size of the file it takes approx 1500ms (avg) to get this value. Is there any faster way? I understand why it takes time (and memory) but since I am new to dealing with files in HTML5, maybe there is something that I don't know of which can make the process faster.

The same stands true for the file system API. If I call in the file through it and call for file.size, it takes similar time.

PS I got to this conclusion by adding console.time() in my code.

Here is the code (massively stripped down)

fileSystem.root.getFile(id, {}, function(fileEntry) {
    fileEntry.file(function(audioTemp) {
        console.time(1);
        console.log(audioTemp.size);
        console.timeEnd(1)
    });
});

This is the file system API example. This (obviously) needs the file named id to be there for it to work. Below is the D&D file input code

function onChangeAddSongsInput() {
    var files = document.getElementById('addSongsInput').files;
    for(var i=0; i<files.length; i++) {
        console.time(1);
        console.log(files[i].size);
        console.timeEnd(1)
    }
}

EDIT

I am on an AMD equiv of core two duo, 2.7 GHz, 2 gigs of ram, win7 x64. The specs i believe are actually decent enough. So if something does take long enough on my machine i will take it as a no-go.

This is a blocker for a major bug fix in my app. I would really like to ship the with a fix for this long time included. I cannot set a bounty (yet) maybe there is a minimum time before a bounty is set.

EDIT

I did some testing and as it turns out, it takes so long because chrome calculates the size instead of just reading it from some metadata. Here is the test result.

The bigger the file, the longer it takes and if called second time it uses some cache and does not load the file. So now.. how can i reduce this time? Size is an important info in my app but probably not important enough to slow user's upload rate by about 1.5 seconds for every file! I am planning on importing libraries and it would really help to reduce this time when adding 100 or so songs. This time then will be a major bump to app's response time.

like image 566
Achshar Avatar asked Sep 06 '11 20:09

Achshar


People also ask

How do I reduce large file size?

Compressing FilesRight-click the file, select Send to, and then select Compressed (zipped) folder. Most files, once compressed into a ZIP file, will reduce in size from anything like 10 to 75%, depending how much available space there is within the file data for the compression algorithm to do its magic.

Does file size affect performance?

Why is file size so important? If you lower the file size, your website is going to load much faster. For example, while loading the compressed file, at 0.08MB, the visitor will see it instantly, but a 15MB image on a 3G connection can take 17 seconds to load, and that's a 18650% increase in waiting time.


1 Answers

Here's a quasi-educated guess:

Looking at the definition of the HTML5 File interface shows that a File is a Blob and that the size attribute is actually part of the Blob interface.

Since a Blob is an abstraction over a raw chunk of data, accessing the size attribute might actually cause the implementation to load the whole file into memory. You could write an experiment to see if the delay varies with the size of the file or if the delay only occurs on the first read of the size attribute.

EDIT:

I really feel like this inefficiency is a problem with the browser's implementation of the File interface, but here're two workaround ideas about how to avoid latency when loading large files into memory:

Web workers(MDN reference, WHATWG Webapps Standard) would allow you to put the slow loading of the files essentially into another thread. This, I think, is your best bet.

Another approach would be to use the slice method of the Blob interface to load up small portions of the File. If the implementation of slice only loads the needed portion of the file, it should go faster. You'll have to load multiple slices for every file and you'll need to detect when you get to the end of a file by paying attention to the size of the Blob returned by slice. You'll detect the end of the file by getting back a blob smaller than you expected-- from the spec:

The slice method MUST clamp on values of size if index arithmetic exceeds the bounds of size. In particular, this means that for a given slice call:

If start + length > size then a user agent MUST return a Blob object as if slice(start, size-start) was called.

If start > size then a user agent MUST return a Blob object of size 0

Unfortunately, the spec also mentions the possibility of throwing exceptions when you request a slice outside of a Blob's buffer size-- on any implementations that do that, you'll have to catch an exception to detect the end of file.

like image 56
ellisbben Avatar answered Nov 15 '22 20:11

ellisbben