ventana tamaño resolucion redimensionar pantalla navegador div detectar cuando cambio cambia alto javascript arrays memory
descargarlo desde GitHub

tamaño - redimensionar ventana javascript



¿He alcanzado los límites del tamaño de los objetos que mi navegador puede manejar con JavaScript? (6)

¿Realmente necesitas todos los datos? ¿no puedes transmitir solo los datos que actualmente necesitas usando AJAX? De forma similar a Google Maps, no puede incluir todos los datos del mapa en la memoria del navegador, solo muestran la parte que está viendo actualmente.

Recuerde que 40 megas de datos duros se pueden inflar a mucho más en la representación interna del navegador. Por ejemplo, el intérprete de JS puede usar hashtable para implementar la matriz, lo que agregaría una sobrecarga de memoria adicional. Además, espero que los navegadores almacenen tanto el código fuente como la memoria JS, eso solo duplica la cantidad de datos.

JS está diseñado para proporcionar interacción con la interfaz de usuario del lado del cliente, no para manejar montones de datos.

EDITAR:

Por cierto, ¿realmente crees que a los usuarios les gustará descargar 40 megabytes de código? Todavía hay muchos usuarios con menos acceso a Internet de banda ancha. Y la ejecución del script se suspenderá hasta que se descarguen todos los datos.

EDIT2:

Eché un vistazo a los datos. Esa matriz definitivamente se representará como hashtable. Además, muchos de los elementos son objetos, lo que requerirá un seguimiento de referencia ... que es memoria adicional.

Supongo que el rendimiento sería mejor si fuera un simple vector de datos primitivos.

EDIT3: Los datos ciertamente podrían simplificarse. La mayor parte son cadenas repetitivas, que podrían codificarse de algún modo como enteros o algo así. Además, mi Opera tiene problemas solo para mostrar el texto, y mucho menos para interpretarlo.

EDIT4: Olvida los objetos DateTime ! ¡Utiliza marcas de tiempo o cadenas de la era de Unix, pero no objetos!

EDIT5: Su procesador no importa porque JS es de un solo hilo. Y su RAM tampoco importa, la mayoría de los navegadores son de 32 bits, por lo que no pueden usar gran parte de esa memoria.

EDIT6: Intente cambiar los índices de la matriz a enteros secuenciales (0, 1, 2, 3 ...). Eso podría hacer que el navegador utilice una estructura de datos de matriz más eficiente. Puede usar constantes para acceder a los elementos de la matriz de manera eficiente. Esto reducirá el tamaño de la matriz en gran cantidad.

Estoy incrustando una gran matriz en etiquetas <script> en mi HTML, así (nada sorprendente):

<script> var largeArray = [/* lots of stuff in here */]; </script>

En este ejemplo particular, la matriz tiene 210,000 elementos. Eso está muy por debajo del máximo teórico de 2 31 , en 4 órdenes de magnitud . Aquí está la parte divertida: si guardo la fuente JS para la matriz en un archivo, ese archivo es> 44 megabytes (46,573,399 bytes, para ser exactos).

Si quieres verlo por ti mismo, puedes descargarlo desde GitHub . (Todos los datos que contiene están enlatados, gran parte de ellos se repiten. Este no será el caso en la producción).

Ahora, realmente no estoy preocupado por servir tantos datos. Mi servidor gzips sus respuestas, por lo que realmente no toma todo ese tiempo para obtener los datos a través del cable. Sin embargo, hay una tendencia realmente desagradable para que la página, una vez cargada, bloquee el navegador. No estoy probando nada en IE (esta es una herramienta interna). Mis objetivos principales son Chrome 8 y Firefox 3.6.

En Firefox, puedo ver un error razonablemente útil en la consola:

Error: script stack space quota is exhausted

En Chrome, simplemente obtengo la página triste:

Corte a la caza, ya

  • ¿De verdad se trata de demasiados datos para que nuestros navegadores modernos de "alto rendimiento" los manejen?
  • ¿Hay algo que pueda hacer * para manejar con gracia esta cantidad de datos?

Por cierto, pude hacer que esto funcionara (léase: no bloquear la pestaña) de manera intermitente en Chrome. Realmente pensé que Chrome, al menos, estaba hecho de cosas más duras, pero aparentemente estaba equivocado ...

Editar 1

@Crayon: no estaba buscando justificar por qué me gustaría descargar esta cantidad de datos en el navegador a la vez. Versión corta: o bien resuelvo este problema (ciertamente no es tan fácil), o tengo que resolver una gran cantidad de otros problemas. Opto por un enfoque más simple por ahora.

@various: en este momento, no estoy especialmente buscando maneras de reducir la cantidad de elementos en la matriz. Sé que podría implementar la paginación Ajax o lo que sea, pero eso introduce su propio conjunto de problemas para mí en otros aspectos.

@Phrogz: cada elemento se ve así:

{dateTime:new Date(1296176400000), terminalId:''terminal999'', ''General___BuildVersion'':''10.05a_V110119_Beta'', ''SSM___ExtId'':26680, ''MD_CDMA_NETLOADER_NO_BCAST___Valid'':''false'', ''MD_CDMA_NETLOADER_NO_BCAST___PngAttempt'':0}

