You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cordova.apache.org by "Nikita Matrosov (JIRA)" <ji...@apache.org> on 2016/11/21 12:14:58 UTC

[jira] [Commented] (CB-12085) FileReader#readAsArrayBuffer reads whole file

    [ https://issues.apache.org/jira/browse/CB-12085?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15683432#comment-15683432 ] 

Nikita Matrosov commented on CB-12085:
--------------------------------------

FileReader in fact reads file in chunked mode (256Kb by default (https://github.com/apache/cordova-plugin-file/blob/815c2b1bfe578ee9a9b0f998a906087aca379cd1/www/FileReader.js#L52)), not the whole file at once. However, it also does some transcoding data -> Base64 -> Uint8Array -> data, which sounds excessive but in fact is a feature of platform and JS-to-native bridge implementation.

Some experiments show that changing this to avoid intermediate base64 encoding/decoding and pass JSON array through bridge in fact slows read operations down even more (~1.5 times), so i think window.atob is not the worst thing here.

As a workaround, to reduce amount of data to pass through bridge I think you can read only the data range that you really need. You can either use 'File.slice' function (See https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) and then create and use a FileReader for sliced file (for 1 Kb of data it takes 20-40 ms to read, instead 2000-3000 for the whole 3Mb file), or just specify 'start' and 'end' properties of the file instance (which is basically the same and gives the same result).

> FileReader#readAsArrayBuffer reads whole file
> ---------------------------------------------
>
>                 Key: CB-12085
>                 URL: https://issues.apache.org/jira/browse/CB-12085
>             Project: Apache Cordova
>          Issue Type: Bug
>          Components: Plugin File
>    Affects Versions: 4.3.0
>         Environment: Android
>            Reporter: Damian Senn
>            Assignee: Nikita Matrosov
>            Priority: Critical
>              Labels: performance
>
> Reading a File with
> ```js
> let fr = new FileReader
> fr.onload = () => done(fs.result)
> fr.readAsArrayBuffer(blob)
> ```
> Is very slow, I'm assuming this is because it reads the whole file, then transfers this via base64 to the JS world, where it is converted to an ArrayBuffer. My use-case involves reading some media metadata in JS-World, this usually involves reading several bytes (maybe around 100b to 1kb) of 2mb to 50mb files.
> I noticed this by profiling via Chrome-DevTools where the most time is being spent in the `atob` function in `cordova/base64.toArrayBuffer`.
> So parsing some hundreds of bytes on a 3mb file may take around 3 to 4 seconds on my Samsung Galaxy S4 and around 1 second on my Samsung Galaxy S6. (This is without trying to read the actual metadata from the file).
> My guess is that this also has a very negative impact on memory usage and garbage collection.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@cordova.apache.org
For additional commands, e-mail: issues-help@cordova.apache.org