Test Foro de elhacker.net SMF 2.1

Programación => Desarrollo Web => Mensaje iniciado por: MA40 en 26 Septiembre 2016, 22:45 PM

Título: ¿Evitar que se bloqueen los navegadores al cargar un javascript?
Publicado por: MA40 en 26 Septiembre 2016, 22:45 PM
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 (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 (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/ (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 (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 (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 (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 (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.
Título: Re: ¿Evitar que se bloqueen los navegadores al cargar un javascript?
Publicado por: Eleкtro en 26 Septiembre 2016, 23:39 PM
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
Título: Re: ¿Evitar que se bloqueen los navegadores al cargar un javascript?
Publicado por: MA40 en 27 Septiembre 2016, 12:52 PM
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 (https://github.com/bringmehome/Concurrent.Thread.js))

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

Un saludo.
Título: Re: ¿Evitar que se bloqueen los navegadores al cargar un javascript?
Publicado por: AlbertoBSD en 27 Septiembre 2016, 13:55 PM
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

Título: Re: ¿Evitar que se bloqueen los navegadores al cargar un javascript?
Publicado por: [u]nsigned en 27 Septiembre 2016, 16:26 PM
1) los JS siempre van al final de la pagina, justo antes de cerrar </body>

2) Para evitar el bloqueo se usan promises (promesas).
Título: Re: ¿Evitar que se bloqueen los navegadores al cargar un javascript?
Publicado por: MA40 en 27 Septiembre 2016, 17:04 PM
[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 (http://librosweb.es/libro/javascript/capitulo_1/como_incluir_javascript_en_documentos_xhtml.html)

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

(http://www.bitcart.info/laboratorio/js.jpg)

MOD: Imagen reimensionada a lo usado en el foro.
Título: Re: ¿Evitar que se bloqueen los navegadores al cargar un javascript?
Publicado por: [u]nsigned en 27 Septiembre 2016, 17:10 PM
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.
Título: Re: ¿Evitar que se bloqueen los navegadores al cargar un javascript?
Publicado por: MA40 en 27 Septiembre 2016, 17:33 PM
[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.