1 jul 2014

Cómo mejorar el rendimiento de tu sitio web con Google Pagespeed Insights.

Pagespeed Insights es un servicio de Google que permite analizar el código fuente de una página web para determinar su rendimiento y ofrecer sugerencias para mejorarlo.

A parte del análisis orientado al rendimiento también proporciona una evaluación de la experiencia de usuario para dispositivos móviles, con lo cual es capaz de proporcionar una buena visión general de algunos de los aspectos que conforman la calidad de una página.

Vamos a realizar un pequeño resumen de los cambios que plantea la herramienta para cualquier web.




Cómo funciona Google Pagespeed Insights:


Pagespeed dispone tanto de de una herramienta online en Google Developers como de una extensión de Chrome para probar directamente en el navegador.

La herramienta online te aporta directamente las sugerencias de mejora de rendimiento apropiadas pero la extensión de Chrome además te ofrece los archivos o problemas detectados directamente optimizados para que después los cargues en tu web.

En general el funcionamiento es simple, conéctate a la página del servicio ofrecido por Google Developers pulsando aquí. Te aparecerá una pantalla donde introducir la dirección de tu sitio web o de una página del mismo y pulsar el botón azul de la derecha donde pone "Analizar".

A la finalización podrás ver los resultados con las diferentes sugerencias para mejorar el rendimiento de tu sitio web.

Cómo solucionar punto por punto:



1) Evita los redireccionamientos a páginas destino. 



 Qué quiere decir esta sugerencia:
  • Se trata de no realizar redirecciones incorrectamente en tu sitio web, esto es: no enviar al navegador desde una dirección web (URL) a otra al acceder a un sitio web. 
  • Si redireccionas desde la página principal de una dirección a otra, se producirá un retraso en el tiempo de ejecución mientras se resuelve el paso de una dirección a otra. 
Qué soluciones se pueden implementar
  • La redirección de un sitio web a otro puede conllevar problemas de duplicidad de información que debes resolver siempre con rel=canonical (para indicar cuál es la URL preferida con la que vas a trabajar).
  • Si no tienes más remedio que realizar alguna redireccón, es conveniente que actualices tu .htaccess (siempre que tengas acceso) para no acometer las mismas por medio de código. Este artículo de Internet Marketing Ninjas te ayudará a hacerlo:

2) Eliminar el JavaScript que bloquea la visualización y el CSS del contenido de la mitad superior de la página. 

Qué quiere decir esta sugerencia:
Bloqueo de visualización por CSS:
  • Todas las páginas utilizan CSS para controlar los aspectos sobre la presentación de un sitio web. Las hojas de estilo deben encontrarse en la zona <head> de un documento HTML. El acceso a las mismas es síncrono, hasta que no se descargan no pueden comenzarse a aplicar los estilos a la página. 
Si accedes a tus css esta manera :
<link href="/resources/css/general.css" rel="stylesheet" type="text/css"> 
  • El navegador se verá obligado a descargar el archivo .css del servidor donde se encuentre para luego interpretarlo y posteriormente aplicarlo a las etiquetas de tu HTML que lo estén utilizando. Durante todo el proceso anteriormente indicado se producirá un retardo en el dibujado de la página que afectará al rendimiento del sitio web mientras esta no esté almacenada en la memoria caché del navegador.
Qué soluciones se pueden implementar para evitar el bloqueo por CSS:
Veamos soluciones prácticas a los problemas de bloqueo en CSS y JS.
Solucionar el problema de bloqueo por CSS:
Siempre que tengas una llamada 
<link href="/resources/css/TU_CSS.css" rel="stylesheet" type="text/css"> 
Puedes minimizar el contenido de dicho .css  y a continuación ponerlo "inline" en la página HTML para que no sea necesaria su descarga:
<style type="text/css">
el contenido de TU_CSS.css
</style>
Evitarás la descarga del archivo .css de un servidor externo o de tu propio servidor porque éste se encontrará directamente integrado en el <head> de tu documento HTML, consiguiendo evitar retardos en el dibujado de la página y potenciando el rendimiento de la misma.

Bloqueo de visualización por JS:
Qué quiere decir esta sugerencia: 
  • Los Javascripts o secuencias de comandos que se utilizan para añadir funcionalidades que requieren cálculo o precálculo de información a una página (carga de botones para redes sociales con contadores, dibujado de sliders o carruseles de imágenes, etc...) pueden producir importantes retardos en el primer dibujado de una página en el navegador de nuestros usuarios.
  • Los scripts requieren un tiempo para realizar sus cálculos y toma de datos que posteriormente servirán para mostrar la página. Si además el javascript en cuestión está encapsulado en un archivo .js externo, el navegador tendrá que descargarlo, interpretarlo y después aplicarlo al documento HTML sobre el que debe aplicarse.
