¿Cuáles son los pros y los contras de la adición de <script> and <link> elementos con JavaScript?

StackOverflow https://stackoverflow.com/questions/5302623

Pregunta

Recientemente vi un HTML con un solo <script> elemento en su <head>...

<head>
    <title>Example</title>
    <script src="script.js" type="text/javascript"></script>
    <link href="plain.css" type="text/css" rel="stylesheet" />
</head>

Este script.js a continuación, agrega cualquier otro <script> elementos y <link> elementos para el documento utilizando document.write(...):(o podría usar document.createElement(...) etc)

document.write("<link href=\"javascript-enabled.css\" type=\"text/css\" rel=\"styleshet\" />");
document.write("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js\" type=\"text/javascript\"></script>");
document.write("<script src=\"https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js\" type=\"text/javascript\"></script>");
document.write("<link href=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/trontastic/jquery-ui.css\" type=\"text/css\" rel=\"stylesheet\" />")
document.write("<script src=\"validation.js\" type=\"text/css\"></script>")

Tenga en cuenta que hay un plain.css Archivo CSS en el documento <head> y script.js sólo añade cualquier y todos los CSS y JavaScript, lo cual podría ser utilizado por un JS-habilitado de agente de usuario.

¿Cuáles son algunos de los pros y los contras de esta técnica?

¿Fue útil?

Solución

La naturaleza de bloqueo de document.write

document.write Pausará todo lo que el navegador está trabajando en la página (incluido el análisis). Es muy recomendable evitar Debido a este comportamiento de bloqueo. El navegador no tiene forma de saber lo que vas a barajar en el flujo de texto HTML en ese punto, o si la escritura basará totalmente todo en el árbol DOM, por lo que tiene que detenerse hasta que hayas terminado.

Esencialmente, la carga de scrips de esta manera obligará al navegador a dejar de analizar HTML. Si su script está en línea, el navegador también ejecutará esos scripts antes de que continúe. Por lo tanto, como nota al margen, siempre se recomienda que difiera los scripts de carga hasta que después Su página está analizada y ha mostrado una interfaz de usuario razonable al usuario.

Si sus scripts se cargan desde archivos separados en el atributo "SRC", entonces los scripts pueden no ejecutarse constantemente en todos los navegadores.

Perder Optimizaciones de velocidad y previsibilidad del navegador

De esta manera, pierde muchas de las optimizaciones de rendimiento realizadas por los navegadores modernos. Además, cuando sus scripts se ejecutan puede ser impredecible.

Por ejemplo, algunos navegadores ejecutarán los scripts justo después de "escribirlos". En tales casos, pierde descargas paralelas de scripts (porque el navegador no ve la segunda etiqueta de script hasta que ha descargado y ejecutado el primero). Pierde descargas paralelas de scripts y hojas de estilo y otros recursos (muchos navegadores pueden descargar recursos, hojas de estilo y scripts, todo al mismo tiempo).

Algunos navegadores aplazan los scripts hasta después del final para ejecutarlos.

El navegador no puede continuar analizando el HTML mientras documenta. Write está continuando y, en ciertos casos, cuando los scripts escritos se ejecutan debido al comportamiento de bloqueo de document.write, entonces su página aparece mucho más lenta.

En otras palabras, su sitio se ha vuelto tan lento como cargando en un navegador de décadas sin optimizaciones.

¿Por qué alguien lo haría así?

La razón por la que es posible que desee usar algo como esto suele ser para mantener la capacidad. Por ejemplo, puede tener un sitio enorme con miles de páginas, cada una cargando el mismo conjunto de scripts y hojas de estilo. Sin embargo, cuando agrega un archivo de script, no desea editar miles de archivos HTML para agregar las etiquetas de script. Esto es particularmente problemático al cargar bibliotecas JavaScript (por ejemplo, dojo o jQuery): debe cambiar cada página HTML cuando actualiza a la próxima versión.

El problema es que JavaScript no tiene una declaración @include o @import para que incluya otros archivos.

Algunas soluciones

La solución a esto probablemente no sea inyectando scripts a través de document.write, pero por:

  1. Usar las directivas de @import en hojas de estilo
  2. Uso de un lenguaje de secuencias de comandos de servidor (por ejemplo, PHP) para administrar su "página maestra" y para generar todas las demás páginas (sin embargo, si no puede usar esto y debe mantener muchas páginas HTML individualmente, esta no es una solución)
  3. Evitar document.write, pero cargue los archivos JavaScript a través de XHR, luego evalúalos (); aunque puede tener preocupaciones de seguridad
  4. Use una biblioteca JavaScript (por ejemplo, dojo) que tiene funciones de carga de módulos para que pueda mantener un archivo JS maestro que cargue otros archivos. Sin embargo, no podrá evitar tener que actualizar los números de versión del archivo de la biblioteca ...

Otros consejos

Una desventaja importante es la incompatibilidad del navegador. No todos los navegadores obtienen e incorporan correctamente los recursos en el DOM, por lo que es arriesgado usar este enfoque. Esto es más cierto para las hojas de estilo que los scripts.

Otro problema es uno de mantenimiento. Concatenar y escribir cadenas para agregar elementos DOM en el lado del cliente puede convertirse en una pesadilla de mantenimiento. Es mejor usar métodos DOM como CreateElement para crear elementos semánticamente.

