¿Por qué 'file.size' toma mucho tiempo y cómo reducir el tiempo?
-
27-10-2019 - |
Pregunta
Estoy haciendo una aplicación que trata con canciones que se arrastran a la aplicación. Cuando uso el file.size
Para obtener el tamaño del archivo, se necesitan aproximadamente 1500 ms (AVG) para obtener este valor. ¿Hay alguna forma más rápida? Entiendo por qué lleva tiempo (y la memoria), pero como soy nuevo en tratar con archivos en HTML5, tal vez hay algo de lo que no sé que pueda hacer que el proceso sea más rápido.
Lo mismo es cierto para la API del sistema de archivos. Si llamo al archivo a través de él y llamo para file.size
, lleva tiempo similar.
PD: llegué a esta conclusión agregando console.time()
en mi código.
Aquí está el código (despojado masivamente)
fileSystem.root.getFile(id, {}, function(fileEntry) {
fileEntry.file(function(audioTemp) {
console.time(1);
console.log(audioTemp.size);
console.timeEnd(1)
});
});
Este es el ejemplo de API del sistema de archivos. Esto (obviamente) necesita el archivo llamado id
estar allí para que funcione. A continuación se muestra el código de entrada del archivo 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)
}
}
EDITAR
Estoy en un AMD Equiv of Core Two Duo, 2.7 GHz, 2 gigas de Ram, Win7 x64. Las especificaciones que creo son lo suficientemente decentes. Entonces, si algo toma lo suficiente en mi máquina, lo tomaré como un no-go.
Este es un bloqueador para una gran corrección de errores en mi aplicación. Realmente me gustaría enviar el con una solución durante mucho tiempo incluido. No puedo establecer una recompensa (todavía), tal vez hay un tiempo mínimo antes de que se establezca una recompensa.
EDITAR
Hice algunas pruebas y resulta que lleva tanto tiempo porque Chrome calcular El tamaño en lugar de solo leerlo de algunos metadatos. Aquí es el resultado de la prueba.
Cuanto más grande sea el archivo, más tiempo lleva y, si se le llama por segunda vez, usa algo de caché y no carga el archivo. Así que ahora ... ¿cómo puedo reducir esta vez? El tamaño es una información importante en mi aplicación, pero probablemente no sea lo suficientemente importante como para retrasar la tasa de carga del usuario en aproximadamente 1.5 segundos para cada archivo. Estoy planeando importar bibliotecas y realmente ayudaría a reducir esta vez al agregar 100 canciones. Esta vez será un gran aumento con el tiempo de respuesta de la aplicación.
Solución
Aquí hay una suposición cuasi educada:
Mirando a La definición del HTML5 File
interfaz muestra que un File
es un Blob
y que el size
El atributo es en realidad parte del Blob
interfaz.
Desde un Blob
es una abstracción sobre una porción sin procesar de datos, accediendo al size
El atributo en realidad podría hacer que la implementación cargue todo el archivo en la memoria. Puede escribir un experimento para ver si el retraso varía con el tamaño del archivo o si el retraso solo ocurre en la primera lectura del size
atributo.
EDITAR:
Realmente siento que esta ineficiencia es un problema con la implementación del navegador del File
interfaz, pero aquí hay dos ideas de solución sobre cómo evitar la latencia al cargar archivos grandes en la memoria:
Trabajadores web(Referencia de MDN, Whatwg WebApps estándar) le permitiría colocar la carga lenta de los archivos esencialmente en otro hilo. Esta, creo, es tu mejor opción.
Otro enfoque sería usar el slice
método del Blob
interfaz para cargar pequeñas porciones del File
. Si la implementación de slice
Solo carga la parte necesaria del archivo, debe ir más rápido. Tendrá que cargar múltiples rebanadas para cada archivo y deberá detectar cuando llegue al final de un archivo prestando atención al tamaño del Blob
devuelto por slice
. Detectará el final del archivo recuperando un blob más pequeño de lo que esperaba, de la especificación:
El método de corte debe sujetar los valores de tamaño si el índice aritmético excede los límites del tamaño. En particular, esto significa que para una llamada de corte dada:
Si Start + Longitud> tamaño, entonces un agente de usuario debe devolver un objeto Blob como si se llamó a Slice (inicio, size-start).
Si iniciar> tamaño, entonces un agente de usuario debe devolver un objeto blob de tamaño 0
Desafortunadamente, la especificación también menciona la posibilidad de lanzar excepciones cuando solicita una porción fuera de un Blob
Tamaño del búfer: en cualquier implementación que lo haga, tendrá que obtener una excepción para detectar el final del archivo.
Otros consejos
Si aumenta el tiempo establecido en console.time (), le dará más rendimiento. Debe asegurarse de que esta vez no se agote hasta que el archivo se cargue y se muestre.