なぜ「file.size」が多くの時間がかかり、時間を短縮するのになぜですか?
-
27-10-2019 - |
質問
私は、曲がアプリにドラッグされることを扱うアプリを作成しています。使用するとき file.size
ファイルのサイズを取得するには、この値を取得するには約1500ms(平均)が必要です。より速い方法はありますか?なぜ時間がかかるのか(そしてメモリ)が必要な理由は理解していますが、HTML5のファイルを扱うのは初めてなので、プロセスをより速くすることができることがわからないものがあるかもしれません。
同じことがファイルシステムAPIに当てはまります。私がそれを通してファイルを呼び出して電話をかけるなら file.size
, 、同様の時間がかかります。
PS追加することでこの結論に達しました console.time()
私のコードで。
これがコードです(大幅に剥奪されました)
fileSystem.root.getFile(id, {}, function(fileEntry) {
fileEntry.file(function(audioTemp) {
console.time(1);
console.log(audioTemp.size);
console.timeEnd(1)
});
});
これは、ファイルシステムAPIの例です。これには(明らかに)名前のファイルが必要です id
それが機能するためにそこにいること。以下はD&Dファイル入力コードです
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)
}
}
編集
私は、Core Two Duo、2.7 GHz、2ギグのRAM、Win7 X64のAMD等式にいます。私が信じている仕様は実際に十分にまともです。したがって、私のマシンで何かが十分に時間がかかった場合、私はそれをノーゴーと見なします。
これは、アプリの主要なバグ修正のブロッカーです。この長い間、修正を加えて出荷したいと思います。バウンティを設定することはできません(まだ)賞金が設定されるまで最低時間があるかもしれません。
編集
私はいくつかのテストをしましたが、結局のところ、Chromeのために非常に長い時間がかかります 計算します いくつかのメタデータからそれを読むだけではなく、サイズ。 ここ テスト結果です。
ファイルが大きいほど、時間がかかり、2回目のキャッシュを使用してファイルをロードしません。だから今..今回はどうすれば減らすことができますか?サイズは私のアプリの重要な情報ですが、おそらくファイルごとにユーザーのアップロードレートを約1.5秒遅らせるほど重要ではありません!私は図書館のインポートを計画していますが、100曲ほどの曲を追加するときにこの時間を減らすのに本当に役立ちます。今回は、アプリの応答時間への大きなバンプになります。
解決
これが準専用の推測です:
見つめている HTML5の定義 File
インターフェース それを示しています File
aです Blob
そしてそれ size
属性は実際にはの一部です Blob
インターフェース.
a以来 Blob
生の塊のデータを抽象化し、にアクセスします size
属性により、実際に実装がファイル全体をメモリにロードする可能性があります。遅延がファイルのサイズによって異なるかどうか、または遅延が最初の読み取りでのみ発生するかどうかを確認するための実験を書くことができます size
属性。
編集:
この非効率性は、ブラウザの実装に問題があると本当に感じています File
インターフェイスですが、大きなファイルをメモリにロードするときに遅延を回避する方法についての2つの回避策のアイデアがあります。
ウェブワーカー(MDNリファレンス, WhatWG WebApps Standard)ファイルを本質的に別のスレッドにゆっくりとロードすることができます。これはあなたの最善の策だと思います。
別のアプローチは、を使用することです slice
方法 の Blob
の小さな部分をロードするインターフェイス File
. 。の実装の場合 slice
ファイルの必要な部分のみをロードすると、より速く進む必要があります。ファイルごとに複数のスライスをロードする必要があり、のサイズに注意を払ってファイルの最後に到達したときに検出する必要があります Blob
によって返されます slice
. 。予想よりも小さいブロブを戻すことで、ファイルの端を検出します。
インデックス算術がサイズの境界を超える場合、スライス法はサイズの値をクランプする必要があります。特に、これは、特定のスライスコールの場合:
Start + Length>サイズの場合、ユーザーエージェントは、スライス(Start、Size-Start)が呼び出されたかのようにBLOBオブジェクトを返す必要があります。
開始>サイズの場合、ユーザーエージェントはサイズ0のBLOBオブジェクトを返す必要があります
残念ながら、スペックには、外側のスライスをリクエストするときに例外を投げる可能性についても言及しています Blob
のバッファサイズ - それを行う実装では、ファイルの終了を検出するために例外をキャッチする必要があります。
他のヒント
Console.time()で設定された時間を長くすると、よりパフォーマンスが発生します。ファイルがロードされて表示されるまで、今回がタイミングが出ないようにする必要があります。