Existen multitud de técnicas para mejorar el rendimiento de las páginas web y conseguir mejores tiempos de respuesta, aunque la mayor parte de estas mejoras se deben realizar en el servidor. Sin embargo existen algunas cosas que podemos hacer desde el propio código HTML, en el Front-End y sin la intervención del servidor, para mejorar la velocidad de carga de las páginas siguientes a la actual y que creo que no son muy conocidas por la comunidad de desarrolladores.
Imagina la siguiente situación: tienes una presentación basada en HTML en la que el usuario se va moviendo hacia adelante para ir visualizando una serie de recursos. Cada pulsación del botón "adelante" hace que se cargue un nuevo recurso. El caso típico es un carrusel de imágenes en el que, cada vez que pulsas en el botón de "adelante" se carga la siguiente imagen que haya en la lista. Si las imágenes son grandes, con mucha resolución, no están muy optimizadas o simplemente la conexión es lenta, es posible que tarden en cargar y por lo tanto no se visualicen correctamente durante unos instantes, o quizá se vayan cargando progresivamente de arriba a abajo, con un efecto muy feo. Seguro que lo has sufrido alguna vez.
HTML dispone de una característica muy interesante para casos así denominada Prefetch, o carga previa de recursos.
Esta carga previa sirve para situaciones como la descrita: cuando sabemos de antemano que es muy probable que el usuario vaya a necesitar uno o varios recursos (páginas, imágenes, fuentes, scripts...) justo a continuación de haber visitado la página actual, podemos avisar al navegador de este hecho y conseguir que los vaya pre-cargando para ahorrar tiempo.
Esto se consigue gracias a un valor especial para el atributo rel
de la etiqueta <link>
de HTML5.
Consideremos la siguiente página, de lo más sencilla:
<!doctype html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Prueba prefetch</title>
</head>
<body>
<p>Descarga en segundo plano de próximas páginas</p>
<p><a href="1.html">Página 1</a></p>
<p><a href="2.html">Página 2</a></p>
<link rel="prefetch" href="1.html" />
<link rel="prefetch" href="2.html" />
<link rel="prefetch" href="3.html" />
</body>
</html>
Como vemos es un simple texto con dos enlaces a las páginas siguientes, 1.html
y 2.html
.
Lo interesante son las tres etiquetas <link>
que hemos colocado a continuación (que podríamos haber colocado en otro lado también). Éstas lo que consiguen es que el navegador, al verlas, descargue automáticamente en segundo plano los recursos que le indiquemos. En este caso son 3 páginas HTML, pero podr��an haber sido imágenes, scripts, o cualquier otra cosa.
Podemos comprobar que, efectivamente, se están descargando mirando el tráfico que se genera al visitar la página de prueba. Por ejemplo con Fiddler:
Como vemos, el navegador carga la página y de manera inmediata comienza con la descarga en segundo plano de los recursos que le hemos indicado. En este caso además el tercero de ellos (3.html) no existe y obtiene un error 404. Lo he hecho a propósito para mostrar que no pasa absolutamente nada y ese error no trasciende hacia la página. Simplemente el navegador hace caso omiso de ese recurso porque no puede obtenerlo.
Nota: es importante señalar que aunque aquí digo "de manera inmediata", en realidad no es exactamente así. El navegador usa "tiempo ocioso" (en inglés, "idle time") en el que no esté especialmente ocupado renderizando o ejecutando scripts, para recuperar esos archivos. Así que no es predecible cuándo lo va a hacer, pero en páginas sencillas los descargará inmediatamente. Si durante el proceso de precarga pulsamos un enlace para cambiar de página o lanzamos alguna descarga en segundo plano mediante código, la precarga se detiene.
Como vemos, esta técnica puede ser muy útil en diversas ocasiones, como el ejemplo del carrusel de fotos que comentaba al principio, pero también en otros casos como por ejemplo para precargar ya desde la primera página algunos scripts, fuentes e imágenes que vamos a usar en toda la aplicación y así acelerar la carga desde la página de "splash". O también para ir cargando los siguientes datos que vamos a necesitar durante la navegación de una tabla de datos que está paginada... Cosas por el estilo.
Esa información queda grabada en la caché temporal del navegador.
Existe una variante de esta técnica que, en el caso de que el recurso sea una página web (estática o dinámica), permite no solo descargarla de antemano, sino incluso renderizarla por adelantado para tenerla lista para visualizar.
Para conseguirlo solo hay que cambiar la propiedad rel
al valor prerender
, por ejemplo:
<link rel="prerender" href="1.html" />
Esto puede ser especialmente útil para mejorar el rendimiento con páginas muy complicadas de renderizar: con muchos elementos, CSS muy complejo, etc...
Adelantamos trabajo haciéndolo en segundo plano si estamos (casi) seguros de que el usuario va a solicitar esa página en breve. La ganancia de rendimiento en un caso de estos puede ser muy apreciable.
Soporte de navegadores
El soporte de navegadores es prácticamente universal. En el caso de "prefetch" casi todos los navegador modernos lo soportan:
y en el caso de "prerender" el único de los grandes que se queda fuera es Firefox (curiosamente, siendo ellos los que empezaron con esta técnica):
De todos modos si no funcionase tampoco pasa nada: simplemente no tendríamos la mejora de rendimiento y estaríamos en la situación normal, así que no perdemos nada por utilizar esta técnica.
Algunos otros detalles a tener en cuenta
- Funciona con todo tipo de recursos que podamos cargar desde el navegador por HTTP.
- Sirve para recursos ubicados en dominios diferentes al nuestro
- Funciona también con recursos descargados a través de conexiones seguras (HTTPS)
- A todos los efectos es una petición normal, por lo que las cookies que haya en el lado cliente para el dominio al que se llama, se envían al servidor, y se reciben también. Hay que tenerlo en cuenta por tráfico, mantenimiento de sesiones (que funciona sin problemas), etc...
- Si utilizas análisis de logs, que sepas que se te van a falsear. el motivo es que te aparecerá la petición correspondiente, como si la hubiera hecho el usuario y por lo tanto hubiera visitado el recurso, pero en realidad puede que luego no la visite. Así que debes tenerlo en cuenta. Eso sí, sistemas basados en JavaScript como Google Analytics no se ven afectados.
¡Espero que te resulte útil!