Pregunta ¿Dónde debería poner las etiquetas

Al incorporar JavaScript en un documento HTML, ¿dónde está el lugar adecuado para colocar el <script> etiquetas y JavaScript incluido? Me parece recordar que no se supone que coloque estos en el <head> sección, pero colocando al comienzo de la <body> la sección también es mala, ya que el JavaScript tendrá que ser analizado antes de que la página se represente por completo (o algo así). Esto parece dejar el fin del <body> sección como un lugar lógico para <script> etiquetas.

Entonces, dónde es el lugar correcto para poner el <script> etiquetas?

(Esta pregunta hace referencia esta pregunta, en el cual se sugirió que las llamadas a la función de JavaScript se deben mover de <a> etiquetas a <script> etiquetas. Estoy usando específicamente jQuery, pero también son apropiadas respuestas más generales).


1154
2018-01-12 18:15


origen


Respuestas:


Esto es lo que sucede cuando un navegador carga un sitio web con un <script> etiqueta en él:

  1. Obtener la página HTML (por ejemplo, index.html)
  2. Comience a analizar el HTML
  3. El analizador encuentra un <script> etiqueta que hace referencia a un archivo de script externo.
  4. El navegador solicita el archivo de script. Mientras tanto, el analizador bloquea y detiene el análisis del otro HTML en su página.
  5. Después de un tiempo, la secuencia de comandos se descarga y se ejecuta posteriormente.
  6. El analizador continúa analizando el resto del documento HTML.

El paso # 4 causa una mala experiencia del usuario. Su sitio web básicamente deja de cargarse hasta que haya descargado todos los scripts. Si hay algo que los usuarios odian, está esperando que se cargue un sitio web.

¿Por qué sucede esto?

Cualquier script puede insertar su propio HTML a través de document.write() u otras manipulaciones DOM. Esto implica que el analizador debe esperar hasta que se haya descargado y ejecutado el script antes de que pueda analizar de manera segura el resto del documento. Después de todo, el guión podría insertó su propio HTML en el documento.

Sin embargo, la mayoría de los desarrolladores de JavaScript ya no manipulan el DOM mientras el documento se está cargando En su lugar, esperan hasta que el documento se haya cargado antes de modificarlo. Por ejemplo:

<!-- index.html -->
<html>
    <head>
        <title>My Page</title>
        <script type="text/javascript" src="my-script.js"></script>
    </head>
    <body>
        <div id="user-greeting">Welcome back, user</div>
    </body>
</html>

Javascript:

// my-script.js
document.addEventListener("DOMContentLoaded", function() { 
    // this function runs when the DOM is ready, i.e. when the document has been parsed
    document.getElementById("user-greeting").textContent = "Welcome back, Bart";
});

Debido a que su navegador no sabe que my-script.js no va a modificar el documento hasta que no se haya descargado y ejecutado, el analizador deja de analizar.

Recomendación anticuada

El viejo enfoque para resolver este problema era poner <script> etiquetas en la parte inferior de su <body>, porque esto asegura que el analizador no está bloqueado hasta el final.

Este enfoque tiene su propio problema: el navegador no puede comenzar a descargar los scripts hasta que se haya analizado todo el documento. Para sitios web más grandes con grandes scripts y hojas de estilo, poder descargar el script lo antes posible es muy importante para el rendimiento. Si su sitio web no se carga en 2 segundos, las personas irán a otro sitio web.

En una solución óptima, el navegador comenzaría a descargar sus scripts lo antes posible, mientras que al mismo tiempo analizará el resto del documento.

El enfoque moderno

Hoy, los navegadores admiten el async y defer atributos en scripts. Estos atributos le dicen al navegador que es seguro continuar el análisis mientras se descargan los scripts.

asincrónico

<script type="text/javascript" src="path/to/script1.js" async></script>
<script type="text/javascript" src="path/to/script2.js" async></script>

Los scripts con el atributo async se ejecutan de forma asíncrona. Esto significa que el script se ejecuta tan pronto como se descarga, sin bloquear el navegador mientras tanto.
Esto implica que es posible que la secuencia de comandos 2 se descargue y ejecute antes de la secuencia de comandos 1.

De acuerdo a http://caniuse.com/#feat=script-async, El 94.57% de todos los navegadores lo admiten.

aplazar

<script type="text/javascript" src="path/to/script1.js" defer></script>
<script type="text/javascript" src="path/to/script2.js" defer></script>

Los scripts con el atributo defer se ejecutan en orden (es decir, primer script 1, luego script 2). Esto tampoco bloquea el navegador.

A diferencia de las secuencias de comandos asíncronas, las secuencias de comandos diferidas solo se ejecutan después de que se haya cargado todo el documento.

De acuerdo a http://caniuse.com/#feat=script-defer, El 94.59% de todos los navegadores lo admiten. 94.92% lo apoyan al menos parcialmente.

Una nota importante sobre la compatibilidad del navegador: en algunas circunstancias IE <= 9 puede ejecutar scripts diferidos fuera de servicio. Si necesita admitir esos navegadores, lea esta ¡primero!

Conclusión

El estado actual del arte es poner scripts en el <head> etiqueta y usa el async o defer atributos. Esto permite que sus scripts se descarguen lo antes posible sin bloquear su navegador.

Lo bueno es que su sitio web aún debe cargar correctamente en el 6% de los navegadores que no admiten estos atributos mientras acelera el otro 94%.


1464
2018-06-05 21:20



Justo antes de la etiqueta de cierre del cuerpo, como se indica en

