Nueva pregunta

Pregunta:

Fecha: 24-06-2017 08:22:29 (En Español)

¿Cuáles son las mejores prácticas para incluir código JavaScript y CSS en nuestro HTML?[Resuelta]



¿Qué es recomendable: incluir enlaces y códigos Javascript/JQuery en la etiqueta <head> o al final del <body>?

Retomando el tema de curiosidades (creo que importantes en la carga de una página) y, por qué no, de buenas prácticas.

Quiero confrontar experiencias y recomendaciones.

Hace algún tiempo que me cuestionaron la inclusión de los códigos Javascript dentro de la página (como siempre lo hacía con códigos más o menos cortos) dentro del <head>, tanto con enlaces a archivos externos como códigos más o menos cortos.

Efectivamente me encontraba con que "la recomendación más extendida consiste en enlazarlo o incluirlo al final de la página, justo antes de la etiqueta </body> de cierre" y con una explicación satisfactoria:
El problema de los scripts es que mientras se descargan, bloquean la descarga de otros contenidos importantes de la página, como por ejemplo las imágenes.
No obstante, las mismas buenas prácticas de Yahoo! indican que a veces es imposible enlazar el código JavaScript al final de la página, como por ejemplo cuando el código modifica el contenido de la página con instrucciones de tipo document.write(...).


Dos ejemplos sencillos:

Javascript en head
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>Javascript en head</title>
    <script>
      alert("El body todavía no existe!!")
    </script>
  </head>
  <body>
    <h1>Javascript en head</h1>
    <p>Hola mundo</p>
  </body>
</html>

Javascript al final del body
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>Javascript al final del body</title>
  </head>
  <body>
    <h1>Javascript al final del body</h1>
    <p>Hola mundo</p> 
    <script>
      alert("El body esta listo y lo puedes ver en el fondo")
    </script>
  </body>
</html>


Todo correcto, pero cuando cargamos librerías como JQuery, Google Maps, algún plugin (a veces nos encontramos con hasta 6, 8, 10 archivos externos o propios que suman cientos o miles de líneas), ¿qué hacer?.

Una técnica que utilizo frecuentemente con Google Maps (y generalmente JQuery incluido) es la carga asíncrona.
Sería algo así:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" async="async"></script>


Otra técnica ( librosweb.es) consiste en utilizar el atributo defer, que indica al navegador que el código JavaScript enlazado se puede descargar y procesar después de que la página se haya cargado completamente. Esta práctica no la he usado. Sería
<script type="text/javascript" defer src="..."></script>


Otra solución (y esta es la que posiblemente utilizo más) es
// código Js
window.onload = function() {
   /* Aquí la instancia a eventos desde elementos que ya
      están cargados dentro de la página */
}


Google Analytics utiliza el método asincrono pero con sus propios códigos.

En fin, el debate está servido.
Dejo abierta la página a sus experiencias y sus recomendaciones.

Saludos.
Etiquetas: HTML - HTML5 - Javascript - JQuery - Mejores Prácticas - Opinión - Pregunta - Sugerencia Votos: 3 - Respuestas: 6 - Vistas: 44 Compartir en: Google Facebook Twitter LinkedIn Link
 

