¿Cuándo debo usar Javascript en línea frente a Javascript externo?

129

Me gustaría saber cuándo debo incluir scripts externos o escribirlos en línea con el código html, en términos de rendimiento y facilidad de mantenimiento.

¿Cuál es la práctica general para esto?

Escenario del mundo real: tengo varias páginas html que necesitan validación de formularios del lado del cliente. Para esto utilizo un complemento jQuery que incluyo en todas estas páginas. Pero la pregunta es, ¿yo:

  • escribe los bits de código que configuran este script en línea?
  • ¿incluye todos los bits en un archivo que se comparte entre todas estas páginas html?
  • ¿incluye cada bit en un archivo externo separado, uno para cada página html?

Gracias.

Dan Burzo
fuente

Respuestas:

114

En el momento en que esta respuesta se publicó originalmente (2008), la regla era simple: todo el script debería ser externo. Tanto por mantenimiento como por rendimiento.

(¿Por qué el rendimiento? Porque si el código está separado, los navegadores pueden almacenarlo más fácilmente).

JavaScript no pertenece al código HTML y si contiene caracteres especiales (como <, por ejemplo >), incluso crea problemas.

Hoy en día, la escalabilidad web ha cambiado. La reducción del número de solicitudes se ha convertido en una consideración válida debido a la latencia de realizar múltiples solicitudes HTTP. Esto hace que la respuesta sea más compleja: en la mayoría de los casos, todavía se recomienda tener JavaScript externo . Pero para ciertos casos, especialmente piezas de código muy pequeñas, tiene sentido incluirlas en el HTML del sitio.

Konrad Rudolph
fuente
66
@ Nick: la mayoría de los problemas se pueden superar. Sin embargo, es mejor no generarlos en primer lugar.
Konrad Rudolph el
17
A veces obtienes un mejor rendimiento cuando estás en línea. Mira la fuente de google.com . Ellos saben lo que están haciendo.
callum
13
@callum Google tiene un caso de uso diferente del 99.999999% de los sitios web. Por supuesto, miden con mucho cuidado e incluso la diferencia más pequeña es importante. Pero solo porque descubrieron que en su caso de uso particular, la alineación funciona mejor (¿probablemente porque el script cambia con mucha frecuencia?) No significa que podamos derivar una regla general de eso, o incluso que debamos ignorar lo "convencional" regla (para externalizar guiones).
Konrad Rudolph el
8
@KonradRudolph: De acuerdo, no se debe derivar ninguna regla general del enfoque de Google. Solo digo que es una pista de que valdría la pena cuestionar la regla en su respuesta. De todos modos, creo que la razón por la que Google lo hace es para reducir las solicitudes HTTP, y esto podría beneficiar a más del 0.000001% de los sitios. El ancho de banda es cada vez mayor, pero los tiempos de ida y vuelta se mantienen igual. Eliminar una solicitud HTTP serie completa a veces es mejor que el beneficio de almacenamiento en caché de JS externo. Depende del tamaño de su JS, por supuesto.
callum
55
@callum Si bien esto es cierto, el punto sobre el almacenamiento en caché sigue siendo importante. Reducir los viajes de ida y vuelta solo es importante si sus visitantes no regresan (y luego no obtendrá suficientes visitas a la página para que sea importante) o si su contenido cambia con tanta frecuencia que el almacenamiento en caché de los archivos de script no tiene ningún beneficio.
Konrad Rudolph el
31

La capacidad de mantenimiento es definitivamente una razón para mantenerlos externos, pero si la configuración es de una sola línea (o, en general, más corta que la sobrecarga de HTTP que obtendría por hacer que esos archivos sean externos), en términos de rendimiento, es mejor mantenerlos en línea. Recuerde siempre que cada solicitud HTTP genera una sobrecarga en términos de tiempo de ejecución y tráfico.

Naturalmente, todo esto se vuelve irrelevante en el momento en que su código es más largo que un par de líneas y no es realmente específico para una sola página. En el momento en que desee poder reutilizar ese código, hágalo externo. Si no lo hace, mire su tamaño y decida entonces.

