Web BizarroWeb Bizarro

Suscríbete a nuestro Newsletter

X

Únete a nuestra lista de correos para recibir semanalmente actualizaciones de nuestro contenido.

6 reglas para crear aplicaciones rápidas

6 reglas para crear aplicaciones rápidas 20.NOV.15

Alvaro José Rios Ch
Fundador WebBizarro

En este artículo vamos a hablar de algunas cosas que podemos hacer para que nuestras aplicaciones sean más rápidas, todo desde el punto de vista del backend. Estas reglas se pueden aplicar con cualquier lenguaje y framework, pero para fines practicos vamos a hablar de PHP.

 

Regla 1: evitar la optimización prematura

Este es un problema común con los desarrolladores, pierden mucho tiempo tratando de optimizar código en zonas no criticas de la aplicación y esto pasa precisamente porque no saben cuales son las zonas criticas, por eso es mejor escribir la primera versión sin preocuparse mucho del rendimiento y luego usar un perfilador para ver donde están los cuello de botella.

 

Regla 2: hacer justo lo que necesitas

Muchas veces el código hace más de lo que necesita, por ejemplo cuando cargamos alguna librería o una clase podemos usar recursos como archivos o conexiones a la base de datos que no son necesarias para la solicitud. Hay algunas técnicas que nos pueden servir como por ejemplo.

Autoloading: una característica de PHP que permite solicitar el archivo que contiene una clase solo cuando esa clase es usada, antes era bastante complicado usar esta herramienta pero actualmente herramientas como composer lo hacen mucho más fácil.

Dependency Injection: un patrón de diseño muy usado en java y que actualmente se ve más en PHP gracias a frameworks como Symphony o Laravel. Básicamente trata cargar pequeñas dependencias por medio del constructor o un método setter, esto obliga al desarrollador a tener que dividir todo en paquetes que hagan una sola cosa y la hagan bien.

Lazy Loading: es otro patrón de diseño basado en el principio de no inicializar un objeto hasta que este no sea utilizado, generalmente usado para conexiones a base de datos o recursos que cargan datos desde archivos.

 

Regla 3: Mamá lo hago mañana

Cuantas veces necesitas enviar un correo a un usuario, cuando se registra o cuando cambia el password, solo por dar un ejemplo. Estas tareas “pesadas” tardan un momento en ejecutarse y los usuarios esperan un mensaje de respuesta lo más pronto posible, por eso lo mejor es aplazar cualquier tarea que no tenga nada que ver con la creación de este mensaje.

Generalmente se hacen colas de trabajo, simplemente se coloca un registro en una base de datos (como mongo por ejemplo) y luego se ejecutan los procesos necesarios como enviar el correo, esto evita que el usuario tenga que esperar.

 

Regla 4: usar cache siempre que se pueda

Los sitios web modernos son complejas estructuras de código que hacen múltiples cosas en cada petición que hacemos, como consultar la base de datos, parsear datos a diferentes formatos (json, xml, etc), e incluso usar sistemas de template para convertir todos esos datos en una página HTML, sin embargo nuestro servidor pierde mucho tiempo ejecutando tareas repetitivas una y otra vez.

La solución inteligente es usar cache, esta nos permite almacenar datos consultados recientemente para no tener que consultarlos otra vez.

Byte Code Cache, común en los lenguajes interpretados lo que hacen es evitar revisar el código si no ha habido ningún cambio algunos lenguajes como python lo traen en el nucleo, php requiere activar una extensión como Xcache.

Aplication Cache, no lo confundas con el aplication cache de HTML5, se trata de ese cache que colocamos a nuestra aplicación por ejemplo si hacemos una gran consulta a la base de datos para cargar el home del sitio, podemos colocar la consulta en cache e incluso colocar todo el home en cache y así ahorrar tiempo. Para esto podemos usar Memcached, Redis o Gibson.