¿Cómo se trabaja normalmente con los Javascript en una página? 
Hay cuatro maneras de utilizar el javascript en una página que incluso pueden combinarse según las necesidades:  
1) Javascript Síncrono (Sychronous Javascript):  
Es el modo de acceso más lento. Se le llama "síncrono" porque el navegador no continuará con el dibujado de la página hasta que finalice con la descarga e interpretación del archivo .js que se referencia. Durante el proceso de descarga e interpretación se produce un retardo en el dibujado de la página que puede afectar al rendimiento de la misma.  
El Javascript se referencia encapsulado dentro de un archivo con extensión .js de esta manera:
<script src="/resources/js/Ejemplo.js" type="text/javascript" ></script>
Aunque los navegadores actuales han perfeccionado el uso del Javascript y se han vuelto extremadamente eficientes a la hora de impedir el bloqueo por el mismo, es absolutamente cierto que en la primera descarga y hasta que el archivo .js se encuentra en el puesto local del usuario, el tiempo que se pierde es excesivo. 
Suele agravarse el problema más aún cuando la declaración de uttilización síncrona del archivo .js se realiza en el <head> del documento HTML, ya que impide que se llegue hasta el <body> de la página hasta que el .js no ha sido descargado e interpretado.
2) Javascript Diferido (Deferred Javascript): 
Un modo de acceso al Javascript externo almacenado en un archivo .js que pospone la descarga e interpretación del Javascript al momento en que el documento HTML ha sido cargado y mostrado.
Un ejemplo de carga diferida de javascript sería el proporcionado por la página Feedthebot:
<script type="text/javascript">
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "defer.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>
En este caso el archivo .js, al igual que sucede con el modo síncrono, debe ser descargado e interpretado pero la página "no tiene que esperar" a que el javascript se haya ejecutado. Bajo la mayor parte de circunstancias esta manera de ejecutar el código pospone su ejecución al final de la página. 
Este tipo de llamadas a archivos .js externos se debe colocar antes del </body> y es ideal para no sobrecargar el <head> con declaraciones síncronas. Es una buena forma de evitar el bloqueo por la utilización de .js al principio del documento HTML y para optimizar en general el rendimiento de la página.
3) Javascript Asíncrono (Asychronous Javascript): 
también conocido como Async. El método de ejecución asíncrono de Javascript mezcla lo mejor del modo síncrono y el diferido. Cuando ejecutamos un archivo externo en modo asíncrono permitimos que la página se dibuje a la vez que se va procesando y descargando el .js en cuestión. De esta manera en lugar de que la página tenga que esperar a su dibujado por el .js a principio de página o en diferido, después de que ésta se haya dibujado, podrá ejecutar en paralelo el procesamiento del javascript y el procesamiento de la página.
Un ejemplo de llamada asíncrona de Javascript es la utilización de Google Analytics:
<script type="text/javascript">
  var _gaq = _gaq || [];  _gaq.push(['_setAccount', 'UA-XXXXX-X']);  _gaq.push(['_trackPageview']);

  (function() {    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);  })();    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);  })(); 