Horst Gutmann
fuente
55
Esa es una de mis preocupaciones. Tener una solicitud HTTP separada para algunas líneas de códigos parece un desperdicio.
Dan Burzo
¿Podría publicar una configuración de muestra para su código? OMI si tiene menos de 300 caracteres y es absolutamente específico de la página, inline.
Horst Gutmann
Esta debería ser la mejor respuesta imo
sgarcia.dev
@ Tenga en cuenta que la solicitud por separado solo ocurre la primera vez. Si espera que sus usuarios carguen la página más de una vez, el almacenamiento en caché externo (incluso para algunas líneas) es claramente más rápido que esperar los bytes para esas pocas líneas sobre el cable en las cargas de página n = 2 +.
jinglesthula
@HorstGutmann ¿de qué manera tener el archivo ayuda externa con la mantenibilidad? Personalmente prefiero js externos siempre que sea posible, pero ¿hay algo objetivo que facilite el mantenimiento?
jinglesthula
21

Externalizar javascript es una de las reglas de rendimiento de yahoo: http://developer.yahoo.com/performance/rules.html#external

Si bien la regla estricta de que siempre debe externalizar los scripts generalmente será una buena apuesta, en algunos casos es posible que desee incluir algunos de los scripts y estilos. Sin embargo, solo debe incluir cosas en línea que sepa que mejorarán el rendimiento (porque lo ha medido).

Joeri Sebrechts
fuente
1
Creo que Yahoo también recomienda la adición de todo el Javascript en una llamada HTTP también - esto no significa que los scripts deben estar todos en el mismo archivo, aunque durante el desarrollo
Paul Shannon
Además, como se señaló anteriormente, HTTP / 2 también cambia la práctica de "1 llamada".
jinglesthula
19

Si solo le importa el rendimiento, la mayoría de los consejos en este hilo son totalmente erróneos y cada vez son más incorrectos en la era SPA, donde podemos suponer que la página es inútil sin el código JS. He pasado innumerables horas optimizando los tiempos de carga de la página SPA y verificando estos resultados con diferentes navegadores. En general, el aumento del rendimiento al reorganizar su html puede ser bastante dramático.

Para obtener el mejor rendimiento, debe pensar en las páginas como cohetes de dos etapas. Estas dos etapas corresponden aproximadamente a las fases <head>y <body>, pero piense en ellas como <static>y <dynamic>. La parte estática es básicamente una constante de cadena que empuja hacia abajo el tubo de respuesta lo más rápido posible. Esto puede ser un poco complicado si usa una gran cantidad de middleware que configura las cookies (estas deben configurarse antes de enviar contenido http), pero en principio solo está descargando el búfer de respuesta, con suerte antes de saltar a algún código de plantilla (razor, php, etc) en el servidor. Esto puede sonar difícil, pero solo lo estoy explicando mal, porque es casi trivial. Como habrás adivinado, esta parte estática debe contener todos los JavaScript incluidos y minimizados. Se vería algo así como

<!DOCTYPE html>
     <html>
         <head>
             <script>/*...inlined jquery, angular, your code*/</script>
             <style>/* ditto css */</style>
         </head>
         <body>
             <!-- inline all your templates, if applicable -->
             <script type='template-mime' id='1'></script>
             <script type='template-mime' id='2'></script>
             <script type='template-mime' id='3'></script>

Dado que le cuesta casi nada enviar esta porción por el cable, puede esperar que el cliente comience a recibir esto en algún lugar alrededor de 5 ms + latencia después de conectarse a su servidor. Suponiendo que el servidor está razonablemente cerca, esta latencia podría estar entre 20 ms y 60 ms. Los navegadores comenzarán a procesar esta sección tan pronto como la obtengan, y el tiempo de procesamiento dominará normalmente el tiempo de transferencia por un factor 20 o más, que ahora es su ventana amortizada para el procesamiento del lado del servidor<dynamic> .

