¿Evitar que se bloqueen los navegadores al cargar un javascript?

Iniciado por MA40, 26 Septiembre 2016, 22:45 PM

0 Miembros y 1 Visitante están viendo este tema.

MA40

Hola.

Cuando se carga una web que tiene algún javascript que requiere mucho tiempo de cálculo, los navegadores se bloquean y después de unos minutos muestran mensajes para continuar o detener el script.

Sin embargo hay algunas webs que evitan esto (no sé cómo lo harán). Pongo el ejemplo de la siguiente página para jugar al ajedrez: http://forwardcoding.com/projects/ajaxchess/chess.html (para probar, hay que poner el "Time per move:" mayor de 10000 ms).

¿Cómo se puede hacer eso?

Para probar, he hecho el siguiente javascript en el archivo bloquea.js

Código (javascript) [Seleccionar]
function bloquea() {
 var limite = 10000000000;
 var n = 0;
 for (var i = 0; i < limite; i++) {
   n = i;
 }
 document.write("Terminado!");
}


Y luego, la siguiente página:

Código (html4strict) [Seleccionar]
<html>
<head>
<meta charset="utf-8">
<script language="javascript" type="text/javascript" src="bloquea.js"></script>
</head>
<body>
<form>
 <input type="button" value="Bloquea" onclick="bloquea()">
</form>
</body>
</html>


Se puede probar aquí: http://bitcart.info/laboratorio/bloquea.htm

Como se puede ver se bloquea, aunque si no se interrumpe voluntariamente el script, después de unos 15 segundos termina.

He estado buscando y encontré esta página en la que creo que se explica cómo solucionar el problema: http://www.frikipandi.com/public/post/cargar-javascript-sin-bloqueo-en-el-navegador/ Pero, utilizando el archivo bloquea.js, no he conseguido hacer funcionar ninguna de las opciones que describe.

El código de la primera es éste:

Código (html4strict) [Seleccionar]
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript">
 var xhrObj = getXHRObject();
 xhrObj.onreadystatechange = function() {
   if ( xhrObj.readyState == 4 && 200 == xhrObj.status ) {
     eval(xhrObj.responseText);
   }
 };
 xhrObj.open('GET', 'bloquea.js', true);
 xhrObj.send('');
</script>
</head>
<body>
<form>
 <input type="button" value="Bloquea" onclick="bloquea()">
</form>
</body>
</html>


Y se puede probar aquí: http://bitcart.info/laboratorio/nobloquea_1.htm

Bloquearse, no se bloquea, pero nunca termina, por lo que pienso que no entra en el bucle.

La segunda opción es ésta:

Código (html4strict) [Seleccionar]
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript">
 var xhrObj = getXHRObject();
 xhrObj.onreadystatechange = function() {
   if ( xhrObj.readyState == 4 ) {
 var scriptElement = document.createElement('script');
 document.getElementsByTagName('head')[0].appendChild(scriptElement);
 scriptElement.text = xhrObj.responseText;
   }
 };
 xhrObj.open('GET', 'bloquea.js', true);
 xhrObj.send('');
</script>
</head>
<body>
<form>
 <input type="button" value="Bloquea" onclick="bloquea()">
</form>
</body>
</html>


Y para probar: http://bitcart.info/laboratorio/nobloquea_2.htm

El resultado es el mismo que el de la anterior.

Tercera opción:

Código (html4strict) [Seleccionar]
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript">
 var scriptElement = document.createElement('script');
 scriptElement.src = 'bloquea.js';
 document.getElementsByTagName('head')
 [0].appendChild(scriptElement);
</script>
</head>
<body>
<form>
 <input type="button" value="Bloquea" onclick="bloquea()">
</form>
</body>
</html>


Y para probar: http://bitcart.info/laboratorio/nobloquea_3.htm

Sí se bloquea, y también termina.

Cuarta opción:

Código (html4strict) [Seleccionar]
<html>
<head>
<meta charset="utf-8">
<script defer="" src="bloquea.js"></script>
</head>
<body>
<form>
 <input type="button" value="Bloquea" onclick="bloquea()">
</form>
</body>
</html>


Para probar: http://bitcart.info/laboratorio/nobloquea_4.htm