</script>
Esta manera de cargar el javascript en la página eleva considereablemente el rendimiento de la misma por no supeditar su dibujado a la ejecución del script.
Es ideal para cargar archivos que son necesarios globalmente en la página <head> y debe sustituir siempre que sea posible a la carga síncrona de Javascript.
4) Javascript Inline: la utilización inline de un archivo .js consiste en extraer directamente el contenido del archivo en cuestión y ponerlo directamente en el documento HTML. 
Un ejemplo de inline sería:
<script type="text/javascript">
document.getElementById("demo").innerHTML = "Hola!";
</script>
La ventaja del javascript inline es que al ir directamente en la página no requiere que un archivo externo .js deba ser descargado para poderse interpretar. Cuando el navegador procesa el documento HTML además procesa directamente sin descarga el javascript "inline".
La gran desventaja es que si el contenido de un javascript es excesivamente extenso (por ejemplo, una librería jquery completa), el incremento de código en página es literalmente enorme. Esto hace que le cueste más al navegador la descarga del documento HTML debido a su gran tamaño y además, dependiendo de su localización, podría afectar al rendimiento en el dibujado de la página. Por ejemplo, si se coloca en el <head>, se incurre en la lectura de gran cantidad de código innecesario que impide que se continúe con el dibujado del resto de la página.
Su utilización está indicada siempre que la cantidad de código del archivo .js sea pequeña.
Qué soluciones se pueden implementar para evitar el bloqueo por Javascript:
Solucionar el problema de bloqueo por Javascript:
En primer lugar, analiza el uso de javascript en tu página, cómo vas llamando a cada función y porqué.
En términos generales:
  • Evita las llamadas de javascript síncrono siempre. No declares el javascript de esta manera en el <head>. Debes dejar la cabecera del documento HTML lo más libre posible de javascript y en caso de no tener más remedio que ejecutarlo (por tener un .js que te obligue a hacerlo en sus recomendaciones) SIEMPRE debes utilizar la versión ASÍNCRONA del mismo.
  • Si utilizas el código asíncrono te aseguras de que el dibujado de la página corra en paralelo a la descarga e interpretación del javascript. El problema es que al ser asíncrono, no podrás nunca llegar a saber con total exactitud cuándo se va a ejecutar y si tienes algún javascript que dependa del que cragaste asíncronamente, puede no funcionar por no encontrarse disponible en el momento de ejecución el javascript cargado en modo asíncrono.
  • Las llamadas asíncronas se pueden "diferir" si se controla su carga gestionando el evento window.onload o similares, en el momento en que se vaya a ejecutar algún javascript dependiente, pero en estos casos es mejor utilizar javascript en modo diferido.
  • El modo diferido, utilizando javascript inline o realizando la carga del .js en diferido es ideal en casi todas las situaciones. Pospone la ejecución del javascript sin necesidad de impedir el dibujado de la página.
Situaciones particulares:
  • Todo el código .js que pertenezca a un plugin de cualquier clase (por ejemplo redes sociales) debe ser ejecutado siempre en modo asíncrono. Especialmente cuando es un script cuyas especificaciones del fabricante recomienden instalarlo en el <head> o al principio del <body>.
  • La combinación de la utlización de javascripts asíncronos sin dependencias posteriores en el <head> y javascript diferido al final del documento HTML, antes del </BODY> es una combinación que en general ofrece las mejores perspectivas de rendimiento.
  • El javascript inline es ideal para scripts pequeños pero es preferible no utilizarlo nunca con grandes archivos .js para no saturar la cantidad de código de la página. Así mismo, es preferible siempre que el código inline esté lo más cercano al /body que el diseño del documento HTML te permita.
Ejemplos prácticos:
Llamada Diferida con jQuery:
Pongamos una página HTML estándar independiente de la plataforma donde se ejecute, en ella pondremos un script de Google analytics y la carga de diversos códigos que pueden funcionar con jQuery (Debido a la extensión del ejemplo, te lo dejo en el botón "ver ejemplo" si deseas visualizarlo al completo)

<html>
<head>

<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-XXXXXXXX-X', 'auto');
  ga('send', 'pageview');

</script> <!-- LLAMADA ASÍNCRONA EN HEAD A SCRIPT DE GOOGLE ANALYTICS -->

</head>
    <body>
        <!-- TODO TU CÓDIGO DEL BODY hasta antes del </BODY> -->

        <script>  <!-- ANTES del </BODY> en diferido -->

var dfLoadStatus = 0;
var dfLoadFiles = [
    [
        "blabla..."
    ]
]; <!-- CARGA DE LAS LIBRERÍAS JQUERY A UTILIZAR -->

function downloadJSAtOnload() {
    if (!dfLoadFiles.length) return;

    var dfGroup = dfLoadFiles.shift();
    dfLoadStatus = 0;

    for (var i = 0; i < dfGroup.length; i++) {
        dfLoadStatus++;
        var element = document.createElement('script');
        element.src = dfGroup[i];
        element.onload = element.onreadystatechange = function () {
            if (!this.readyState || this.readyState === 'complete') {
                dfLoadStatus--;
                if (dfLoadStatus === 0) {
                    if (dfGroup.length === 1) { //if jquery was loaded, then load other js
                        downloadJSAtOnload();
                    } else { //all is already loaded, perform deffered actions
                        performDeferredActions();
                    }
                }
            }
        };
        document.body.appendChild(element);
    }
}