@Will: pero tengo una computadora con un procesador de 4 núcleos, 6 gigabytes de RAM, más de medio terabyte de espacio en disco ... y ni siquiera estoy pidiendo que el navegador lo haga rápidamente, solo estoy preguntando para que funcione en absoluto!

Editar 2

¡Misión cumplida!

Con las sugerencias puntuales de Juan y Guffa , ¡pude hacer que esto funcionara! Parecería que el problema consistía solo en analizar el código fuente, sin trabajar con él en la memoria.

Para resumir el atolladero del comentario sobre la respuesta de Juan: tuve que dividir mi gran matriz en una serie de más pequeños, y luego Array#concat() ellos, pero eso no fue suficiente. También tuve que ponerlos en declaraciones separadas de var . Me gusta esto:

var arr0 = [...]; var arr1 = [...]; var arr2 = [...]; /* ... */ var bigArray = arr0.concat(arr1, arr2, ...);

A todos los que contribuyeron a resolver esto: gracias. ¡La primera ronda está en mí!

* aparte de lo obvio: enviar menos datos al navegador


Esto es lo que probaría: dijiste que es un archivo de 44 MB. Eso seguramente toma más de 44MB de memoria, supongo que esto requiere mucho más de 44MB de RAM, tal vez medio concierto. ¿Podría simplemente reducir los datos hasta que el navegador no se bloquee y ver cuánta memoria usa el navegador?

Incluso las aplicaciones que se ejecutan solo en el servidor estarán bien servidas para no leer un archivo de 44MB y mantenerlo en la memoria. Habiendo dicho todo eso, creo que el navegador debería poder manejarlo, así que déjame ejecutar algunas pruebas.

(Usando Windows 7, 4GB de memoria)

Primera prueba Corté la matriz por la mitad y no hubo problemas, usa 80 MB, sin bloqueo

Segunda prueba : dividí la matriz en dos matrices separadas, pero aún contiene todos los datos, usa 160Mb, sin bloqueo

Tercera prueba Desde que Firefox dijo que se quedó sin stack, es probable que el problema no pueda analizar la matriz de una vez. Creé dos matrices separadas, arr1, arr2 y luego arr3 = arr1.concat (arr2); Funcionó bien y usa solo un poco más de memoria, alrededor de 165MB.

Cuarta prueba Estoy creando 7 de esas matrices (22 MB cada una) y las concaturo para probar los límites del navegador. La página tarda unos 10 segundos en terminar de cargarse. La memoria sube a 1.3GB, luego vuelve a bajar a 500MB. Así que sí, Chrome puede manejarlo. Simplemente no puede analizarlo todo de una vez porque utiliza algún tipo de recursión, como puede advertirse en el mensaje de error de la consola.

Respuesta Cree matrices separadas (menos de 20 MB cada una) y luego concatúguelas. Cada matriz debe estar en su propia instrucción var, en lugar de hacer declaraciones múltiples con una sola var.

Todavía consideraría buscar solo la parte necesaria, puede hacer que el navegador sea lento. sin embargo, si se trata de una tarea interna, esto debería estar bien.

Último punto: no estás en los niveles máximos de memoria, solo en los niveles máximos de análisis.


Intentaría tenerlo como una gran cadena con separador entre cada "elemento" y luego usar split , algo así como:

var largeString = "item1,item2,......."; var largeArray = largeString.split(",");

Esperemos que la cuerda no agote la pila tan rápido.

Editar: para probarlo, creé una matriz ficticia con 200,000 elementos simples (cada elemento, un número) y Chrome lo cargó en un instante. 2,000,000 artículos? Un par de segundos, pero no se cuelga. 6,000,000 de elementos de matriz (archivo de 50 MB) hicieron que Chrome se cargara durante unos 10 segundos, pero aún así, no se bloquea de ninguna manera.

Entonces, esto me lleva a pensar que el problema no está en la matriz en sí, sino en sus contenidos ... optimice los contenidos en elementos simples y luego analícelos "sobre la marcha" y debería funcionar.


Intente recuperar los datos con Ajax como una página JSON. No sé el tamaño exacto, pero he podido obtener grandes cantidades de datos en Google Chrome de esa manera.


Sí, es demasiado pedir a un navegador.

Esa cantidad de datos sería manejable si ya se tratara de datos, pero aún no son datos. Considere que el navegador tiene que analizar ese gran bloque de código fuente mientras comprueba que la sintaxis se suma a todo. Una vez analizado en código válido, el código debe ejecutarse para producir la matriz real.

Entonces, todos los datos existirán en (al menos) dos o tres versiones a la vez, cada una con cierta cantidad de sobrecarga. Como el literal de la matriz es una declaración única, cada paso deberá incluir todos los datos.

Dividir los datos en varias matrices más pequeñas posiblemente lo haría más fácil en el navegador.


Usa carga lenta Tener indicadores de los datos y obtenerlos cuando el usuario lo solicite.

Esta técnica se usa en varios lugares para administrar millones de registros de datos.

[Editar]

Encontré lo que estaba buscando. Desplazamiento virtual en jqgrid . Eso es 500k registros cargados de forma perezosa.