Here are the key steps to combine images into a CSS sprite:
1. Place all the images you want to combine into a single image file. Position them next to each other.
2. Use the CSS background-image property to display the sprite image.
3. Set the background-position to position the part of the sprite you want to display.
4. Set the height/width of the element to crop the image to the desired size.
5. On hover, active states etc, adjust the background-position to display a different part of the sprite.
This avoids separate HTTP requests for each image and improves perceived performance. It does increase file size so use judiciously.
2. Nexica Private & Hybrid Cloud
Fieles a nuestros compromisos de Nexica Private & Hybrid Cloud
servicio, innovación y, especialmente,
flexibilidad, te ofrecemos diferentes Agilidad en la Provisión
modalidades de gestión, explotación,
Pago por Uso Proximidad
disponibilidad y facturación para que las combines y
encuentres el formato de cloud que más se adapte a Elasticidad Servicio Gestionado
tus requisitos.
Alto Rendimiento Seguridad
Modalidades de Servicio
Virtual Hosting Hybrid Cloud Cloud
Infrastructure Todo el coste es
Coste fijo a largo Base con coste fijo. variable. Capacidad
Coste fijo, capacidad plazo (permanencia). Capacidad adicional bajo demanda, no
limitada por la Capacidad fija por bajo demanda, con está limitada por la
plataforma servidores coste variable. plataforma
Assisted
Assisted Assisted Assisted Assisted
Modalidades
de Gestión
Pool Hosting Hybrid Cloud Cloud
Managed
Managed Managed Managed
Hosting Hybrid Cloud Cloud
-2-
3. Nuestros servicios
Cloud Computing – Nexica Private & Hybrid Cloud
Recursos TIC en la nube, de pago por uso, con servicio y seguridad garantizados.
• Cloud privado / público / híbrido.
• RaaS: Servicio de recuperación ante desastres basado en cloud
Hosting Gestionado
Alojamiento de aplicaciones a medida, escalable y de alta disponibilidad.
• Alojamiento gestionado de aplicaciones.
• Balanceo, aceleración, encriptación, caching, cifrado SSL…
• Firewall de aplicaciones.
• Monitorización de transacciones web.
• Distribución de contenidos (CDN).
Correo
Servicios para garantizar el envío y la recepción de tus correos electrónicos y campañas.
• Alojamiento gestionado Exchange.
• Pasarelas de correo.
• Plataforma de envíos masivos.
Servicios Profesionales
Garantizamos la disponibilidad de tus servicios.
• Soporte técnico / manos remotas.
• Gestión y monitorización de aplicaciones 24x7.
• Pruebas de estrés de aplicaciones.
• Diseño, instalación, configuración y migración de plataformas.
-3- Servicios Gestionados
5. ¿Qué afecta a la velocidad de una página web?
Código
Código que se envía al cliente:
• HTML
• JavaScript
• CSS
Código que genera el código que se envía al cliente:
• PHP, Java (Servlets, JSP, JSF), .NET
• Librerías, APIs, Frameworks
• SQL
•…
-5-
6. ¿Qué afecta a la velocidad de una página web?
Medios
• Imágenes
• Sonido
• Video
• Documentos
• Otros
Metadatos
• Cabeceras HTTP
• Cookies
-6-
7. ¿Qué afecta a la velocidad de una página web?
Infraestructura
• Arquitectura de Servidores
• Balanceadores
• Elasticidad
• Elementos de Cacheo estático y dinámico
• Hardware
• Software y su parametrización
Velocidad de acceso
• No podemos controlar la velocidad de acceso
• Sí podemos tomar decisiones en función del tipo de conexión
-7-
8. ¿Qué afecta a la velocidad de una página web?
Interpretación y Renderizado
• Navegador (y versión)
• Dispositivo
• Ordenador
• Móvil
• Tablets, Consolas, Televisores….
• Podemos tomar decisiones en función de estos parámetros
-8-
9. ¿Qué vamos a ver en este seminario?
Web Performance Optimization (WPO)
• Conjunto de “Best Practices” relativas al rendimiento web
• Basadas en reglas
• Herramientas
• Desde el punto de vista del cliente
• Medida: Tiempo de carga de la página (W3C, Navigation Timing)
• Sobre cualquier elemento que afecte al rendimiento
-9-
10. Web Performance Best Practices
Categorías
• Optimización del Cacheo
• Minimizar el número de peticiones / respuestas
• Minimizar el tamaño de las peticiones
• Minimizar el tamaño de las respuestas
• Optimizar el renderizado
-10-
12. Optimización del Cacheo
Introducción
Elementos de las páginas web que cambian con poca frecuencia pueden ser
cacheados para evitar solicitarlos y descargarlos en cada petición.
- Principalmente:
- HTML
- CSS
- JavaScript
- Imágenes
- Pero también:
- Medios
- Flash
- …
-12-
13. Optimización del Cacheo
Introducción
Cacheando estos contenidos se reduce:
- Número de peticiones
- Volumen de descarga (reducción de costes)
Podemos cachear en:
- Navegador
- Proxy Caché
- Content Delivery Network (CDN)
-13-
14. Optimización del Cacheo
Cacheo en Navegador
Podemos configurar nuestro servidor web para incluir cabeceras de cacheo al
servir nuestros contenidos.
HTTP/1.1 ofrece las siguientes cabeceras:
- Expires y Cache-Control: max-age
Fecha de expiración del recurso y tiempo máximo de almacenaje en caché.
- Last-Modified y Etag
Fecha de modificación del recurso y UID
En principio deberíamos utilizar sólo un mecanismo de cada par, puesto que
son redundantes.
-14-
15. Optimización del Cacheo
Cacheo en Navegador
Ejemplo de cabecera devuelta por el servidor:
HTTP/1.1 200 OK
Last-Modified: Tue, 22 May 2012 02:02:15 GMT
ETag: "10c24bc-4ab-457e1c1f"
Content-Length: 12195
En la siguiente petición al mismo recurso, se envía esta información en la
cabecera HTTP:
GET /img/logo.png HTTP/1.1
Host: www.nexica.com
If-Modified-Since: Tue, 22 May 2012 02:02:15 GMT
If-None-Match: "10c24bc-4ab-457e1c1f“
HTTP/1.1 304 Not Modified
-15-
16. Optimización del Cacheo
Cacheo en Navegador
Si tenemos la necesidad de forzar la recarga de un recurso antes de la fecha
que especificamos, podemos cambiar su URL o parte de ella. (URL
fingerprinting)
-16-
17. Optimización del Cacheo
Cacheo en Navegador
Existen otras consideraciones a tener en cuenta en función del navegador o
dispositivo:
- En función de la implementación, puede que el navegador decida borrar
elementos de la caché antes de su fecha de expiración, normalmente los
menos utilizados.
- En Firefox, la URL del recurso ha de variar en como mínimo 8 caracteres
para evitar colisione en el algoritmo de hasheo de recursos.
- Firefox sólo cachea contenido servido bajo HTTPS si existe la cabecera
Cache Control: public
- Los dispositivos móviles, por espacio, suelen no cachear elementos que
superen un determinado tamaño.
-17-
19. Optimización del Cacheo
Cacheo en Proxy
Podemos indicar que un recurso sea cacheable en los proxies a través de la
cabecera HTTP Cache Control: public
Recomendaciones:
No incluir parámetros en la URL de acceso al recurso que queremos cachear,
ya que ciertos proxies no cachearán este recurso independientemente del
valor de la cabecera Cache Control.
<img src=“http://www.nexica.com/images/logo.png?v=1” />
No cachear recursos que generen cookies (Cache Control: private), o mejor
aún, utilizar un dominio sin cookies para servir contenidos que queramos
cachear.
-19-
20. Optimización del Cacheo
Content Delivery Network (CDN)
Servidores de contenido estático distribuidos geográficamente que sirven el
contenido desde el servidor más cercano de la CDN.
El contenido que se quiere servir desde la CDN es accedido a través de un
subdominio del estilo static.example.com , que resuelve a una IP diferente en
función de la localización del cliente.
Recomendado para grandes sitios con acceso internacional.
Favorece el Domain Sharding.
-20-
21. Optimización del Cacheo
Domain Sharding
En función de la implementación, los navegadores están limitados a cierto
número de conexiones simultaneas por dominio. Por ejemplo 2 en IE7.
Esto provoca la serialización de peticiones HTTP a una página.
www.example.com/resource1
www.example.com/resource2
www.example.com/resource3
www.example.com/resource4
www.example.com/resource5
www.example.com/resource6
Mediante la técnica de Domain Sharding podemos aumentar el número de
conexiones simultaneas desde un navegador a nuestra web.
-21-
22. Optimización del Cacheo
Domain Sharding
www.example.com/resource1
www.example.com/resource2
ww1.example.com/resource3
ww1.example.com/resource4
static.example.com/resource5 (CDN)
static.example.com/resource6 (CDN)
- Aumenta el tiempo de resolución de DNS.
- Puede tener implicaciones en el SEO de nuestro sitio si no limitamos la
indexación de contenidos a un único dominio. Contenidos duplicados.
- Si servimos contenidos bajo HTTPS, debemos securizar cada uno de los
subdominios adecuadamente.
-22-
24. Minimizar el número de Peticiones / Respuestas
Introducción
El número de peticiones necesario para descargar todos los recursos de una
página afecta directamente al tiempo de carga de la misma.
¿Qué podemos hacer para reducir el número de peticiones y el tiempo de
establecimiento de las mismas?
-24-
25. Minimizar el número de Peticiones / Respuestas
Introducción
- Combinar ficheros JavaScript
- Combinar ficheros CSS
- Combinar imágenes usando CSS Sprites
- Reducir el número de resoluciones de DNS
- Reducir el número de redirecciones
- Eliminar peticiones que acaban en 404
- Eliminar imágenes sin src
- Optimizar el orden de CSS y JS
- Evitar document.write y @import
- Cargar recursos de forma asíncrona
- Paralelizar descargas
- Cachear llamadas AJAX
-25-
26. Minimizar el número de Peticiones / Respuestas
Combinar ficheros JS
Si combinamos varios ficheros JS en una, sólo es necesario realizar una conexión para
descargar todo el código incluido en dichos ficheros.
¿Es buena idea combinar todo el código JavaScript de una aplicación en un único
fichero?
Idealmente sólo deberíamos descargar el código necesario para el contenido que
estamos visualizando.
-26-
27. Minimizar el número de Peticiones / Respuestas
Combinar ficheros JS
Recomendaciones:
- Crear dos ficheros JS: Uno que tenga el código mínimo necesario para la
renderización inicial de la página y otro con el código que no necesitaremos hasta
una vez la página haya cargado.
- Incluir el menor número posible de ficheros JS en el <head>
- Minimizar el tamaño de estos ficheros.
- Si tenemos código correspondiente a páginas con pocas visitas, dedicarles un fichero
propio y descargarlo sólo cuando un usuario acceda a dicho contenido.
- Si sólo hemos de incluir pequeños trozos de código, evaluar la posibilidad de
incrustarlo en el propio HTML.
- Evitar el uso de document.write
- Posicionar correctamente la carga de JS en el código para maximizar las descargas en
paralelo.
-27-
28. Minimizar el número de Peticiones / Respuestas
Combinar ficheros CSS
El caso de los ficheros CSS es similar al de los JS y por lo tanto también las
recomendaciones en este aspecto.
Recomendaciones:
- Crear dos ficheros CSS: Uno que tenga los estilos necesarios para la renderización
inicial de la página y con los estilos que no necesitaremos hasta una vez la página
haya cargado.
- Servir el CSS de contenidos con pocas visitas en un fichero independiente.
- Evaluar la posibilidad de incrustar el CSS en el propio HTML.
- Evitar el uso de @import (ya en desuso)
- Posicionar correctamente la carga de los CSS respecto a los JS en el código para
maximizar las descargas en paralelo.
-28-
29. Minimizar el número de Peticiones / Respuestas
Optimizar el orden de CSS y JS
Dado que el contenido de ficheros JS puede alterar el contenido y disposición de
elementos en la página, el navegador bloquea el renderizado, e incluso la descarga, del
contenido que sigue a un script hasta que éste se ha descargado, parseado y ejecutado.
<head>
<link rel="stylesheet" type="text/css" href="stylesheet1.css" />
<script type="text/javascript" src="scriptfile1.js" />
<script type="text/javascript" src="scriptfile2.js" />
<link rel="stylesheet" type="text/css" href="stylesheet2.css" />
<link rel="stylesheet" type="text/css" href="stylesheet3.css" />
</head>
-29-
30. Minimizar el número de Peticiones / Respuestas
Optimizar el orden de CSS y JS
En cambio, si comienza a descargarse un JS cuando ya hay otros recursos en descarga,
éste se descarga en paralelo.
<head>
<link rel="stylesheet" type="text/css" href="stylesheet1.css" />
<link rel="stylesheet" type="text/css" href="stylesheet2.css" />
<link rel="stylesheet" type="text/css" href="stylesheet3.css" />
<script type="text/javascript" src="scriptfile1.js" />
<script type="text/javascript" src="scriptfile2.js" />
</head>
-30-
31. Minimizar el número de Peticiones / Respuestas
Optimizar el orden de CSS y JS
Por lo general deberíamos cargar los CSS lo antes posible (<head>) y los JS al final y si es
posible, de forma asíncrona.
async y defer
Gracias a estos “hints” podemos indicar al navegador cómo queremos que se comporte
ante los ficheros JS:
- async == true: El Script se ejecuta de forma asíncrona tan pronto como está
disponible.
- async == false, defer == true: El script se ejecuta cuando la página se ha acabado de
parsear.
- async == defer == false: El script se ejecuta de forma inmediata, antes de continuar
parseando la página.
-31-
32. Minimizar el número de Peticiones / Respuestas
Optimizar el orden de CSS y JS
Podemos usar defer, por ejemplo, sobre un código JS que se encargue de cargar otros
fichero JS que no son necesarios en la carga inicial de la página.
<script type="text/javascript">
var element = document.createElement("script");
element.src = "moreJavaScriptCode.js";
document.body.appendChild(element);
</script>
-32-
33. Minimizar el número de Peticiones / Respuestas
Combinar imágenes usando CSS Sprites
De forma similar a los JS y CSS, descargar múltiples imágenes implica realizar muchas
peticiones.
Una buena alternativa es combinar en una única imagen aquellas que suelan aparecer
juntas con frecuencia y mostrarlas de forma individual usando CSS.
Recomendaciones:
- Utilizar formatos de imagen para iconos (GIF, PNG8)
- Minimizar el espacio vacío entre imágenes
- Evaluar la posibilidad de incrustar imágenes directamente en el HTML
<img src="data:image/gif;base64,”TEXTOBASE64” />
-33-
34. Minimizar el número de Peticiones / Respuestas
Eliminar imágenes sin src
Una imagen sin src puede ocasionar diferentes problemas en función de la
implementación en el navegador y la configuración del servidor:
- No devolver nada.
- Devolver toda la página completa.
- Devolver el listado de ficheros del servidor para la ruta actual.
Se genera un tráfico innecesario y en el peor de los casos pueden sobrescribirse cookies
que impliquen pérdida de información.
Podemos encontrar imágenes sin src:
- Directamente en el código HTML: <img src=“”>
- Como parte de un código JavaScript:
var img = new Image();
img.src = “”;
-34-
36. Minimizar el tamaño de las Peticiones
Minimizar el tamaño de la Peticiones
Cada vez que nuestro navegador realiza una petición HTTP envía todas las cookies que
tenga par dicho dominio y path.
Dado que muchos usuarios tienen conexiones asimétricas, la velocidad de subida es
muy inferior a la de descarga.
En un ADSL de 10Mb/500Kb una petición de 20KB equivale a una descarga de 400KB.
Recomendaciones:
- Reducir el tamaño de las cookies al mínimo. (UID)
- Servir el contenido estático desde un dominio sin cookies.
- Si servimos el contenido desde un CDN, solicitar que sea sin cookies.
- Aplicar correctamente la fecha de expiración de las cookies.
- Intentar reducir la longitud de las URLs.
-36-
37. Minimizar el tamaño de las Peticiones
Reducir el tiempo de resolución DNS
La resolución de dominios que ha de realizar el navegador para transformar los
dominios en direcciones IP implica un tiempo de consulta a los servidores DNS.
Aún teniendo en cuenta técnicas como el Domain Sharding, deberíamos intentar servir
los contenidos de nuestra página desde el menor número posible de dominios.
Los navegadores más modernos implementan DNS Prefetching. Esta técnica consiste en
resolver los dominios de los enlaces de la página actual de forma automática antes de
que el usuario pulse sobre ellos.
-37-
38. Minimizar el tamaño de las Peticiones
Minimizar el número de redirecciones
Las redirecciones añaden latencia a las peticiones , ya que han de hacer la petición
tanto a la URL antigua como a la redireccionada.
Es importante añadir cabeceras de expiración en la respuesta que acompaña a una
redirección para que estas puedan ser cacheadas.
Una redirección muy frecuente ocurre cuando se especifican URLs que no terminan en
‘/’, que puede evitarse fácilmente configurando el servidor web para añadirlas
automáticamente.
El peor de los casos es realizar la redirección por código, en lugar de cabeceras HTTP:
<script type="text/javascript">
window.location = "http://www.google.com/"
</script>
-38-
40. Minimizar el tamaño de las Respuestas
Introducción
El peso de los recursos que devuelve nuestra aplicación tiene un impacto directo en el
tiempo que éstos tardan en descargarse y por lo tanto en el tiempo de respuesta de
nuestra web.
Recomendaciones:
- Evitar comentarios o código muerto en el HTML, JS y CSS
- Hacer que el código JavaScript y CSS sea cacheable externalizándolo
- Minimizar el tamaño de los JS
- Minimizar el tamaño de los CSS
- Optimizar las imágenes
-40-
41. Minimizar el tamaño de las Respuestas
Activar la compresión
Configurando nuestro servidor para comprimir ciertos recursos, podemos reducir
drásticamente el tiempo de descarga de los mismos.
“Every day, more than 99 human years are wasted because of uncompressed content”
Comprimir / descomprimir consume cierto tiempo, pero suele ser menor que el ahorro
conseguido por enviar la información comprimida.
Recomendaciones:
- La compresión ha de ser selectiva:
- HTML, JS, CSS y Ficheros de texto (xml, txt, …)
- No conviene comprimir ficheros de imágenes ni binarios
- Tampoco ficheros de menos de 150 bytes
-41-
42. Minimizar el tamaño de las Respuestas
Minimizar el tamaño de los JS
Eliminando los caracteres innecesarios de los ficheros JS podemos reducir su tamaño y
por lo tanto acelerar su descarga y tiempo de parseo:
- Espacios
- Retornos de carro
- Tabulaciones
- Comentarios y código obsoleto o pruebas
- Duplicidades
Esto es aplicable al propio HTML.
Programamos sobre una versión “normal” del código, pero la “condensamos” antes de
publicarla.
Se ha estimado que la mejora es notable en ficheros JS a partir de 4KB.
-42-
43. Minimizar el tamaño de las Respuestas
Minimizar el tamaño de los JS
También es posible reemplazar el nombre de funciones o variables por literales más
cortos:
function add(firstNumber, secondNumber) {
var sum = firstNumber + secondNumber;
return sum;
}
function add(_a, _b) { var _c = _a + _b; return _c; }
Lo cual añade cierto grado de ofuscación al código.
-43-
44. Minimizar el tamaño de las Respuestas
Minimizar el tamaño de los CSS
De forma análoga a los JS, es posible reducir el tamaño de los CSS.
- Eliminado caracteres innecesarios
- Eliminando comentarios
- Eliminando estilos que no se utilizan
- Usando la variante de colores en su notación más corta:
- Rojo:
- #ff0000
- #ff0
- red
-44-
45. Minimizar el tamaño de las Respuestas
Optimizar Imágenes
Es importante seleccionar un formato adecuado en función del uso que daremos a la
imagen.
- PNG suele dar mejores resultados que GIF para iconos y logos.
- Utilizar JPG para fotografías.
- Evitar el uso del formato BMP y TIFF a no ser que nuestra aplicación los requiera.
Es interesante realizar pruebas con los ratios de compresión de las imágenes, ya que se
pueden conseguir grandes reducciones de peso con una pérdida de calidad a penas
perceptible.
-45-
46. Minimizar el tamaño de las Respuestas
Optimizar Imágenes
Recomendaciones:
- Especificar siempre el height y width de las imágenes en el HTML o CSS.
- No escalar imágenes por código. Es mejor servir un thumbnail y una imagen de
mayor resolución de forma asíncrona.
- Servir una imagen siempre por la misma URL para maximizar el rendimiento de la
caché.
Es útil disponer de un favicon o como mínimo un favicon.ico vacío para evitar devolver
códigos 404.
- Cacheable
- Ligero
- Susceptible de tener una fecha de expiración en caché elevada.
-46-
48. Optimizar el Renderizado
Optimizar el Renderizado
Una vez los recursos han llegado al cliente, éste ha de interpretarlo y renderizarlo.
Hay una serie de pautas que nos pueden ayudar a optimizar esta parte del proceso:
- Evitar el uso de expresiones en CSS (Obsoletas IE5 -> IE7)
- Poner el CSS en el <head>
- Programación eficiente de JavaScript
- Reducir el número de elementos de DOM
- Reducir el número de iFrames
- Especificar el alto y ancho de las imágenes
- Especificar el ancho de las tablas
- Generar HTML bien formado
-48-