if (window.addEventListener) {
    window.addEventListener("load", downloadJSAtOnload, false);
} else if (window.attachEvent) {
    window.attachEvent("onload", downloadJSAtOnload);
} else {
    window.onload = downloadJSAtOnload;
}

function performDeferredActions() { <!-- VAS CARGANDO LOS .JS QUE NECESITAS EN TU WEB Y QUE REQUIEREN JQUERY-->

   $.ajax({
        type: "GET", 
        url: "http://CADA_JS.js", 
        dataType: "script", 
        cache: true /* or false if you don't want to cache it*/ 
    }); 

}

        </script>
    </body>
</html>


Llamada asíncrona de jQuery con código inline:
Esta es otra manera de optimizar las llamadas javascript a unos niveles de rendimiento importantes. La idea es lanzar en asíncrono la carga de jQuery y realizar las llamadas posteriores a las funciones dependientes una vez el documento HTML está listo. Esta forma de realizar llamadas te permite ejecutar en modo asíncrono una librería Javascript completa para después una vez se ha dibujado la página y sin perder tiempo en descargas de .js, se ejecuten funciones inline dependientes de la asíncrona.


<html><head>
<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
  ga('create', 'UA-XXXXXXXX-X', 'auto');
  ga('send', 'pageview');
</script> <!-- LLAMADA ASÍNCRONA EN HEAD A SCRIPT DE GOOGLE ANALYTICS -->
</head>
    <body>
        <!-- TODO TU CÓDIGO DEL BODY hasta antes del </BODY> -->
