Cómo cargar css y js y no bloquear la carga de contenido

Publicado el 11 de Octubre del 2017 por Lino Uruñuela

Como muchos habréis notado he rediseñado el blog, que ya era hora después de 11 años con el mismo diseño. Los motivos han sido varios

Mobile First

El híper anunciado índice móvil parece ser que está llegando este mes, cosa que ya anunció Google hace bastante tiempo, que no se diga que no nos lo viene avisando con antelación y últimamente con mucha mayor frecuencia. Nadie sabemos cómo afectará a la mayoría de los sites, tendremos que ir aprendiendo según se vaya implementando y vayamos sufriendo sus efectos, mientras tanto todo son especulaciones, pero que no quepa duda que esto es un cambio de paradigma.

Es casi la principal causa de mi "puesta a punto", no vale con decir qe debemos pensar en móvil, que el futuro, o mejor dicho, el presente es el Responsive Desing, hay que hacerlo. No hay nada como remangarse y meterse en la fango para aprender cualquier materia en profundidad.


Está claro, que cómo yo, no vas a ser un experto en diseño, maquetación y experiencia de usuario, o sí... pero hay que tener unos mínimos conocimientos sobre el tema, porque eso de repetir las típicas  frases "Mobile First" y "pensar en móvil" no va conmigo. Yo soy más de hacer cosas, y por supuesto eso también conlleva cagarla en muchas ocasiones, pero cómo siempre digo, los experimentos se hacen con gaseosa, y con gaseosa me refiero a mis propios proyectos.

Así que yo, aunque algo tarde, intento ponerme las pilas con Bootstrap, jQuery y  experiencia de usuario, y rediseñar el blog está siendo mi primer paso.


Aprender peleando

Enfrentarse a las mismas problemáticas a las que se enfrentan los desarrolladores cuándo los SEO decimos, "esto debe ser así" y el saber los costes de las tareas que definimos en nuestro día a día nos otorga una visión más amplia para poder realizar mejores estrategias en cuanto a tiempos y prioridades.

Además, muchos de los problemas que identificamos y para los que pedimos solución a los desarrolladores (incluso hasta exigimos) no son de la atención de los técnicos, y hasta ahora no lo era de nadie.

Crear una maquetación que no conteniga elementos que bloquén la visualización del contenido, concretando,  "que bloquén la visualización del contenido de la mitad superior de la página" que es tal cómo nos alerta PageSpeed Insights,  (herramienta de Google que "mide el rendimiento de las páginas para dispositivos móviles y para ordenadores"), de que debemos mejorar la carga del site para no perjudicar la experiencia de nuestros usuarios cuando acceden por medio del móvil, esto es algo relativamente nuevo.

Antes del boom móvil, que nos ha conducido al uso masivo de estos dispositivos para acceder a internet, esos detalles a la hora de cargar los elementos del DOM como scripts, hojas de estilos o imágenes optimizadas era una "frikada", ya que desde ordenadores "normales" este tipo de optimizaciones a la hora de cargar elementos del DOM no influía en nada, o prácticamente no era relevante, en la experiencia de los usarios a la hora de acceder a la información.

Pero con los móviles es distinto, son más lentos que un ordenador, y también suele ser más lenta la velocidad de conexión, por lo que determinados detalles cómo el orden en que se cargan los elementos parece ser que influye, y bastante, en la satisfacción de los usaurios que acceden.

Sin más dilación voy a explicar brevemente cómo he realizado esta maquetación del blog obteniendo una "puntación" en PageSpeed Tools de 95.




Errores actuales no solucionados

  • Especificar caché del navegador
    Son archivos externos como las llamadas a  google analytics.
  • Reducir el tiempo de respuesta del servidor
    Es lo que tiene tenerlo en un hosting comparido...

Típicos erroes fácilmente solucionables