El navegador tarda aproximadamente 50 ms (cromo, el resto puede ser un 20% más lento) para procesar jquery en línea + señalizador + angular + ng animado + ng táctil + ng rutas + lodash. Eso es bastante sorprendente en sí mismo. La mayoría de las aplicaciones web tienen menos código que todas esas bibliotecas populares juntas, pero supongamos que tiene la misma cantidad, por lo que ganaríamos latencia + 100 ms de procesamiento en el cliente (esta ganancia de latencia proviene del segundo fragmento de transferencia). Cuando llega el segundo fragmento, hemos procesado todos los códigos y plantillas js y podemos comenzar a ejecutar transformaciones dom.

Puede objetar que este método es ortogonal al concepto de alineación, pero no lo es. Si, en lugar de en línea, vincula a cdns o sus propios servidores, el navegador tendría que abrir otra (s) conexión (es) y retrasar la ejecución. Dado que esta ejecución es básicamente gratuita (ya que el lado del servidor está hablando con la base de datos), debe quedar claro que todos estos saltos costarían más que no hacer ningún salto. Si hubiera una peculiaridad del navegador que dijera que js externo se ejecuta más rápido, podríamos medir qué factor domina. Mis mediciones indican que las solicitudes adicionales matan el rendimiento en esta etapa.

Trabajo mucho con la optimización de aplicaciones de SPA. Es común que las personas piensen que el volumen de datos es un gran problema, mientras que, en verdad, la latencia y la ejecución a menudo dominan. Las bibliotecas minimizadas que enumeré agregan hasta 300 kb de datos, y eso es solo 68 kb descomprimidos, o 200 ms de descarga en un teléfono 2mbit 3g / 4g, que es exactamente la latencia que tomaría en el mismo teléfono para verificar si tenía los mismos datos en su caché ya, incluso si era proxy en caché, porque el impuesto de latencia móvil (latencia de teléfono a torre) todavía se aplica. Mientras tanto, las conexiones de escritorio que tienen una latencia de primer salto más baja generalmente tienen un ancho de banda más alto de todos modos.

En resumen, en este momento (2014), es mejor incorporar todos los scripts, estilos y plantillas.

EDITAR (MAYO 2016)

A medida que las aplicaciones JS continúan creciendo, y algunas de mis cargas ahora se acumulan a más de 3 megabytes de código minificado, se hace evidente que, al menos, las bibliotecas comunes ya no deberían estar en línea.

Gleno
fuente
No obtuve el que ahora es su ventana amortizada para el procesamiento del lado del servidor de la parte de la parte <dynamic> : el servidor procesa lo que necesita y solo luego sirve todo el html procesado (head + body), qué otro procesamiento del servidor se necesita después de eso?
BornToCode
@BornToCode La idea es darle al cliente algo que hacer al mismo tiempo que el lado del servidor tiene algo que hacer. Debido a que las bibliotecas del cliente deben ser interpretadas, es mejor comenzar ese proceso antes de realizar cualquier cálculo en el servidor. La ventana amortizada es el tiempo que le toma al cliente procesar el JS. Obtienes esa ventana gratis si organizas un cohete de 2 etapas.
Gleno
9

En realidad, hay un caso bastante sólido para usar JavaScript en línea. Si js es lo suficientemente pequeño (una línea), tiendo a preferir el javascript en línea debido a dos factores:

  • Localidad . No es necesario navegar por un archivo externo para validar el comportamiento de algunos JavaScript
  • AJAX . Si está actualizando alguna sección de la página a través de AJAX, puede perder todos sus controladores DOM (onclick, etc.) para esa sección, dependiendo de cómo los vinculó. Por ejemplo, usando jQuerypuede usar los métodos liveo delegatepara evitar esto, pero encuentro que si js es lo suficientemente pequeño, es preferible simplemente ponerlo en línea.
Miguel Ping
fuente
5

Otra razón por la que siempre debe usar scripts externos es para facilitar la transición a la Política de seguridad de contenido (CSP) . Los valores predeterminados de CSP prohíben todos los scripts en línea, lo que hace que su sitio sea más resistente a los ataques XSS.