Respuestas:

  • Fecha: 24-06-2017 12:36:23 Vaya como ampliación al tema, en usos con JQuery:
    En los dos primeros casos, las funciones actúan después de que se carguen los elementos HTML, sea el DOM o el HTML completo

    .ready actúa cuando el DOM de su página está listo para ser manipulado.
    $(document).ready(function(){
     //código
     }); 

    load es similar a ready, pero espera a que se cargue toda la página (desde <html< hasta </html>
    $(window).on( "load" , function () { 
     //código 
     });


    Tema diferente pero relacionado con el elemento load (carga) es el utilizado en el entrono AJAX (ejemplos tomados de www.w3schools.com/jquery/jquery_ajax_load.asp:)
    $("#div1").load("demo_test.txt");
    $("#div1").load("demo_test.txt #p1");
    o más complejo:
    $("#result").load("ajax/test.html", function() {
      alert( "Carga realizada.");
    });


    Creo que cabe entender que en estos casos, async o defer no son necesarios
    (ni el planteamiento de trabajarlos en head o al final de body).
    A menos que tengamos alguna observación de buenas prácticas.

    Sería interesante comparar otras funciones, que creo abundan en JQuery, sobre la ejecución en tiempo de carga de la página.

    Saludos
      Votos: 3 - Link respuesta
     
  • Fecha: 26-06-2017 03:15:02 Buenos días, para el caso de que se utilice del evento load para cargar una página, puede suceder que se ejecuten las funciones en el js de la página a cargar antes de que se muestre. Esto sucede si el js está llamado desde la página principal. En ese caso, lo que hago (y lo hago para todas las páginas, lo llame con load o no) es cargar el js desde cada página. Al principio o al final del html que deseo cargar, enlazo el js correspondiente. En este caso, todas las librerías en la página principal, las enlazo en el head porque deben estar disponibles para la página que cargo desde load.
    En el caso de que lo maneje de otra manera, trato de enlazarlo desde en el body. En jQuery, como bien dice Txema Artzain, comienza a "ejecutarse" una vez que cargó la página (con las excepciones del load antes mencionado) pero el problema no es que comience a funcionar la página, sino que se muestre rápido para que el cliente vea "algo" y no una página en blanco.
      Votos: 1 - Link respuesta
     
  • Fecha: 26-06-2017 03:36:37 Hola Txema, muy interesante este tema, te dejo mis comentarios del caso.

    * Carga asíncrona de JavaScript por medio del atributo async="async": es una buena opción pero hay que tener presente que los archivos se cargan en paralelo, y si uno depende de otro no hay forma de marcar precedencia, y es aquí donde se produce el famoso error por condición de carrera. Por ejemplo: imaginemos que incluimos la librería JQuery y luego un script corto que hace uso de la misma, primero se va a cargar el script corto y al no encontrar la librería JQuery cargada fallará, luego se cargará la librería (ya que su peso será mayor), pero ya será tarde, porque el script que hace uso de la misma ya se ejecuto y falló.

    * El atributo defer se utiliza para indicar que el script se ejecute cuando la pagina finaliza su parsing. En lo personal yo no utlizo este atributo, ya que defer tiene el problema de no garantizar en todos los casos la ejecución ordenada de los script, por lo cual, nuevamente la condición de carrera puede ser un problema.
    Nota: si se utiliza un DOCTYPE XHTML la forma correcta de emplear el atributo es: defer="defer".

    * El evento onload es lanzado cuando todo el contenido de nuestra web ha finalizado su carga y ejecución (HTML, imágenes, CSS y Javascript). Aquí recomiendo utilizar el código comentado por el usuario de librosweb (para que sea cross browser).
    <script type="text/javascript">
    function cargarCodigoJavaScript() {
        var element = document.createElement("script");
        // el archivo `codigo_javascript.js` contiene todo el código
        // JavaScript que no se ejecuta antes de cargar la página
        element.src = "codigo_javascript.js";
        document.body.appendChild(element);
    }
     
    if (window.addEventListener) {
        window.addEventListener("load", cargarCodigoJavaScript, false);
    } else if (window.attachEvent) {
        window.attachEvent("onload", cargarCodigoJavaScript);
    } else {
        window.onload = cargarCodigoJavaScript;
    }
    </script>
    


    En lo personal utilizo una combinación de colocar scripts en la etiqueta head y antes del cierre del body, y en casos muy particulares una "carga perezosa" (lazy load) luego del evento onload (como en el último script ejemplificado aquí).

    Saludos y buen código!
      Votos: 4 - Link respuesta
     
  • Fecha: 28-06-2017 18:34:18 Aquí les dejo una liga muy interesante de Google que trata el tema.

    https://developers.google.com/speed/docs/insights/BlockingJS

    Saludos
      Votos: 4 - Link respuesta
     
  • Fecha: 29-06-2017 03:15:48 Hola Ernesto, +1 por el link, interesante el video que enlaza (que para los que entienden ingles esta muy bien), aquí lo incluyo en la comunidad:

    Recomendaciones para el uso de JavaScript y CSS en nuestras apps web (ingles)



    Nota: Inicio en tiempo 14m28s

    Algunos comentarios extras.

    A nivel CSS:
    * Tener presente que la inclusión de CSS no soporta el atributo "async" y no lo puedes agregar al final del HTML (como en el caso del JavaScript).
    * No inlcuir datos en el CSS (como ser imagenes incrustadas).
    * Minimizar el código y colocarlo en una sola línea (suprimiendo los espacios, tabulaciones, saltos de línea y comentarios).
    * Código incrustado: incluir tu CSS crítico como código incrustado (dentro de tu head con las etiquetas <style>....</style>) para evitamos la llamada remota. Debemos tener presente que perdemos la posiblidad de cache, consumiendo mayor ancho de banda en llamas sucesivas (por eso, de haberlo, el contenido incrustado debe ser pequeño y solo el crítico para el render de la página).

    A nivel JavaScript:
    * Cargar asincronicamente siempre que sea posible por medio del atributo "async".
    * Minimizar el código JavaScript.
    * Utilizar un "server-side rendering" siempre que sea posible, usar un framework JavaScript para dar soporte a esto <-- en lo personal no lo he aplicado, pero según indican típicamente aumenta x5 la velocidad.

    Saludos y buen código!
      Votos: 3 - Link respuesta
     
  • Fecha: 30-06-2017 01:03:09 Gracias por las aportaciones.

    Me han parecido muy interesantes dos aspectos mencionados por Fernando:
    - El famoso error por condición de carrera (algo muy lógico, que explicado parece de Perogrullo pero no siempre tenido en cuenta y que nos permite evaluar si nos merece la pena una carga asíncrona).
    - La importancia de coordinar la mejor carga de CSS y Javascript, y por este orden.

    Algo también apuntado desde el enlace de Ernesto (y que en algún modo nos apunta hacia ambos aspectos) donde se reitera la optimización de la carga CSS.

    Sería interesante seguir evaluando "server-side rendering" y posiblemente otras ideas.

    Dejo abierta la pregunta a otros aspectos que nos puedan deparar las musas y la experiencia de los programadores.

    Saludos.
      Votos: 1 - Link respuesta
     
Para participar activamente de la comunidad primero debes autenticarte, ingresa al sistema.Iniciar Sesión
 
frjcbbae garagebible.com