http://developer.yahoo.com/performance/rules.html#js_bottom

Ponga scripts en la parte inferior

El problema causado por los scripts es que bloquean las descargas paralelas. La especificación HTTP / 1.1 sugiere que los navegadores no descarguen más de dos componentes en paralelo por nombre de host. Si sirve sus imágenes desde múltiples nombres de host, puede obtener más de dos descargas en paralelo. Sin embargo, mientras se descarga una secuencia de comandos, el navegador no iniciará ninguna otra descarga, incluso en diferentes nombres de host.


218
2018-01-12 18:18



Las etiquetas de script sin bloqueo se pueden colocar casi en cualquier lugar:

<script src="script.js" async></script>
<script src="script.js" defer></script>
<script src="script.js" async defer></script>
  • async script se ejecutará de manera asíncrona tan pronto como esté disponible
  • defer script se ejecuta cuando el documento ha terminado de analizar
  • async defer script vuelve al comportamiento diferir si async no es compatible

Tales scripts se ejecutarán de forma asíncrona / después de la preparación del documento, lo que significa que no puede hacer esto:

<script src="jquery.js" async></script>
<script>jQuery(something);</script>
<!--
  * might throw "jQuery is not defined" error
  * defer will not work either
-->

O esto:

<script src="document.write(something).js" async></script>
<!--
  * might issue "cannot write into document from an asynchronous script" warning
  * defer will not work either
-->

O esto:

<script src="jquery.js" async></script>
<script src="jQuery(something).js" async></script>
<!--
  * might throw "jQuery is not defined" error (no guarantee which script runs first)
  * defer will work in sane browsers
-->

O esto:

<script src="document.getElementById(header).js" async></script>
<div id="header"></div>
<!--
  * might not locate #header (script could fire before parser looks at the next line)
  * defer will work in sane browsers
-->

Una vez dicho esto, los scripts asincrónicos ofrecen estas ventajas:

  • Descarga paralela de recursos:
    El navegador puede descargar hojas de estilo, imágenes y otros scripts en paralelo sin esperar a que se descargue y ejecute un script.
  • Fuente orden independencia:
    Puede colocar las secuencias de comandos dentro de la cabeza o el cuerpo sin preocuparse por el bloqueo (útil si está utilizando un CMS). Sin embargo, la orden de ejecución sigue siendo importante.

Es posible sortear los problemas de orden de ejecución mediante el uso de scripts externos que admiten devoluciones de llamada. Muchas API de JavaScript de terceros ahora son compatibles con la ejecución sin bloqueo. Aquí hay un ejemplo de cargando la API de Google Maps de forma asíncrona.


56
2018-02-06 11:19



El consejo estándar, promovido por Yahoo! Equipo de rendimiento excepcional, es poner el <script> etiquetas al final del cuerpo del documento para que no bloqueen la representación de la página.

Pero hay algunos enfoques más nuevos que ofrecen un mejor rendimiento, como se describe en esta respuesta sobre el tiempo de carga del archivo JavaScript de Google Analytics:

Hay algunos grandes diapositivas por Steve Souders (experto en rendimiento del lado del cliente) sobre:

  • Diferentes técnicas para cargar archivos JavaScript externos en paralelo
  • su efecto sobre el tiempo de carga y la representación de la página
  • qué tipo de indicadores "en progreso" muestra el navegador (por ejemplo, "cargando" en la barra de estado, cursor del reloj de arena).

36
2018-01-12 23:37



Si está usando JQuery, coloque el javascript donde lo encuentre mejor y use $(document).ready() para asegurarse de que las cosas se carguen correctamente antes de ejecutar cualquier función.

En una nota al margen: me gustan todas mis etiquetas de guiones en el <head> sección, ya que parece ser el lugar más limpio.


19
2018-01-12 18:18



XHTML no validará si el script está en otro lugar que no sea dentro del elemento principal. resulta que puede estar en todas partes.

Puede diferir la ejecución con algo así como jQuery, por lo que no importa dónde se coloca (a excepción de un pequeño golpe de rendimiento durante el análisis).


8
2018-01-12 18:22



<script src="myjs.js"></script>
</body>

la etiqueta de script debe usarse siempre antes cuerpo cerca o Abajo en HTML archivo.

entonces puedes ver el contenido de la página primero antes de cargar js archivo.

verifique esto si es necesario: http://stevesouders.com/hpws/rule-js-bottom.php


8
2017-07-16 11:16



La respuesta convencional (y ampliamente aceptada) es "en la parte inferior", porque entonces todo el DOM se habrá cargado antes de que algo pueda comenzar a ejecutarse.

Hay disidentes, por diversas razones, comenzando con la práctica disponible para comenzar intencionalmente la ejecución con un evento de carga de página.


5
2018-01-12 18:18



Dependiendo de la secuencia de comandos y su uso, lo mejor (en términos de carga de página y tiempo de representación) puede ser no usar una etiqueta <script> convencional per se, sino activar dinámicamente la carga de la secuencia de comandos de forma asincrónica.

Existen algunas técnicas diferentes, pero la más directa es usar document.createElement ("script") cuando se desencadena el evento window.onload. A continuación, el script se carga primero cuando la página se ha procesado, lo que no afecta el tiempo que el usuario tiene que esperar para que aparezca la página.

Esto naturalmente requiere que el script en sí no sea necesario para la representación de la página.

Para más información, mira la publicación Acoplamiento de secuencias de comandos asíncronas por Steve Souders (creador de YSlow pero ahora en Google).


0
2018-01-12 21:06