Почему "file.size" занимает много времени и как сократить время?
Я создаю приложение, которое касается перетаскивания песен в приложение. Когда я использую file.size
, чтобы получить размер файла, для получения этого значения требуется около 1500 мс (avg). Есть ли более быстрый способ? Я понимаю, почему требуется время (и память), но поскольку я новичок в работе с файлами в 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)
}
}
ИЗМЕНИТЬ
Я нахожусь в AMD equiv двухъядерных двух дуо, 2.7 ГГц, 2 гигабайта RAM, win7 x64. Спекуляции, на которые я верю, на самом деле достаточно приличные. Так что, если что-то займет достаточно много времени на моей машине, я возьму его как нет.
Это блокиратор для основного исправления ошибок в моем приложении. Я действительно хотел бы отправить с исправлением для этого долгого времени. Я не могу установить щедрость (пока), возможно, есть минимальное время до того, как будет установлена награда.
ИЗМЕНИТЬ
Я провел некоторое тестирование, и, как оказалось, это занимает много времени, потому что chrome вычисляет размер вместо того, чтобы просто читать его из некоторых метаданных. Здесь - результат теста.
Чем больше файл, тем дольше он требуется, и если он вызван во второй раз, он использует некоторый кеш и не загружает файл. Итак, теперь.. как я могу уменьшить это время? Размер - важная информация в моем приложении, но, вероятно, недостаточно важна, чтобы замедлить скорость загрузки пользователей примерно на 1,5 секунды для каждого файла! Я планирую импортировать библиотеки, и это действительно поможет уменьшить это время при добавлении 100 или около того песен. На этот раз это будет серьезным ответом на время отклика приложения.
Ответы
Ответ 1
Здесь квазиобразованное предположение:
Глядя на определение интерфейса HTML5 File
показывает, что File
является Blob
и что size
атрибут фактически является частью Blob
интерфейса.
Так как a Blob
является абстракцией над необработанным фрагментом данных, доступ к атрибуту size
может фактически заставить реализацию загрузить весь файл в память. Вы можете написать эксперимент, чтобы узнать, зависит ли задержка с размером файла или если задержка возникает только при первом чтении атрибута size
.
EDIT:
Мне действительно кажется, что эта неэффективность является проблемой с реализацией браузера интерфейса File
, но здесь есть две обходные идеи о том, как избежать латентности при загрузке больших файлов в память:
Веб-рабочие (ссылка MDN, WHATWG Webapps Standard) позволит вам поместить медленную загрузку файлов по существу в другой поток. Это, я думаю, это ваш лучший выбор.
Другим подходом было бы использовать метод slice
интерфейса Blob
для загрузки небольших частей File
. Если реализация slice
загружает только необходимую часть файла, она должна идти быстрее. Вам нужно будет загружать несколько фрагментов для каждого файла, и вам нужно будет обнаружить, когда вы дойдете до конца файла, обратив внимание на размер Blob
, возвращенный slice
. Вы обнаружите конец файла, вернув blob меньше, чем вы ожидали - из спецификации:
Метод среза ДОЛЖЕН зажать значения размера, если арифметика индекса превышает границы размера. В частности, это означает, что для данного вызова среза:
Если размер начала + длинa > , тогда агент пользователя ДОЛЖЕН вернуть объект Blob, как если бы был вызван срез (начало, размер-начало).
Если start > size, пользовательский агент ДОЛЖЕН вернуть объект Blob размером 0
К сожалению, спецификация также упоминает возможность исключения исключений, когда вы запрашиваете срез за пределами размера буфера Blob
- для любых реализаций, которые это делают, вам придется поймать исключение, чтобы обнаружить конец файла.
Ответ 2
если вы увеличиваете время, установленное в Console.Time(), оно даст вам больше производительности. Вы должны убедиться, что это время не синхронизируется до загрузки и отображения файла.