¿Por que se dice que los scripts de javascript deben ir en el cierre?
En la web existen muchas recomendaciones acerca de que deben poner el javascript al final del sitio justo antes del cierre del </body>, la razón argumentada es sencilla, los navegadores leían secuencialmente los scripts y bloqueaban el render de la página hasta haberla leído el script, pero entonces ¿por qué razón Ruby on Rails, que supuestamente es construido por expertos carga javascript dentro de la etiqueta <head> </head> en lugar del cierre de la página?.
¿Entonces por qué Rails los pone al principio?
Hay 2 razones:
La primera es porque todos los navegadores modernos (incluyendo internet explorer 8) a partir del 2008 incorporaron un sistema llamado preload scanning que les permite cargar todos los scripts paralelamente sin causar bloqueos (bueno, realmente los bloqueos todavía existen, pero son parciales y ya ahondaremos más sobre como eliminarlos).
El segundo problema de agregar javascript al inicio consiste en que a veces alguna funcionalidad crítica de la página (o de tu negocio) depende de esos javascript, por ejemplo si pones google analytics al final, en el cierre del body y el usuario sale del sitio antes de terminar cargar la página entonces pierdes la data del usuario, otra de las funcionalidades críticas de Rails viene dada por jquery-ujs, si esto se cargara al final de la página tendríamos un problema con los usuarios que son del tipo Quicky Clicker y presionan el los links antes de que la página termine de cargar.
Más sobre Preload Scanning
Preload Scanning no evita completamente el bloqueo, su implementación cambia dependiendo del navegador, pero en términos básicos consiste en un light weight process que se levanta para seguir leyendo archivos css, imágenes u otros scripts cuando se topa con un script. Pero esta lectura es sólo de forma parcial, por lo que sigue siendo recomendado en muchos casos poner javascript al final.
Otra forma de optimizar el proceso es ponerlo en el head junto con los atributos async o defer, este thread de stackoverflow es bastante aclarativo sobre las diferencias, sin embargo como todo lo asincrónico se recomienda implementar con cuidado.
¿Que dice google al respecto?
Técnicamente el guideline oficial de google developers dice que debes evitar en lo posible bloquear, en otras palabras cargar javascript, si lo haces, hazlo al final, ocupa async y defer cuando puedas y si el script es pequeño, es mejor tenerlo dentro del html (esto último si que me lo esperaba) debido que al evitar el llamado disminuyes la latencia de los requests.
Sugerencias finales:
Nada de lo leído quiere decir que uno pueda poner en cualquier parte cualquier script, muchos de ellos tienen dependencias, otros necesitan el DOM cargado y como no están bien programados hay que agregarlos necesariamente al final, a fin de cuentas el preload scanning lo que lo logra es evitar que la lectura de un script de javascript bloquee la lectura del HTML.
En resumen:
si las funcionalidad es crítica en el head, sino en el cierre del body, si el javascript consiste sólo en un par de líneas puede ir inline para optimizar la carga.
Referencias:
http://andydavies.me/blog/2013/10/22/how-the-browser-pre-loader-makes-pages-load-faster/
http://railsapps.github.io/rails-javascript-include-external.html
http://stackoverflow.com/questions/436411/where-is-the-best-place-to-put-script-tags-in-html-markup
https://developers.google.com/speed/docs/insights/BlockingJS
Gonzalo Sánchez
Artículos relacionados
8 Comentario
Deja una respuesta
Recibe los artículos más leidos y beneficios especiales de nuestra academia
Empieza a trabajar en los roles digitales mejor pagados
Fórmate de manera práctica, e intensiva, con sesiones en vivo de forma flexible y efectiva. Te acompañamos desde que partes hasta que encuentras trabajo.
buen articulo
buen consejo…
gonzalo, pruebe usar highcharts declarando los js de la libreria en el head!!! lo he intentado en rails, django y otros FWs… y no funciona!!! saludos.
Lo que dice el artículo que la carga de javascript no bloquea la página, pero eso no quiere decir que puedas agregar cualquier javascript donde quieras, si algún js depende específicamente de que cierta parte del DOM esté cargado, necesitas ponerlo después de esa sección.
Estaría bueno saber que desventaja existe en poner los scripts al final… el articulo dice Estás equivocado, mi pregunta es ¿equivocado en que? no terminas de aclararlo.
si, toda la razón, tengo que complementar mejor el artículo, hay un par de razones por ejemplo si quieres capturar información de que el usuario entró (ejemplo analytics) y lo pones al final y el usuario se retira antes de terminar de cargar la página pierdes el dato, también un usuario que haga click en borrar un elemento y ese link depende de alguna forma de jquery (como pasa en rails para poner los data-methods) entonces tampoco estará cargado y el link no funcionará.
Por experiencia propia, es mejor cargar todas las librerías antes del cierre del body (fuera de que se vea mas ordenado) a excepción de Google Analitycs que tiene que estar en el head como dices, pero existen casos en los que tienes que poner otros scrips en el head y eso también esta bien. Osea a fin de cuentas no esta mal ponerlo al final pero hay que tener cuidado con ciertos scripts que si necesitan estar en el head.
Yo prefiero cargar el js al final, una forma de solucionar el problema de interacción antes de que cargue la información es activar las acciones del usuario una vez cargada toda la página. Por ejemplo que por defecto todos los botones e inputs aparezcan deshabilitados hasta terminar la carga (en este caso se puede implementar un loader o un modal con un mensaje de espera). Pienso que es mas importante optimizar la páginas para que carguen lo mas rápido posible y evitar todos estos errores. Si se trabaja con muchas imagenes como por ejemplo en el caso de una galería, se puede usar un proceso de carga dinámica, es decir que cargue las imagenes con el js una vez cargado el resto del documento.