Muchos ya nos hemos estado "picando" anteriormente con esta tool para mejorar esa puntación, yo particularmente siempre solucionaba estos puntos ya que es bastante sencillo hacerlo

  • Habilitar compresión Mostrar cómo corregirlo
  • Especificar caché de navegador
  • Optimizar imágenes 
  • Minificar CSS y JavaScript

De estos warnings no voy a hablar, ya que cómo he dicho son bastante sencillos de solventar, en este post quería compartir el cómo he solucionado los dos puntos que para mi han sido, y son, los más difíciles.

  • Quitar el JavaScript que bloquea la visualización de contenido
    No se ha podido visualizar el contenido de la mitad superior de la página sin tener que esperar a que se cargara alguno de los recursos. Intenta aplazar o cargar de forma asíncrona los recursos que bloquean la visualización, o bien inserta porciones críticas de dichos recursos directamente en el HTML.

    Esta regla se activa cuando PageSpeed Insights detecta que el código HTML hce referencia a algún archivo JavaScript externo que bloquea la visualización de contenido en la mitad superior de la página.

  • Optimizar la entrega de CSS
    Los navegadores bloquean los archivos CSS externos antes de que apliquen formatos al contenido de la pantalla. Esto conlleva latencia de red adicional y aumenta el tiempo de carga del contenido.

    Ten en cuenta que, si el archivo CSS es grande, al insertar todo el código CSS, es posible que PageSpeed Insights advierta a través de Prioriza el contenido visible que la mitad superior de la página es demasiado extensa


