Este documento presenta varias mejores prácticas para mejorar el rendimiento de aplicaciones web, incluyendo el uso de caché, CDN, compresión GZIP, lazy loading, sprites CSS, imágenes optimizadas, combinación y minificación de scripts, y monitoreo de métricas clave. También discute técnicas para el frontend como preloading y caching de páginas, y para el backend enfatiza el uso de caché, procesamiento asíncrono, y arquitectura orientada a servicios.
1. Mejorando el
rendimiento de
aplicaciones web
Edwin Cruz - Crowd Interactive
@softr8
Festival Software Libre Vallarta 2012
Friday, November 2, 12
2. Agenda
• Meta
• Personajes famosos
• Mejores Practicas
• Lidiando con la Red
• Lidiando con la aplicación
• backend
• frontend
• Servidor Web
• Servidor de base de datos
Friday, November 2, 12
3. Agenda
• Meta
• Personajes famosos
• Mejores Practicas
• Lidiando con la Red
• Lidiando con la aplicación
• backend
• frontend
• Servidor Web
• Servidor de base de datos
Friday, November 2, 12
4. Meta
Hacer que nuestra aplicación carge rápido desde la primera
visita, o al menos hacer parecer que lo hace, lo principal es
la experiencia del usuario.
Friday, November 2, 12
5. Agenda
• Meta
• Personajes famosos
• Mejores Practicas
• Lidiando con la Red
• Lidiando con la aplicación
• backend
• frontend
• Servidor Web
• Servidor de base de datos
Friday, November 2, 12
8. "If we can't make the bits travel faster, then
the only way to improve the situation is to
move the bits closer."
Ilya Grigorik
Friday, November 2, 12
12. Agenda
• Meta
• Personajes famosos
• Mejores Practicas
• Lidiando con la Red
• Lidiando con la aplicación
• backend
• frontend
• Servidor Web
• Servidor de base de datos
Friday, November 2, 12
13. Mejores Prácticas
Steve Souders y un equipo de expertos trabajando en
Yahoo identificaron/estandarizaron algunas mejores
prácticas para mejorar el rendimiento de aplicaciones web.
Friday, November 2, 12
14. Mejores Prácticas
• Minimizar peticiones HTTP
• Usar un Content Delivery Network
• Cache Control Headers
• Gzip, comprimir los paquetes
• Incluir los archivos CSS al principio
Friday, November 2, 12
15. Mejores Prácticas
• Incluir los scripts hasta el final
• Aprovechar el cache de los navegadores
• Hacer solo peticiones DNS muy necesarias
• Minimizar archivos JS y CSS
• Aprovechar E-Tags
Friday, November 2, 12
16. Mejores Prácticas
• Ajax Cacheables
• Precarga de componentes
• Dividir los componentes en dominios
diferentes
• Cookies pequeñas
• Optimizar Imágenes
Friday, November 2, 12
18. Agenda
• Meta
• Personajes famosos
• Mejores Practicas
• Lidiando con la Red
• Lidiando con la aplicación
• backend
• frontend
• Servidor Web
• Servidor de base de datos
Friday, November 2, 12
20. Lidiando con la Red
• Menos de 6 dominios diferentes
• Evitar hacer redirecciones
• 20-120 en resolver un dominio
• 1 segundo para re intentar, explorer 30
• TTL muy a futuro
Friday, November 2, 12
28. Lidiando con la Red
Minimizar scripts/css
Friday, November 2, 12
29. Agenda
• Meta
• Personajes famosos
• Mejores Practicas
• Lidiando con la Red
• Lidiando con la aplicación
• backend
• frontend
• Servidor Web
• Servidor de base de datos
Friday, November 2, 12
30. Backend, cache is king
Mandar a cache lo más posible para evitar costosas
operaciones.
Friday, November 2, 12
31. Backend, Counter Caches
• product.product_images.count vs
product.product_images_count
• select count(1) from product_images
where product_id = 1
• select * from products where id = 1
Friday, November 2, 12
32. Backend, Counter Caches
• product.inventory_units.on_hand.count vs
• product.inventory_units_on_hand_count
Friday, November 2, 12
33. Backend, Counter Caches
class Product < ActiveRecord::Base
has_many :inventory_units
def update_counter_cache
inventory_units_on_hand_count = inventory_units.on_hand.count
save
end
end
class InventoryUnit < ActiveRecord::Base
after_save :update_counter_caches
belongs_to :product
scope :on_hand, where(state: ‘on_hand’)
protected
def update_counter_caches
product.update_counter_cache
end
end
Friday, November 2, 12
34. Backend - Busquedas
Usen tecnología diseñada para búsquedas en texto
Friday, November 2, 12
35. Backend - Solr
• Usar solr para hacer busquedas de texto y
filtrado de resultados
• extremadamente poderoso y rápido
Friday, November 2, 12
39. Backend-Fragment Cache
Benchmark.ms do
Super.cache.fetch('count', :expires_in => 1.minute) do
Product.all(:conditions => ['name like ?', '%Army%']).count
end
end
=> 336.477508
Benchmark.ms do
Super.cache.fetch('count', :expires_in => 1.minute) do
Product.all(:conditions => ['name like ?', '%Army%']).count
end
end
=> 0.461155
Friday, November 2, 12
40. Backend - Super Cache
module Super
class Cache
def self.fetch(key, options, &block)
if content = Memcached.get(key)
content
else
content = yield()
Memcached.add(key, content, options[:expires_in] )
content
end
end
def exist?(key)
!Memcached.get(key).blank?
end
end
end
Friday, November 2, 12
41. Backend - Trabajar Inteligente
Hagan uso de queues(colas)
Friday, November 2, 12
42. Backend - Asynchronously
• Manden todo lo no necesario a background
• Envio emails
• Activaciones
• Procesamiento imagenes
• Tareas recurrentes
• Notificaciones a otros servicios
Friday, November 2, 12
43. Backend - CDN
Configuren su aplicación para tomar ventaja de un CDN
Friday, November 2, 12
56. Agenda
• Meta
• Personajes famosos
• Mejores Practicas
• Lidiando con la Red
• Lidiando con la aplicación
• backend
• frontend
• Servidor Web
• Servidor de base de datos
Friday, November 2, 12
57. Frontend - Caching
Full Page Caching + Personalization
Friday, November 2, 12
62. Frontend
La página principal tiene que ser la página más rápida
Friday, November 2, 12
63. Frontend - Homepage
• Codigo HTML minimo necesario,
incluyendo css’s y javascripts
• Preloading de estáticos
• Javascripts
• CSS
• Resolver nombres
Friday, November 2, 12
64. Frontend - Push+Ajax
• Descargar estaticos una sola vez
• Reemplazar el contenido del contenedor
con ajax
• Elimina descargas de estaticos
• No obstrusivo
Friday, November 2, 12
70. Frontend - Imagenes
• Nunca redimensionar con html
• Especificar el tamaño con codigo html
• Formatos correctos
• PNG
• JPEG
• MultiRes
• jQuery lazy load
Friday, November 2, 12
71. Frontend - Javascripts
• Combinar archivos
• Eliminar duplicidades
• Lazy loading: modernizr.load, require.js
• minimizar recursos
• un solo archivo con todo
• JSMin,YUI Compressor
Friday, November 2, 12
73. Frontend - Mejoras
• Entender el funcionamiento de
• HTML Parser
• HTML Renderer
• Bloqueos
• Re-Rendering
Friday, November 2, 12
74. Agenda
• Meta
• Personajes famosos
• Mejores Practicas
• Lidiando con la Red
• Lidiando con la aplicación
• backend
• frontend
• Servidor Web
• Servidor de base de datos
Friday, November 2, 12
75. Servidor Web
• Expiration Header
• ‘never expire’ para imagenes
• ‘Expire after’ para javascripts y css’s
• gzip
Friday, November 2, 12
76. Servidor Web
• Gzip
• Javascripts
• Stylesheets
• HTML
• JSON
• NUNCA! imagenes o binarios
Friday, November 2, 12
77. Servidor Web
SSL, una pesadilla
Friday, November 2, 12
79. Servidor web
Logeen Todo y haganlo “grep’eable”!
log_format main '$remote_addr - $remote_user [$time_local] $request '
'"$status" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$gzip_ratio" '
'"$http_x_forwarded_for"'
'upstream_addr $upstream_addr '
'upstream_response_time $upstream_response_time '
'request_time $request_time $cookie_Domain_Session';
174.254.55.34 - - [31/Oct/2012:23:17:27 +0000] GET /stylesheets/compiled/mobile.css?1351550028 HTTP/1.1 "200" 21218
"https://www.dominio.com/customers/accounts" "www.dominio.com" "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS
X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25" "4.84" "-" upstream_addr -
upstream_response_time - request_time 0.333 - aabcdsd4335f4f46
117.120.16.138 - - [31/Oct/2012:23:17:27 +0000] GET /help/my-measurements-faq HTTP/1.0 "200" 51489 "http://
www.dominio.com/help/fit-and-form-details" "www.dominio.com" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1;
Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.1)" "-" "203.144.29.5, 10.37.58.201"
upstream_addr 127.0.0.1:8100 upstream_response_time 0.356 request_time 0.356 - aabcdsd4335f4f46
Friday, November 2, 12
80. Agenda
• Meta
• Personajes famosos
• Mejores Practicas
• Lidiando con la Red
• Lidiando con la aplicación
• backend
• frontend
• Servidor Web
• Servidor de base de datos
Friday, November 2, 12
81. Base de Datos
Multiples Particiones
Friday, November 2, 12
82. Base de Datos
• MySQL? Percona binaries
Friday, November 2, 12
83. Base de Datos
Tablas Temporales... cuidado!
tmp_table_size
Friday, November 2, 12
84. Base de Datos
mysql_query_cache, del demonio?
Usen otro cache en frente de mysql
Friday, November 2, 12
85. Base de Datos
innodb_buffer_pool_size
El más importante, generalmente va al 70% del total de la
memoria
Friday, November 2, 12
86. Base de Datos
innodb_thread_concurrency
numero de cores * 2
Friday, November 2, 12
87. Base de Datos
Indices, evitar índices duplicados
mysql_slow_query_log
Friday, November 2, 12
88. Base de Datos
Cuiden los UPDATES
Nadie pone atención en ellos, pero son los principales
causantes de bloqueo de tablas
Friday, November 2, 12
89. Base de Datos
• Migraciones
• Agregar Columna
• Remover Columna
• Agregar Tabla
• Remover Tabla
Friday, November 2, 12
90. Parte Humana
• Siempre midan los cambios
• Paranoia es una cualidad muy codiciada
• Aprendan a manejar el pánico
• No tengan miedo de mandar cambios
• Siempre, siempre tengan un plan de
respaldo
Friday, November 2, 12