Lo mismo, se bloquea y termina.

La quinta opción ya no la he probado.

¿Alguien puede ayudarme?

Un saludo.
¿Qué sucedería si se enfrentara una fuerza imparable contra un muro inamovible?
Visita Ediciones MA40 - Libros clásicos de ajedrez y este blog de ajedrez
ChessFaucet.com - Gana bitcoins jugando al ajedrez contra el ordenador

Eleкtro

#1
No se si te servirá de algo, pero lee esta respuesta:

Al parecer podrias utilizar el método window.setTimeout() en la implementación de tu algoritmo para evitar que se bloquee el hilo del render mientras se procesan las operaciones expensivas que necesites llevar a cabo, o eso es lo que entendí según lo que parece poner en esa respuesta...

Ejemplo:
Cita de: http://stackoverflow.com/a/39922/1248295
Código (javascript) [Seleccionar]
setTimeout(function () {
   ... do the rest of the work...
}, 0);

Y si eso no funciona, esto otro seguro que lo hará, puesto que en teoría te permitirá ejecutar tareas de forma asincrónica (por ende, el hilo principal de la web/navegador no se bloqueará):

PD: Yo no uso javascript.

Saludos








MA40

Hola.

Encontré esta otra dirección, muy interesante y en español, donde se explica cómo podrían programarse multihilos con la librería Concurrent.Thread.js (https://github.com/bringmehome/Concurrent.Thread.js)

La dirección: http://www.purojavascript.com/2012/07/documento-sin-titulo.html

Un saludo.
¿Qué sucedería si se enfrentara una fuerza imparable contra un muro inamovible?
Visita Ediciones MA40 - Libros clásicos de ajedrez y este blog de ajedrez
ChessFaucet.com - Gana bitcoins jugando al ajedrez contra el ordenador

AlbertoBSD

Otra opcion igual de valida seria enviar los datos al servidor y que este los procese, y tener un script que se ejecute cada x segundos para comprobar si el servidor ya acabo de procesar los datos y en ese caso mostrarlos.

Saludos

Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

[u]nsigned

1) los JS siempre van al final de la pagina, justo antes de cerrar </body>

2) Para evitar el bloqueo se usan promises (promesas).

No hay atajo ante la duda, el misterio se hace aquí...
Se hace carne en cada uno, el misterio es existir!

MA40

#5
[quote author=nsigned link=topic=458291.msg2089829#msg2089829 date=1474986418]

1) los JS siempre van al final de la pagina, justo antes de cerrar </body>

[/quote]

http://librosweb.es/libro/javascript/capitulo_1/como_incluir_javascript_en_documentos_xhtml.html

:huh: :huh: :huh: :huh: :huh:



MOD: Imagen reimensionada a lo usado en el foro.
¿Qué sucedería si se enfrentara una fuerza imparable contra un muro inamovible?
Visita Ediciones MA40 - Libros clásicos de ajedrez y este blog de ajedrez
ChessFaucet.com - Gana bitcoins jugando al ajedrez contra el ordenador

[u]nsigned

Eso está mal, lo correcto es ponerlos donde te dije yo. Asi cargan de ultimo, porque los js bloquean la carga,e s decir mientras se cargan no carga nada mas, por esos ponerlo al final del body.

No hay atajo ante la duda, el misterio se hace aquí...
Se hace carne en cada uno, el misterio es existir!

MA40

[quote author=nsigned link=topic=458291.msg2089836#msg2089836 date=1474989050]

Eso está mal, lo correcto es ponerlos donde te dije yo. Asi cargan de ultimo, porque los js bloquean la carga,e s decir mientras se cargan no carga nada mas, por esos ponerlo al final del body.

[/quote]

Gracias {u}nsigned, tomamos nota.

En cuanto a lo de evitar el bloqueo en navegadores ¿cómo se podría resolver con promises? ¿Podrías poner el código para mi primer ejemplo (el de bloquea.js)?

Muchas gracias y un saludo.
¿Qué sucedería si se enfrentara una fuerza imparable contra un muro inamovible?
Visita Ediciones MA40 - Libros clásicos de ajedrez y este blog de ajedrez
ChessFaucet.com - Gana bitcoins jugando al ajedrez contra el ordenador