Seminario optimización de código
Transcript of Seminario optimización de código
-2-
Nexica Private & Hybrid Cloud
Fieles a nuestros compromisos de servicio, innovación y, especialmente, flexibilidad, te ofrecemos diferentes modalidades de gestión, explotación, disponibilidad y facturación para que las combines y encuentres el formato de cloud que más se adapte a tus requisitos.
Alto Rendimiento
Elasticidad
Agilidad en la Provisión
Pago por Uso
Nexica Private & Hybrid Cloud
Man
aged
Hybrid Cloud Cloud
Mo
dal
idad
es
de
Ge
stió
n
Modalidades de Servicio
Managed Cloud
Hosting
Base con coste fijo. Capacidad adicional bajo demanda, con
coste variable.
Todo el coste es variable. Capacidad bajo demanda, no
está limitada por la plataforma
Coste fijo a largo plazo (permanencia).
Capacidad fija por servidores
Virtual Infrastructure Coste fijo, capacidad
limitada por la plataforma
Managed Hybrid Cloud
Managed Hosting
Ass
iste
d
Assisted Cloud
Assisted Hybrid Cloud
Assisted Hosting
Assisted Pool
Servicio Gestionado
Seguridad
Proximidad
-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.
Servicios Gestionados
-4-
Técnicas de Optimización de Código
-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
• …
-6-
¿Qué afecta a la velocidad de una página web?
Medios
• Imágenes
• Sonido
• Video
• Documentos
• Otros
Metadatos
• Cabeceras HTTP
• Cookies
-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
-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
-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
-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
-11-
Optimización del Cacheo
-12-
Optimización del Cacheo
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
- …
Introducción
-13-
Optimización del Cacheo
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)
Introducción
-14-
Optimización del Cacheo
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.
Cacheo en Navegador
-15-
Optimización del Cacheo
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
Cacheo en Navegador
-16-
Optimización del Cacheo
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)
Cacheo en Navegador
-17-
Optimización del Cacheo
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.
Cacheo en Navegador
-18-
Optimización del Cacheo
Cacheo en Navegador - Móviles
-19-
Optimización del Cacheo
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.
Cacheo en Proxy
-20-
Optimización del Cacheo
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.
Content Delivery Network (CDN)
-21-
Optimización del Cacheo
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.
Domain Sharding
-22-
Optimización del Cacheo
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.
Domain Sharding
-23-
Minimizar el número de
Peticiones / Repuestas
-24-
Minimizar el número de Peticiones / Respuestas
El número de peticiones necesario para descargar todos los recursos de una página afecta directamente al tiempo de carga de la misma.
Introducción
¿Qué podemos hacer para reducir el número de peticiones y el tiempo de establecimiento de las mismas?
-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
-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.
-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.
-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.
-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>
-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>
-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.
-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>
-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” />
-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 = “”;
-35-
Minimizar el tamaño de
las Peticiones
-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.
-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.
-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>
-39-
Minimizar el tamaño de
las Respuestas
-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
-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
-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.
-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.
-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
-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.
-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.
-47-
Optimizar el Renderizado
-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
-49-
¿Preguntas?