<script type='text/javascript'>  <!-- EJEMPLO DE CARGA ASÍNCRONA A JQUERY -->
(function(){
  var bsa = document.createElement('script');
     bsa.type = 'text/javascript';
     bsa.async = true;
     bsa.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js';
  (document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(bsa);
})();
</script>
      
<script>window.onload = function(){ <!-- CUANDO LA VENTANA ESTÁ CARGADA -->

<!-- LLAMADAS A jQuery CON LA LIBRERÍA YA CARGADA Y LISTA -->
jQuery(document).ready(function(e){e(".PRUEBA-1432447472-id").hide();e("ul.tabs-widget-widget-themater_tabs-1432447472-id li:first a").addClass("tabs-widget-current").show();e(".tabs-widget-content-widget-themater_tabs-1432447472-id:first").show();e("ul.tabs-widget-widget-themater_tabs-1432447472-id li a").click(function(){e("ul.tabs-widget-widget-themater_tabs-1432447472-id li a").removeClass("tabs-widget-current a");e(this).addClass("tabs-widget-current");e(".tabs-widget-content-widget-themater_tabs-1432447472-id").hide();var f=e(this).attr("href");e(f).fadeIn();return false})});
jQuery(document).ready(function(e){var f=function(){setTimeout(function(){e("ul.prueba-list li:first").animate({marginTop:"-50px"},800,function(){e(this).detach().appendTo("ul.ticker-list").removeAttr("style")});f()},5000)};f()});

}</script>

    </body>
</html>




Próxima actualización


Continuaremos con las siguientes normas de Pagespeed a tener en cuenta y contemplando los últimos cambios en las reglas de detección de la herramienta para mejorar el rendimiento absoluto de nuestro sitio web. Por supuesto, pregunta lo que necesites, los comentarios están abiertos para ti.


Escrito por Miguel García Sánchez - Colomer

Dispuesto a ayudarte con tu Blog en todo lo posible, Diarios de la nube es mi medio para llegar hasta ti. El conocimiento es universal, es del mundo, es de todos, esta es mi parte y la comparto contigo.

15comentarios:

  1. Respuestas
    1. Gracias Félix. Cualquier duda me cuentas, poco a poco iré actualizando la guía con nuevas optimizaciones para nuestras webs. Un saludo!!!

      Eliminar
  2. Sobre todo necesito algún consejo para mejorar el indicador "Prioriza el contenido visible". He hecho muchos esfuerzos y no pasó del 10% u 15%, incluso dejando todo en texto en la mitad superior de la página. Saludos.

    ResponderEliminar
    Respuestas
    1. Tengo pendiente ampliar la guía, no obstante, te comento cómo funciona.

      Debes intentar que no exista contenido que deba ser calculado antes de que la página se dibuje. Es decir img con size auto o tamaños no fijados desde antes del dubujado de la página hará que está regla se lance.

      Intenta que todo div, img o cualquier componente de tu HTML tenga los valores de dibujado prefijados y que no sean calculados vía javascript o por el navegador.

      Un saludo!!!

      Eliminar
  3. hola otra vez... he usado el programa ese para que anlice mi página y tanto en movil como versión web lo más preocupante es lo del bloqueo por CSS por el Javscript. Los conceptos los entiendo, pero como dices bien no me atrevo a meter mano en nada de eso. Tb dice k habilite la compresión... no se hay algo de esto que se pueda hacer de forma fácil? te recuerdo mi web www.suxana.es Por supuesto que te supercomparto, no tengo otra forma de agradecerte...

    ResponderEliminar
    Respuestas
    1. Hola Susana, es mucho más fácil de lo que parece. ¿Qué tecnología está utilizando para tu web?, si es Blogger prueba esto: http://www.diariosdelanube.com/2013/09/la-guia-de-rendimiento-para-bloggers_10.html es justo para esas advertencias sobre el javascript y el css.

      Cualquier duda pregunta lo que necesites.

      Un saludo!!!

      Eliminar
  4. Lo que sabe tu cuerpo, ¡madre mía! te leo y parece todo súper fácil, eres un crack!

    ResponderEliminar
  5. Hola, cual es la extension de Chrome que mencionas? no la pude encontrar, gracias.

    ResponderEliminar
    Respuestas
    1. Es que Google tenía una extensión instalable en Chrome de pagespeed:https://developers.google.com/speed/pagespeed/insights_extensions

      Pero la han "deprecado". Ahora sólo se usa la versión Online. Además han metido una mejora para la que haré una entrada en los próximos días, mediante la cual ya te dan ellos mismos para descarga automática los recursos de tu web optimizados (css, javascript, imágenes, etc...).

      Cualquier cosa aquí estoy.

      Un saludo!!!!

      Eliminar
  6. Brutal tu post, te felicito! eres todo un master!

    ResponderEliminar
  7. Tengo mi pagina con wordpress, he entendido los bloqueos de javascript y css, necesito tu guia para saber donde entro para hacer esos cambios porque no tengo idea, Gracias

    ResponderEliminar
    Respuestas
    1. Entra en el editor HTML del theme y debes hacer ahí los cambios. Haz pruebas antes en un blog de prueba y no toques el tuyo sin hacer copias de seguridad. WordPress mezcla php con HTML,ten en cuenta que construye código dinámicamente en tu theme.

      Haz pruebas y veré la posibilidad de hacer un tutorial para WordPress... lo malo que ando escasísimo de tiempo.

      Un saludo!

      Eliminar
  8. Hola Miguel,
    He probado el PageSpeedInsights y me sale que tengo varios redireccionamientos en blogspot. No se donde y como solucionarlo...
    Tu página tiene 3 redireccionamientos. Los redireccionamientos añaden retrasos adicionales antes de que la página se pueda cargar.
    Evitar redireccionamientos a la página de destino para esta cadena de URL redireccionadas.
    http://sergiopellico.blogspot.com.es/
    http://sergiopellico.blogspot.be/?m=1
    https://sergiopellico.blogspot.be/?m=1
    https://sergiopellico.blogspot.be/p/video-boda-madrid.html?m=1

    ResponderEliminar
  9. Hola Sergio!, feliz año.
    El redireccionamiento a "m=1" es para móviles, no es un redireccionamiento negativo, lo que sucede es que ralentiza el dibujado de la página porque Blogger pone un "decisor" para saber si el cliente que te visita está haciéndolo con un móvil o un ordenador, en caso de que lo haga con móvil, redireccionará a m=1.

    Ese redireccionamiento se evita haciendo una página "Responsive": http://www.diariosdelanube.com/2014/02/que-es-responsive-design.html

    Al utilizar diseño Reponsive, no es necesario activar en Blogger el redireccionamiento a páginas para móviles (m1)... por eso en mi web, por ejemplo, no existe ese redireccionamiento.

    No te preocupes mucho por ello, hoy día es preferible para el posicionamiento que tu web se vea bien en móviles con prioridad sobre que se ejecute más rápido. Si compras una plantilla "responsive" y luego la optimizas para Pagespeed, podrías conseguir evitar el redireccionamiento... pero todo eso es mucho trabajo.

    Lo tienes bien, tal cual lo tienes, no te preocupes.

    Un saludo.

    ResponderEliminar

 

© 2015 Por: Miguel García Sánchez - Colomer en Diarios de la nube Todos los derechos reservados.