Analizando y optimizando la velocidad de nuestro sitio web con PhantomJS

Con PhantomJS y sus scripts, analizaremos y optimizaremos la velocidad de nuestro sitio web en muy poco tiempo.

PhantomJS (GitHub) es una implementación del motor WebKit scriptable con JavaScript que nos permite ejecutar nuestros propios scripts directamente sobre WebKit. Gracias a ello, PhantomJS es capaz de entender el DOM, CSS, JavaScript, Canvas y SVG con el beneficio de que no es un navegador web. Al ejecutarse mediante línea de comandos en Linux, Windows y Mac OS X, podremos ejecutar tareas como realizar capturas de pantalla y exportarlas a imagen, realizar tests unitarios automáticamente o analizar el rendimiento de nuestro sitio web cómodamente.

Análisis de rendimiento

En este caso vamos a hablar de la última de las opciones: analizar el rendimiento de nuestro sitio web.

Empezaremos instalando PhantomJS, en el caso de Windows podemos utilizar la versión binaria que se distribuye desde el sitio web oficial, pero si utilizáis Linux seguramente vuestra distribución incluya PhantomJS en su gestor de paquetes (apt-get, yum, emerge, etc). También se proporcionan unos scripts de ejemplo en la carpeta examples.

LoadSpeed

Un script de ejemplo es el llamado loadspeed.js, que como bien indica su nombre, nos devolverá únicamente el tiempo de carga de una página:

phantomjs loadspeed.js https://felixsanz.com
Page title is felixsanz
Loading time 940 msec

Netsniff

El script netsniff.js es capaz de analizar una página web y exportar los resultados en formato HAR:

phantomjs netsniff.js https://felixsanz.com > webdata.har

El formato HAR es un fichero JSON con toda la información necesaria para generar la "network waterfall". El fichero HAR también se puede generar desde Google Chrome a través de las herramientas para desarrolladores. Más información en la especificación HAR 1.2.

Después podemos utilizar Har Viewer o ChromeHAR para ver nuestros resultados. Arrastramos el fichero HAR y los datos se importarán, dándonos resultados más fáciles de leer por los humanos. Esto incluye datos como las cabeceras y el tamaño de cada fichero que utiliza la página web, el tiempo total de carga y gráficos sobre el impacto de los recursos en el tiempo de carga.

Lectura de fichero HAR con HAR Viewer
Lectura de fichero HAR con HAR Viewer

Yslow

Hoy por hoy Yslow para PhantomJS está prácticamente abandonado y no funciona, pero con un simple cambio podemos volver a tenerlo funcionando.

Yslow no sólo nos ofrecerá datos si no también una puntuación y consejos para optimizar nuestra página web. El script de Yslow para PhantomJS se puede descargar aquí. Mediante el siguiente comando, obtendremos un resumen de los datos:

phantomjs yslow.js --info basic --format plain https://felixsanz.com
version: 3.1.8
size: 98.8K (98856 bytes)
overall score: B (88)
url: https://felixsanz.com/
# of requests: 16
ruleset: ydefault
page load time: 1120

Podemos ir más allá de un simple test y obtener información de porqué obtenemos una puntuación de 81/100, mediante el siguiente comando:

phantomjs yslow.js --info grade --format tap https://felixsanz.com
TAP version 13
1..24
ok 1 B (88) overall score
ok 2 A (96) ynumreq: Make fewer HTTP requests
  ---
  message: This page has 3 external stylesheets.  Try combining them into one.
  ...
not ok 3 E (50) ycdn: Use a Content Delivery Network (CDN)
  ---
  message: There are 5 static components that are not on CDN. <p>You can specify CDN hostnames in your preferences. See <a href="https://github.com/marcelduran/yslow/wiki/FAQ#wiki-faq_cdn">YSlow FAQ</a> for details.</p>
  offenders:
    - "felixsanz.com: 2 components, 63.4K (20.7K GZip)"
    - "fonts.googleapis.com: 2 components, 1.0K (1.0K GZip)"
    - "www.gravatar.com: 1 component, 18.7K"
  ...