Cache HTTP, consultar por la red a cada momento es algo realmente costoso por eso es mejor decirle al navegador que el ya descargó algunos elementos para eso usamos los headers Etag y Cache-control, esto ayuda a descargar mucho al servidor.

Proxy cache, esta técnica se trata de tener un servidor que recibe todo el tráfico web y tiene una copia completa del sitio por lo que puede entregarla mucho más rápido y se evita sobrecargar al servidor de la aplicación.

El principal problema con el uso de cache y es algo con lo que deben tener cuidado, es cuando la invalidamos, cuando los datos en cache no son validos, esto depende mucho del comportamiento de nuestra aplicación y no hay una única forma de resolverlo, por ejemplo podemos usar menos niveles de cache para nuestra aplicación.

 

Regla 5: evite el problema de N + 1 consultas

Esto es algo que puede ocurrir de forma involuntaria muchas veces, sobre todo si se usa algún sistema ORM y no sabe usarlo bien. Se trata de consultar N registros en la base de datos usando N + 1 consultas. Vea el siguiente código.

<?php function getUsers() {
    //... retrieve the users from the database (1 query)
    return $users;
}

function loadLastLoginsForUsers($users) {
    foreach ($users as $user) {
        $lastLogins = ... // load the last logins for the user (1 query, executed n times)
        $user->setLastLogins($lastLogins);
    }
    return $users;
}

$users = getUsers();
loadLastLoginsForUsers($users);

Como puede ver primero consulta todos los usuarios en la base de datos y luego consulta la última vez que hicieron login uno por uno, eso genera algo como esto.

SELECT id FROM Users;
-- ids: 1, 2, 3, 4, 5, 6...
SELECT * FROM Logins WHERE user_id = 1;
SELECT * FROM Logins WHERE user_id = 2;
SELECT * FROM Logins WHERE user_id = 3;
SELECT * FROM Logins WHERE user_id = 4;
SELECT * FROM Logins WHERE user_id = 5;
SELECT * FROM Logins WHERE user_id = 6;
-- ...

Esto puede cambiarse fácilmente por

SELECT id FROM Users;
-- ids: 1, 2, 3, 4, 5, 6...
SELECT * FROM Logins WHERE user_id IN (1, 2, 3, 4, 5, 6, ...);

Este último es más eficiente, incluso podría usar un JOIN también y soluciona el problema del N + 1, sin embargo para solucionar esto debes tener control de las consultas a la base de datos o conocer muy bien el ORM con el que estas trabajando, los perfiladores también pueden ser un herramienta útil en estos casos.

 

Regla 6: escalar horizontalmente

Escalabilidad es la capacidad que tiene tu aplicación para mantener el mismo rendimiento en el caso de tener una gran cantidad de usuarios haciendo peticiones, esto es un tema complejo y no hablaremos mucho sobre esto pero hay dos problemas fundamentales con la escalabilidad.

Sesiones de usuario, generalmente sistemas como PHP guardan la información de sesión del usuario en un archivo local, esto no es solo más lento sino que además tendrás problemas cuando quieras agregar más maquinas al cluster, ya que si la información de sesión esta en una maquina al pasar a otra se perderá. Esto se puede solucionar fácilmente guardando los datos de sesión en la base de datos por ejemplo, muchos frameworks permiten hacer esto solo con un poco de configuración, otra forma es elegir tu método de almacenamiento de sesión favorito e instalarlo en tu servidor y luego cuando tengas que crecer moverlo a una maquina a la que todas en el cluster puedan alcanzar.

El otro problema son los archivos de usuario, si tu aplicación almacena archivos de los usuarios debes tener en cuenta como vas a sincronizarlos, incluso puedes pensar usar servicios de almacenamiento como Amazon S3.También puedes usar NFS para crear directorios compartidos.

 

Bien espero que les sea de ayuda, cualquier otro aporte pueden dejarlo en los comentarios. Finalmente pueden ver más información en la versión en ingles de este artículo.