No voy a entrar al detalle de estos mensajes, primero porque no tengo el conocimiento suficiente para explicar cómo se renderiza el DOM en el navegador, algo he investigado... al final la cosa va de matrices, por quí podéis empezar para quién queira invesztigar. El método que he usado es bastante simple, funciona y parece ser,  si hacemos caso a  PageSpeed Insights, que para SEO es totalmente válido.

 

 

 ACTUALIZACIÓN (18 de octuibre del 2017

En Safari no se veía correctamente así que he actualizado el códgo para solventarlo

 

 

El problema con las llamadas a hojas de estilos y ficheros js

Si tienes así el código, usando las clásicas llamdas a hojas de estilos y ficheros javascript, lo más probable es que Pagespeed te alerte de elementos que pueden bloquear la carga de contenido de la parte superior.


		<html>
	< head>
	< link href="https://www.mecagoenlos.com/Posicionamiento/assets/corporate/css/style.css" rel="stylesheet">
	< script async src="https://www.mecagoenlos.com/includes/scripts.min.js" type="text/javascript">
	< /head>
	<body></body>
	< /html>
	

¿Cómo solucionar la carga de ficheros css?

Ahora vamos con la magia, fácil, sencillo y para toda la familia. No está siendo tan ffácil para Safari

  • El código JavaScript que necesariamente debamos cargarr antes del <body>
    Para cargarlo adecuadamente podemos meterlo como un código en línea, he de probar a ver si soy capaz de cargarlo via jQuery una vez el documento esté listo.

    		<script> 
    	var script = document.createElement("script");
    	script.async = false;
    	script.src = 'https://www.mecagoenlos.com/jquery-3.2.1.min.js';
    	document.head.appendChild(script);

    //función para cargar después los ficheros de hoja de estilo .css!
    function
    (e){"use strict" var n=function(n,t,o){function i(e){return f.body?e():void setTimeout(function(){i(e)})}var d,r,a,l,f=e.document,s=f.createElement("link"),u=o||"all" return t?d=t:(r=(f.body||f.getElementsByTagName("head")[0]).childNodes,d=r[r.length-1]),a=f.styleSheets,s.rel="stylesheet",s.href=n,s.media="only x",i(function(){d.parentNode.insertBefore(s,t?d:d.nextSibling)}),l=function(e){for(var n=s.href,t=a.length;t--;)if(a[t].href===n)return e() setTimeout(function(){l(e)})},s.addEventListener&&s.addEventListener("load",function(){this.media=u}),s.onloadcssdefined=l,l(function(){s.media!==u&&(s.media=u)}),s} "undefined"!=typeof exports?exports.loadCSS=n:e.loadCSS=n}("undefined"!=typeof global?global:this)
    </script>

 

  • La llamadas a los ficheros  de estilos prioritarios

    Los cargamos mediante la función antes creada, en mo caso estos son los que me provocan el bloquei según PageSpeed.

    		<script>
    	loadCSS("/Posicionamiento/assets/corporate/css/style-responsive.css");
    	loadCSS("/Posicionamiento/assets/corporate/css/style.css");
    	loadCSS("/Posicionamiento/assets/plugins/font-awesome/css/font-awesome.min.css");
    </script>


    No sé por qué, pero si cargo todos de esta forma me salta el bloqueo de contenido en PageSpeed, a veces sí y otras no.
  • Llamadas a hojas de estilo no prioritarias

    El puntoo clave aquí es el onload="this.rel='stylesheet'", un truco muy avispado, que consigue  que el navegador no tome esto como una hoja de estilos hasta que el contenido se cargue comlpetamente, de esta manera no bloquea la carga del contenido.

    		<!-- Theme styles END -->
    	<link async  href="https://www.mecagoenlos.com/Posicionamiento/assets/plugins/bootstrap/css/bootstrap.min.css" rel="preload" as="style" onload="this.rel='stylesheets'">
    	<noscript><link rel="stylesheet" href="https://www.mecagoenlos.com/Posicionamiento/assets/plugins/bootstrap/css/bootstrap.min.css" rel="preload" as="style" onload="this.rel='stylesheets'"></noscript>
    	<!-- Theme styles END -->
    	<link  async  href="https://www.mecagoenlos.com/Posicionamiento/assets/corporate/css/custom.min.css"   rel="preload" as="style" onload="this.rel='stylesheets'">
    	<noscript><link rel="stylesheet" href="https://www.mecagoenlos.com/Posicionamiento/assets/corporate/css/custom.min.css"></noscript>
    	<link  async  href="https://www.mecagoenlos.com/Posicionamiento/assets/pages/css/components.css"   rel="preload" as="style" onload="this.rel='stylesheets'">
    	<noscript><link rel="stylesheet" href="https://www.mecagoenlos.com/Posicionamiento/assets/pages/css/components.css"></noscript>
    	


    Aquí es dónde he tenido el mayor problema con el navegador Safari, y NO he dado de solventarlo mediante CSS y JavaScript, ¿entonces cómo lo he hecho?  pues a lo puky...

    Cómo no he sido capaz de hacer que se vea bien en Safari, y a la vez  que  PageSpeed no me alerte de que se está bloqueando el contenido, al final he decidio añadir el código conflictivo, en color azu,l que se añado solo a las hojas de estilos, cuándo  el User Agent no sea Safari.

    		  async  rel="preload" as="style" onload="this.rel='stylesheets'
    	

    Esta comprobación dell User Agent del usuario la chago coni php, ya que tenñia la función ya hecha, pero seguro que se puede haer correctamente usando sollo JavaScript,y una correcta y ordenada carga de las hojas de estilo. De momento  yo lo he hecho al estilo punky,


    Cuando detectamos que es Safari hacemos una llamada normal a las hojas de estilo. Supongo que se podría hacer usando el mismo método (comprobando user agent) pero desde JavaScript, y así no mezclarr código en el lado del servidorr, cuándo tenga tiempo lo volveré a probar y a ver si lop consigo.

  • Llamadas a ficheros js

    Hemos visto al principio cómo lo cargábamos, en ese caso lo he puesto encima del <body> porque me daba falos de  jQuery , y para que no se rompiera todo la introduzco sasí.

    		<script type="text/javascript">
    	function downloadJSAtOnload() {
    	var element = document.createElement("script");
    	element.src = "https://www.mecagoenlos.com/Posicionamiento/assets/plugins/bootstrap/js/bootstrap.min.js";
    	document.body.appendChild(element);
    	var element = document.createElement("script");
    	element.src = "https://www.mecagoenlos.com/Posicionamiento/assets/corporate/scripts/back-to-top.js";
    	document.body.appendChild(element);
    	var element = document.createElement("script");
    	element.src = "https://www.mecagoenlos.com/Posicionamiento/assets/plugins/jquery-migrate.min.js";
    	document.body.appendChild(element);
    	var element = document.createElement("script");
    	element.src = "https://www.mecagoenlos.com/Posicionamiento/assets/plugins/fancybox/source/jquery.fancybox.pack.js";
    	document.body.appendChild(element);
    	var element = document.createElement("script");
    	element.src = "https://www.mecagoenlos.com/Posicionamiento/assets/corporate/scripts/layout.js";
    	document.body.appendChild(element);
    	var element = document.createElement("script");
    	element.src = "https://www.mecagoenlos.com/includes/scripts.min.js";
    	document.body.appendChild(element);
    	}
    	if (window.addEventListener)
    	window.addEventListener("load", downloadJSAtOnload, false);
    	else if (window.attachEvent)
    	window.attachEvent("onload", downloadJSAtOnload);
    	else window.onload = downloadJSAtOnload;
    	
    </script>

     

Cómo podéis verr hago un excesivo uso de ficheros externos entre .js y hjas de estilos, Seguramoente me sobran la mitad y cómo sigo haciendo cambiios para  ver las distintas maneras de hacerlo  ahora me toca poner  orden y corregir algún fallo que mde da a veces

OSEGUIRÉ ACTUALIZANDO!

¿Algún otro métiodo sencillo?

 

 


Luis Salazar Jurado (@)hace Hace más de 7 años y 40 días

Lo he implementado y va como la seda

Espero la actualización que has comentado en Twitter para ver el Javascript, pero solo con el CSS ya vuela el site.

Gracias

Errioxa (@)hace Hace más de 7 años y 40 días

@Luis actualizado!

Si te da algún problema avisa!

Juan M. (@)hace Hace más de 7 años y 39 días

Para mí, esa forma de cargar los estilos donde todo se ve sin estilo y los carga a los segundos me da una muy mala sensación del site. Tanto como que me tira para atrás. Da una muy mala sensación. Por lo tanto no es una opción válida.

Tomás (@)hace Hace más de 7 años y 39 días

Hola Lino. En WordPress, ¿de qué manera se podría editar una línea de código CSS y JS para añadir las modificaciones en verde que mencionas? En el archivo header.php solo muestra la linea

Tomás (@)hace Hace más de 7 años y 39 días

...la línea ---?php wp_head()---

Gracias.

Luis Salazar Jurado (@)hace Hace más de 7 años y 39 días

Gracias Lino por avisar.

Solo he aplicado las mejoras de CSS y va como un tiro.

Debido a que la web en la que lo he implementado cargo el Javascript en el Footer, y además tiene poco, no he implementado la parte de Javascript.

Gracias

Luis Salazar Jurado (@)hace Hace más de 7 años y 37 días

Buenas Lino

He hecho un test en mi site: www.seotecnico.com y tras hacer test en Iphone, Chrome y Firefow parece que funciona

Sería añadir estas líneas y ajustar el valor c=a.setInterval(b.poly,300) para determinar el tiempo en cargar el CSS

--




/*! loadCSS. [c]2017 Filament Group, Inc. MIT License */
!function(a){"use strict";var b=function(b,c,d){function e(a){return h.body?a():void setTimeout(function(){e(a)})}function f(){i.addEventListener&&i.removeEventListener("load",f),i.media=d||"all"}var g,h=a.document,i=h.createElement("link");if(c)g=c;else{var j=(h.body||h.getElementsByTagName("head")[0]).childNodes;g=j[j.length-1]}var k=h.styleSheets;i.rel="stylesheet",i.href=b,i.media="only x",e(function(){g.parentNode.insertBefore(i,c?g:g.nextSibling)});var l=function(a){for(var b=i.href,c=k.length;c--;)if(k[c].href===b)return a();setTimeout(function(){l(a)})};return i.addEventListener&&i.addEventListener("load",f),i.onloadcssdefined=l,l(f),i};"undefined"!=typeof exports?exports.loadCSS=b:a.loadCSS=b}("undefined"!=typeof global?global:this);
/*! loadCSS rel=preload polyfill. [c]2017 Filament Group, Inc. MIT License */
!function(a){if(a.loadCSS){var b=loadCSS.relpreload={};if(b.support=function(){try{return a.document.createElement("link").relList.supports("preload")}catch(b){return!1}},b.poly=function(){for(var b=a.document.getElementsByTagName("link"),c=0;c

Juan M. (@)hace Hace más de 7 años y 25 días

¿Esto lo has probado en Safari o Firefox? No pilla bien el preload para css

pSeo (@)hace Hace más de 6 años y 364 días

va como un tiro con el onready!!!

Francisco (@)hace Hace más de 5 años y 149 días

Flaco. Por lo general, no dejo comentarios pero, en tu caso, voy a hacer una excepción pues, sencillamente... ¡sos un genio!, Gracias.

Literalmente estuve TODA la noche buscando como resolver lo de ..."Elimina los recursos que bloqueen el renderizado".. de 3 "fucking" archivos que, no encontraba la manera de sacarlos y, con tu código... ¡lo logré!

De nuevo, gracias.

Saludos!

Profe Ray (@proferay)hace Hace más de 1 años y 321 días

Veo que hay comentarios de hace 5 años y de hace 3 años. ¿Habrá algun post actualizado sobre este tema o sigue funcionando? Lo cierto es que aún no he tenido el tiempo de probarlo pero he buscado por varios lugares sobre este tema y encuentro "mucho ruido y pocas nueces" hasta que dí con este post que parece bastante cercano a mi problema. Pero no quería echar mano al asunto por si esto resulta que está obsoleto o que existe alguna solución más actual. Desde ya gracias y siguiendo en Twitter y por el blog también. Abrazo!


Últimos posts

Últimos comentarios


Dana

Post: Experimento para comprobar la teoría del primer enlace

JaviLazaro
Ya me has dado la necesidad de crear un comaando en bash para hacer estas cosas. Gracias Lino por estos tips
Post: Obtener KWs de varias fuentes usando la línea de comandos

Señor Muñoz
Lino, el 11% más de clicks y el 47% más de impresiones diarias ¿es algo constante o depende de cada sitio web?
Post: Diferencias entre la exportación de datos de Search Console usando BigQuery o usando la API

Carlos
Hola En mi blog tengo artículos atemporales (es decir, no caducan nunca, de manera que sirve para quien lo lea hoy o lo lea dentro de 5
Post: Tratamiento de urls que tienen un tiempo de vida muy corto

Profe Ray
Veo que hay comentarios de hace 5 años y de hace 3 años. ¿Habrá algun post actualizado sobre este tema o sigue funcionando? Lo cierto es
Post: Cómo cargar css y js y no bloquear la carga de contenido

Pepe
Muchas gracias por el articulo!! Muy buena información.
Post: Qué es ofuscar enlaces y cómo mejora el enlazado interno

María
Sí, he buscado el archivo robots.txt y todo está correcto. La última versión vista con error fue el 08/11/2021 y la última vez que el
Post: Errores críticos originados por el robots.txt

Lino
@María un placer verte por aquí :) Lo primero, a veces, con el robots.txt no se puede "forzar" a que lo rastree, si tu site no es muy p
Post: Errores críticos originados por el robots.txt

María
Hola Lino, tengo el mismo problema. El probador de robots de google me indica: "Error al obtener el archivo robots.txt Tienes un archivo ro
Post: Errores críticos originados por el robots.txt

Mario
Estoy tratando de vincular los datos en Google Data Studio y he combinado los datos de la tabla "Impresión del sitio" con "Impresión de UR
Post: Datos incoherentes y cálculo de la posición media en Search Console