chiborg
fuente
4

Echaría un vistazo al código requerido y lo dividiría en tantos archivos separados como sea necesario. Cada archivo js solo contendría un "conjunto lógico" de funciones, etc. un archivo para todas las funciones relacionadas con el inicio de sesión.

Luego, durante el desarrollo del sitio en cada página html, solo incluye aquellos que son necesarios. Cuando entre en funcionamiento con su sitio, puede optimizar combinando todos los archivos js que una página necesita en un solo archivo.

Gene
fuente
4

La única defensa que puedo ofrecer para javascipt en línea es que al usar vistas fuertemente tipadas con .net MVC puede referirse a las variables de c # en JavaScript que me han resultado útiles.

Austin_G
fuente
3

Tres consideraciones:

  • ¿Cuánto código necesita (a veces las bibliotecas son un consumidor de primera clase)?
  • Especificidad: ¿este código solo funciona en el contexto de este documento o elemento específico?
  • Cada código dentro del documento tiende a hacerlo más largo y, por lo tanto, más lento. Además de que las consideraciones de SEO lo hacen obvio, que minimizas las secuencias de comandos internas ...
Roenving
fuente
2

Las secuencias de comandos externas también son más fáciles de depurar con Firebug. Me gusta Unit Test my JavaScript y tenerlo todo ayuda externa. Odio ver JavaScript en código PHP y HTML, me parece un gran desastre.

Embrague
fuente
2

En el punto de mantener JavaScript externo:

ASP.NET 3.5SP1 introdujo recientemente la funcionalidad para crear un recurso de secuencia de comandos compuesta (fusionar un montón de archivos js en uno). Otro beneficio de esto es cuando la compresión del servidor web está activada, la descarga de un archivo un poco más grande tendrá una mejor relación de compresión que muchos archivos más pequeños (también menos sobrecarga de http, ida y vuelta, etc.). Supongo que esto ahorra en la carga inicial de la página, luego el almacenamiento en caché del navegador comienza como se mencionó anteriormente.

Dejando a un lado ASP.NET, este screencast explica los beneficios con más detalle: http://www.asp.net/learn/3.5-SP1/video-296.aspx

Brendan Kowitz
fuente
2

Otro beneficio oculto de los scripts externos es que puede ejecutarlos fácilmente a través de un verificador de sintaxis como jslint . Eso puede salvarlo de muchos errores IE6 desgarradores y difíciles de encontrar.

Conocido
fuente
1

En su situación, parece que escribir las cosas externas en un archivo compartido entre las páginas sería bueno para usted. Estoy de acuerdo con todo lo dicho anteriormente.

mate
fuente
1

Durante la creación de prototipos temprana, mantenga su código en línea para el beneficio de una iteración rápida, pero asegúrese de hacerlo todo externo para cuando llegue a producción.

Incluso me atrevería a decir que si no puede colocar todos sus Javascript externamente, entonces tiene un mal diseño en sus manos, y debería refactorizar sus datos y scripts

Robert Gould
fuente
1

Google ha incluido tiempos de carga en las medidas de clasificación de su página, si se alinea mucho, las arañas tardarán más en rastrear a través de su página, esto puede influir en la clasificación de su página si tiene que incluir mucho. en cualquier caso, diferentes estrategias pueden influir en su clasificación.

Kees Hessels
fuente
1

bueno, creo que deberías usar en línea cuando crees sitios web de una sola página, ya que los scripts no tendrán que compartirse en varias páginas

Zak Sheikh
fuente
-3

Siempre trate de usar Js externos ya que js en línea siempre es difícil de mantener.

Además, se requiere profesionalmente que use un js externo ya que la mayoría de los desarrolladores recomiendan usar js externamente.

Yo mismo uso js externos.

Daniel Puiu
fuente
2
¿Profesionalmente requerido? ¿Por qué? ¿Quién dice eso?
Siyah