ok 4 A (100) yemptysrc: Avoid empty src or href
not ok 5 F (0) yexpires: Add Expires headers
  ---
  message: There are 11 static components without a far-future expiration date.
  offenders:
    - "https://felixsanz.com/css/styles.min.css"
    - "https://fonts.googleapis.com/css?family=Titillium+Web:200,400"
    - "https://fonts.googleapis.com/css?family=Open+Sans:400,600"
    - "https://www.google-analytics.com/analytics.js"
    - "https://felixsanz.com/assets/img/logo.png"
    - "https://www.gravatar.com/avatar/ab87d702e38bc0622fc37839aa7cdad9?s=96"
    - "https://felixsanz.com/favicon-16x16.png"
    - "https://felixsanz.com/favicon-32x32.png"
    - "https://felixsanz.com/favicon-96x96.png"
    - "https://felixsanz.com/favicon-194x194.png"
    - "https://felixsanz.com/android-chrome-192x192.png"
  ...
ok 6 A (100) ycompress: Compress components with gzip
ok 7 A (100) ycsstop: Put CSS at top
ok 8 A (100) yjsbottom: Put JavaScript at bottom
ok 9 A (100) yexpressions: Avoid CSS expressions
ok 10 N/A (-1) yexternal: Make JavaScript and CSS external # SKIP score N/A
  ---
  message: Only consider this if your property is a common user home page.
  offenders:
    - "There is a total of 2 inline scripts"
  ...
ok 11 A (95) ydns: Reduce DNS lookups
  ---
  message: The components are split over more than 4 domains
  offenders:
    - "felixsanz.com: 8 components, 81.8K (31.0K GZip)"
    - "fonts.googleapis.com: 2 components, 1.0K (1.0K GZip)"
    - "fonts.gstatic.com: 4 components, 124.9K (92.0K GZip)"
    - "www.google-analytics.com: 1 component, 27.5K (15.0K GZip)"
    - "www.gravatar.com: 1 component, 18.7K"
  ...
ok 12 A (100) yminify: Minify JavaScript and CSS
ok 13 A (100) yredirects: Avoid URL redirects
ok 14 A (100) ydupes: Remove duplicate JavaScript and CSS
ok 15 A (100) yetags: Configure entity tags (ETags)
ok 16 A (100) yxhr: Make AJAX cacheable
ok 17 A (100) yxhrmethod: Use GET for AJAX requests
ok 18 A (100) ymindom: Reduce the number of DOM elements
ok 19 A (100) yno404: Avoid HTTP 404 (Not Found) error
ok 20 A (100) ymincookie: Reduce cookie size
ok 21 A (100) ycookiefree: Use cookie-free domains
ok 22 A (100) ynofilter: Avoid AlphaImageLoader filter
ok 23 A (100) yimgnoscale: Do not scale images in HTML
ok 24 A (95) yfavicon: Make favicon small and cacheable
  ---
  message: Favicon is not cacheable
  ...

Si el test dio "not ok", se ofrece un mensaje y los culpables. Message indica el problema en cuestión y offenders se refiere a los recursos que son afectados por el mensaje. En nuestro caso los errores se encuentran en los siguientes mensajes:

ycdn: Use a Content Delivery Network (CDN)
yexpires: Add Expires headers

En este caso no podemos hacer nada, ya que nuestra lista de errores son culpa de Google Analytics, los botones y cajas sociales, etc. Pero por supuesto esto es un valioso recurso que os invito a probar para optimizar un sitio web, algo que nosotros ya hicimos de la mejor forma que pudimos (¡queremos un 100/100!).

Resumen

Hay otros recursos compatibles con PhantomJS para monitorizar y optimizar la velocidad de nuestro sitio web, por ejemplo: sitespeed.io (GitHub) o basset. Esto sólo ha sido una breve introducción de las posibilidades que ofrece PhantomJS en este tipo de acciones y esperamos que os haya gustado.

Compartir en

Facebook Twitter Google+ LinkedIn