Me pasa mucho que cuando comento que en Platanus somos expertos en Rails, me critican bastante.
Pero si funciona lento!
Depende.
Se quedaron desactualizados. Debieran usar Node o GoLang
Meeeh.
Hace un tiempo Andrés Matte escribió un post de que Rails si escala. No voy a escribir el 2.0. Solo quiero contarte sobre cómo conocer un framework a fondo te puede ayudar a optimizarlo mucho.
SuperCartola es un proyecto interno de Platanus. Es una plataforma que ayuda a empresas a manejar de forma fácil muchas cuentas de banco. Ya tiene algunos clientes, y está con tráfico constante.
Los timeouts se empezaron a hacer más comunes. Las consultas a SQL más largas. Funcionaba igual, pero esos microsegundos hacen que la experiencia de usuario empeore mucho.
As page load time goes from 1s to 5s, the probability of bounce increases 90%. (1)
El diagnóstico
Para monitorear la base de datos de nuestras aplicaciones usamos Scout, un add-on de Heroku muy fácil de configurar. Después de un tiempo juntando datos, me ayudó a identificar qué queries se estaban demorando mucho. Aquí un resumen de lo que estaba pasando:
La vista principal de SuperCartola trae los movimientos de tus cuentas de banco y te permite agregar más información (comentarios, estado, etc...). Uno de esos datos es la cantidad de comentarios que tiene un movimiento:
Optimizando esa vista
Existe Bullet, una herramienta para aplicaciones Rails que nos ayuda a optimizar las consultas que se hacen a la BD. Una vez instalada te va mostrando pop-ups cuando existe alguna consulta que se puede optimizar. Se ve algo así:
Estuve así un rato navegando por la aplicación. Arreglando las distintas alertas. Pero la página de inicio todavía cargaba lento. Me puse a mirar las consultas SQL de la vista principal y me pillé con esto:
En el fondo, para cada movimiento, se hace una consulta para ver cuántos comentarios tiene. Esto solo para poder poner ese ícono de la cantidad de comentarios en la cartola.
Para abordar esto, existe una herramienta muy útil que nos da Rails, los counter cache. Básicamente es una forma fácil de usar los counter_cache que tienen las bases de datos. No voy a entrar en el detalle de cómo implementarlo, pero me demoré 5 minutos en dejarlo andando.
Te dejo un pequeño tip:
Para que funcione el counter cache, tuve que cambiar esto:
### Dentro de un serializer
...
object.comments.count
...
A esto:
### Dentro de un serializer
...
object.comments.size
...
En verdad se podría usar directamente la columna debank_movement.comments_count
, pero Rails sabe manejarlo por debajo con el.size
también.
Resultado final
El resultado final de estos pequeños tweaks fue mucho mayor a lo que esperaba. Usando rack-mini-profiler pude medir la diferencia antes y después. Nada mal ese 70% de performance por un par de minutos de pega:
Como estaba:
Como quedó:
Conociendo algunos tips básicos, como este, puedes dejar funcionando la app como un Rolex. No te preocupes si te dicen que Rails no funciona bien.
Rails es bacán.
Te permite construir software a una velocidad difícil de superar.
(1) Si te interesa más sobre cómo afecta el tiempo de carga en la experiencia de usuario te recomiendo este post.