true tag script entre diferencia defer async javascript html deferred-execution

javascript - tag - script defer



¿Cómo funciona exactamente<script defer="defer">? (10)

ACTUALIZADO: 2/19/2016

Considera esta respuesta desactualizada. Consulte otras respuestas en esta publicación para obtener información relevante para la nueva versión del navegador.

Básicamente, aplazar le dice al navegador que espere "hasta que esté listo" antes de ejecutar el javascript en ese bloque de script. Normalmente esto ocurre después de que el DOM haya terminado de cargarse y document.readyState == 4

El atributo de aplazamiento es específico del explorador de Internet. En Internet Explorer 8, en Windows 7, el resultado que veo en su página de prueba de JS Fiddle es 1 - 2 - 3.

Los resultados pueden variar de un navegador a otro.

http://msdn.microsoft.com/en-us/library/ms533719(v=vs.85).aspx

Contrariamente a la creencia popular, IE sigue los estándares con mayor frecuencia que las personas, en realidad el atributo "diferir" se define en la especificación de DOM Nivel 1 http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html

La definición de aplazamiento del W3C: http://www.w3.org/TR/REC-html40/interact/scripts.html#adef-defer :

"Cuando se establece, este atributo booleano proporciona una sugerencia al agente de usuario de que el script no generará ningún contenido de documento (por ejemplo, no" document.write "en javascript) y, por lo tanto, el agente de usuario puede continuar analizando y renderizando".

Tengo algunos elementos <script> , y el código en algunos de ellos depende del código en otros elementos <script> . Vi que el atributo de aplazamiento puede ser útil aquí ya que permite que los bloques de código se pospongan en ejecución.

Para probarlo ejecuté esto en Chrome: http://jsfiddle.net/xXZMN/ .

<script defer="defer">alert(2);</script> <script>alert(1)</script> <script defer="defer">alert(3);</script>

Sin embargo, alerta 2 - 1 - 3 . ¿Por qué no alerta 1 - 2 - 3 ?


Algunos fragmentos de la especificación HTML5: http://w3c.github.io/html/semantics-scripting.html#element-attrdef-script-async

Los atributos de aplazamiento y asíncrono no deben especificarse si el atributo src no está presente.

Hay tres modos posibles que pueden seleccionarse utilizando estos atributos [asíncrono y diferido]. Si el atributo asíncrono está presente, el script se ejecutará de forma asíncrona, tan pronto como esté disponible. Si el atributo asíncrono no está presente pero el atributo de aplazamiento está presente, la secuencia de comandos se ejecuta cuando la página ha finalizado el análisis. Si ninguno de los atributos está presente, entonces el script se recupera y ejecuta inmediatamente, antes de que el agente de usuario continúe analizando la página.

Los detalles exactos del procesamiento de estos atributos son, por razones principalmente históricas, un tanto no triviales, que involucran varios aspectos de HTML. Por lo tanto, los requisitos de implementación se encuentran dispersos por la especificación. Los algoritmos a continuación (en esta sección) describen el núcleo de este procesamiento, pero estos algoritmos hacen referencia a ellos y se hace referencia a ellos mediante las reglas de análisis para las etiquetas de inicio y fin de script en HTML, en contenido externo y en XML, las reglas para document.write () Método, manejo de scripting, etc.

Si el elemento tiene un atributo src, y el elemento tiene un atributo diferido y el elemento se ha marcado como "insertado en el analizador", y el elemento no tiene un atributo asíncrono:

El elemento debe agregarse al final de la lista de scripts que se ejecutarán cuando el documento haya terminado de analizar asociado con el documento del analizador que creó el elemento.


Como atributo de aplazamiento solo funciona con la etiqueta de scripts con src. Encontré una manera de imitar el aplazamiento de los scripts en línea. Utilice el evento DOMContentLoaded.