Una ventaja obvia es que hace que el uso condicional de los recursos sea mucho más fácil. Puede tener una lógica que determine qué recursos cargar, reduciendo así el consumo de ancho de banda y el tiempo general de procesamiento para la página. Usaría una llamada de biblioteca como jQuery $ .getScript () para cargar scripts versus document.write. La ventaja es que este enfoque es más limpio y también le permite ejecutar el código cuando la solicitud se completa o falla.

Bien, me puede tirar mi sombrero en el anillo que en este...

Si usted examina google cierre de la biblioteca, base.js verá que en el documento.se utiliza la escritura en sus writeScriptTag_() la función.Esta es una parte esencial de la gestión de la dependencia del sistema que 'cierre' proporciona, y es una enorme ventaja a la hora de crear una compleja, multi-archivo, biblioteca de base de javascript de la aplicación permite que el archivo/código prerrequisitos determinar el orden de carga.Actualmente el uso de esta técnica y se han de tener problema con ellos.TBH, no hemos tenido un solo problema con la compatibilidad del navegador, y ponemos a prueba con regularidad en IE 6/7/8, FF3/2, Safari 4/5 y Chrome última.

El único inconveniente que hemos tenido hasta ahora es que puede ser difícil para un seguimiento de los problemas causados por la carga de un recurso dos veces, o en su defecto para cargar uno en todo.Desde el acto de la carga de recursos es programático, está sujeta a errores programáticos, y a diferencia de agregar las etiquetas directamente en el HTML, puede ser difícil ver cuál es el exacto orden de carga es.Sin embargo, este problema se puede superar en gran medida por el uso de una biblioteca con alguna forma de gestión de la dependencia del sistema, tales como cierre, o dojo.

EDITAR: He hecho un par de comentarios de esta naturaleza, pero pensé que era mejor para resumir, en mi respuesta:Hay algunos problemas con el dojo.require() y jQuery.getScript() (tanto que ultimiately realizar una petición ajax y eval).

  1. carga a través de ajax significa que no hay cruz de secuencias de comandos - es decir, sin la carga de javascript que no es de su sitio.Este va a ser un problema si usted desea incluir https://ajax.googleapis.com como aparece en la descripción.
  2. Eval había secuencias de comandos no se mostrará en un depurador de javascript de la lista de la página de scripts, lo que la depuración es bastante difícil.Versiones recientes de firebug le mostrará eval gustaría código, sin embargo los nombres de archivo se perdió a hacer que la ley de ajuste de los puntos de interrupción tedioso.AFAIK, Webkit consola de javascript y IE8 herramientas de desarrollador no mostrar eval había secuencias de comandos.

Tiene la ventaja de que no necesita repetir las referencias de script en cada archivo HTML. La desventaja es que el navegador deber Obtenga y ejecute el archivo JavaScript principal antes de que pueda cargar los otros.

Supongo que una ventaja que podría pensar sería que si usas estos scripts en varias páginas, solo tienes que recordar incluir un script, y guarda algo de espacio.

En Google PageSpeed, lo desaniman mucho de usar esta técnica, porque hace que las cosas sean más lentas. Aparte de la carga secuencial de su script.js antes de todos los demás Hay otra captura:

Los navegadores modernos utilizan analizadores especulativos para descubrir de manera más eficiente los recursos externos [...] Por lo tanto, usar el documento de JavaScript.Write () para obtener recursos externos hace que sea imposible que el analizador especulativo descubra esos recursos, lo que puede retrasar la descarga, el análisis y el análisis y el análisis representación de esos recursos.

También es posible que esto haya sido escrito como una recomendación de una empresa de SEO para hacer que el elemento de la cabeza sea más corto si es posible, por lo que el contenido único está más cerca de la parte superior del documento, también crea una relación de texto a HTML más alta. Aunque suena, en general, como una muy buena manera de hacer esto; Aunque haría que el mantenimiento sea más lento, un mejor enfoque probablemente sería condensar a JavaScript en un solo archivo .js y CSS en un solo archivo .css, si se considerara completamente necesario para reducir el tamaño del elemento de la cabeza.

Una gran desventaja es que agregar scriptS en la cabeza detendrá el procesamiento del documento hasta que esos scripts se descargaran completamente analizados y ejecutados (porque el navegador cree que pueden usar document.write). - Esto dañará la capacidad de respuesta.

Hoy en día se recomienda que ponga sus etiquetas de script correctamente Befo </body>. Por supuesto, esto no es posible el 100% de los tiempos, pero si está usando Unbtrusve JavaScript (Como deberías), todos los scripts pueden ser respuestas al final del documento.

HTML5 se le ocurrió el async Atributo que sugiere el navegador solo para ejecutar los scripts después de que se haya cargado el documento principal. Este es el comportamiento de los scripts insertados en scripts en muchos navegadores, pero no en todos ellos.

yo aconsejo contra usando document.write cueste lo que cueste. Incluso sin él, esto da como resultado una solicitud adicional hacia el servidor. (Nos gusta inimizar el número de solicitudes, por ejemplo con Sprites CSS.)

Y sí, como otros mencionaron anteriormente, si el scriping está deshabilitado, su página se mostrará sin CSS (lo que lo hace potencialmente inutilizable).

  1. Si JavaScript es desactivado - <script> and <link> Los elementos no se agregarán en absoluto.

  2. Si coloca funciones de inicio de JavaScript en la parte inferior de su página (que es una buena práctica) y vincula CSS con JavaScript, puede causar un retraso antes de las cargas de CSS (el diseño roto será visible por poco tiempo).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top