<script defer src="external-script.js"></script> <script> document.addEventListener("DOMContentLoaded", function(event) { // Your inline scripts which uses methods from external-scripts. }); </script>

Esto se debe a que, el evento DOMContentLoaded se desencadena después de que los scripts de atribución diferidos se cargan completamente.


Eche un vistazo a este excelente artículo. Sumérjase en las aguas turbias de la carga de scripts del desarrollador de Google Jake Archibald, escrito en 2013.

Citando la sección correspondiente de ese artículo:

Aplazar

<script src="//other-domain.com/1.js" defer></script> <script src="2.js" defer></script>

La especificación dice : Descargar juntos, ejecutar en orden justo antes de DOMContentLoaded. Ignore "aplazar" en los scripts sin "src".

IE <10 dice : podría ejecutar 2.js a mitad de la ejecución de 1.js. ¿No es divertido?

Los navegadores en rojo dicen : no tengo idea de lo que es este "aplazamiento", voy a cargar los scripts como si no estuvieran allí.

Otros navegadores dicen : Ok, pero podría no ignorar "diferir" en los scripts sin "src".

(Agregaré que las primeras versiones de Firefox activan DOMContentLoaded antes de que las secuencias de comandos de aplazamiento terminen de ejecutarse, de acuerdo con este comentario ).

Los navegadores modernos parecen admitir async correctamente, pero debe estar bien con los scripts que se ejecutan fuera de orden y posiblemente antes de DOMContentLoaded.


El atributo de aplazamiento es un atributo booleano.

Cuando está presente, especifica que el script se ejecuta cuando la página ha terminado de analizar.

Nota: El atributo de diferir es solo para scripts externos (solo debe usarse si el atributo src está presente).

Nota: Hay varias formas de ejecutar un script externo:

Si async está presente: la secuencia de comandos se ejecuta de forma asíncrona con el resto de la página (la secuencia de comandos se ejecutará mientras la página continúa el análisis) Si async no está presente y el aplazamiento está presente: la secuencia de comandos se ejecuta cuando la página ha finalizado el análisis Si ni async ni aplazado están presentes: el script se recupera y se ejecuta inmediatamente, antes de que el navegador continúe analizando la página


El atributo de diferir es solo para scripts externos (solo debe usarse si el atributo src está presente).


Este atributo booleano se configura para indicar a un navegador que el script debe ejecutarse después de que se haya analizado el documento. Dado que esta función aún no ha sido implementada por todos los demás navegadores principales, los autores no deben asumir que la ejecución del script realmente será diferida. Nunca llame a document.write () desde un script de aplazamiento (desde Gecko 1.9.2, esto eliminará el documento). El atributo de aplazamiento no se debe usar en scripts que no tienen el atributo src. Desde Gecko 1.9.2, el atributo de aplazamiento se ignora en los scripts que no tienen el atributo src. Sin embargo, en Gecko 1.9.1 incluso los scripts en línea se difieren si se establece el atributo de aplazamiento.

diferir funciona con chrome, firefox, es decir,> 7 y Safari

ref: https://developer.mozilla.org/en-US/docs/HTML/Element/script


La respuesta real es: porque no se puede confiar en diferir.

En concepto, diferir y asíncrono difieren de la siguiente manera:

async permite que la secuencia de comandos se descargue en segundo plano sin bloquear. Luego, en el momento en que finaliza la descarga, la representación se bloquea y ese script se ejecuta. El render se reanuda cuando el script se ha ejecutado.

aplazar hace lo mismo, excepto las reclamaciones para garantizar que los scripts se ejecuten en el orden en que se especificaron en la página, y que se ejecutarán una vez que el documento haya terminado de analizarse. Por lo tanto, algunos scripts pueden terminar de descargarse y luego sentarse y esperar por los scripts que se descargaron más tarde pero aparecieron antes que ellos.

Desafortunadamente, debido a lo que realmente es una pelea de gatos estándar, la definición de diferimientos varía según las especificaciones, e incluso en las especificaciones más recientes no ofrece una garantía útil. Como lo demuestran las respuestas here y este problema , los navegadores implementan diferir de manera diferente:

  • En ciertas situaciones, algunos navegadores tienen un error que hace que los scripts de defer desordenen.
  • Algunos navegadores retrasan el evento DOMContentLoaded hasta después de que se hayan cargado los scripts de DOMContentLoaded , y otros no.
  • Algunos navegadores obedecen, defer en los elementos <script> con código en línea y sin un atributo src , y algunos lo ignoran.

Afortunadamente, la especificación al menos especifica que las anulaciones asíncronas difieren. Por lo tanto, puede tratar todos los scripts como asíncronos y obtener una amplia variedad de soporte de navegador como:

<script defer async src="..."></script>

El 98% de los navegadores en uso en todo el mundo y el 99% en los EE. UU. Evitarán el bloqueo con este enfoque.

(Si necesita esperar hasta que el documento haya terminado de analizarse, escuche el evento DOMContentLoaded evento o use la función .ready() jQuery. Desea hacer esto de todos modos para retroceder con gracia en los navegadores que no implementan la defer en todos.)



defer solo se puede utilizar en la etiqueta <script> para la inclusión de scripts externos . Por lo tanto, se recomienda su uso en las etiquetas <script> en la sección <head> .