SPA, SSR, SSG... ¿de qué se trata?
En este artículo voy a hacer un análisis de los diferentes tipos de diseño desde el punto de vista del frontend. Viniendo de una trayectoria mayormente orientada a backend y con la necesidad actual de desempeñarme del otro lado del espejo, me vi en la necesidad de ponerme al corriente sobre qué opciones tenemos hoy al momento de idear una interfaz web.
Aplicaciones full-stack tradicionales
Comencemos por la vieja (pero no obsoleta 🦾) arquitectura full-stack. En estas aplicaciones la mayor parte del contenido es procesado en el servidor y entregado casi en su totalidad de forma estática, con la salvedad de alguna interacción dinámica resuelta mediante JS/AJAX. Para ello solemos usar algún motor de plantillas a fin de componer las vistas HTML sin repetir contenido y lograr una mayor modularización. Estos motores de plantillas suelen ser parte de la misma solución backend, esto es, misma plataforma, mismo lenguaje y forman parte del mismo proyecto. A este mecanismo lo conocemos como Server-Side Rendering.
SPA
Este concepto de Single-Page Application se popularizó con el arribo de los entonces novedosos frameworks frontend como Angular y React. Fue en su momento un enfoque disruptivo en el que, a diferencia de los sitios tradicionales y como su nombre indica, no tendremos varias páginas sino una única, la cual se cargará con su contenido (hojas de estilo y JS) una única vez; el cuerpo del HTML de esta página consiste en una ranura en la cual se insertará, removerá y actualizará el contenido de forma dinámica según se lo haya programado con Javascript. Esto implica que tendremos un tiempo de carga inicial un poco mayor pero luego de ello el sitio brindará una experiencia en principio más veloz y fluida. El sistema de enrutamiento es también delegado a la aplicación frontend, la cual normalmente también actualiza las URLs conforme el usuario utiliza las diferentes características de la aplicación.
La principal ventaja de las SPA es, desde un punto de vista arquitectónico, que logramos extraer la totalidad de lógica relacionada con vistas y content rendering de nuestros servidores, por lo que nos quedará una API ligera que sólo transaccionará en JSON, XML o algún otro formato de intercambio de datos.
Hablando de los costos, las SPA resultan maravillosas ya que podemos alojarlas en un servidor estático o incluso en un bucket, por lo que tendremos costos de cómputo muy bajos o nulos.
Por último pero no menos importante, estos frameworks frontend nos permiten estructurar nuestras aplicaciones en componentes y vistas, por lo que el mantenimiento y reusabilidad del código crecen, en principio, drásticamente.
Sin embargo …
No es todo color de rosa
Los sitios diseñados como SPA presentan diferentes limitaciones, como:
- La imposibilidad total o parcial de indexación de contenido en motores de búsqueda (SEO) y problemas al momento de utilizar otras herramientas que requieren que el contenido sea estático, como los sitios de redes sociales que esperan metadatos OpenGraph en el documento HTML;
- Si nuestra aplicación está orientada a datos, cuando nuestro sitio crezca nos toparemos con problemas de rendimiento que no podremos resolver de forma trivial mediante el uso de CDNs, ya que éstas se limitan a almacenar copias del contenido estático, y las llamadas que haga nuestra aplicación a la correspondiente API deberán ser también contempladas y configuradas en las reglas de la CDN, toda vez que sea posible.
Por otro lado debemos tener presente que, si bien estamos hablando de una aplicación frontend, la misma no deja de ser monolítica. Esto es: la totalidad de la aplicación que contempla todos los casos de uso, en un único producto que normalmente es mantenido por diferentes equipos. He visto cómo la extensibilidad del producto decrece conforme avanza el ciclo de vida del producto y éste se vuelve más complejo, como todo monolito. Sobre este punto sólo mencionaré que hace años se viene desarrollando el concepto de micro-frontends, aunque como todo micro*, tiene sus desafíos y requiere de un ser de luz que guíe el plan de migración con total certeza de lo que se debe hacer y hacia dónde se desea llegar; también he visto fallar a compañías tratando de aplicarlo.
SSG
Static Site Generation (también llamado pre-rendering) lleva la generación de contenido un paso más allá: partiendo del supuesto de que el contenido será el mismo para todos los usuarios y sólo cambiará cuando el administrador del mismo lo modifique, ¿por qué no generarlo en tiempo de compilación y entregarlo de forma completamente estática? Suena genial ¿no?.
Un ejemplo de SSG es este Blog, el cual está escrito con Hugo, y no requiere más infraestructura que un servicio que “escucha” cuando alguien hace un push al repositorio y entonces compila todo el sitio y lo despliega en su CDN. Bueno, barato y bonito.
El problema es, naturalmente, que para la mayoría de los negocios los dos supuestos de contenido común y cambio predecible no aplican. El contenido suele estar justamente orientado a cada usuario y se espera que gran parte del mismo cambie en tiempo real.
Una nueva forma de SSR
Cuando hablamos previamente sobre las aplicaciones full-stack mencionamos server-side rendering. Sin embargo conocemos los desafíos que esto acarrea en un mercado que en los últimos años no ha hecho más que demandar interfaces cada vez más fluidas y dinámicas. Por ejemplo, si tenemos que resolver esto con PHP y Twig/Blade a la vieja escuela, pasaremos un mal rato escribiendo plantillas del lado del servidor y luego gestionando el código del lado del cliente. Es en ese momento en el que comenzamos a extrañar las virtudes de las SPA y la orientación a componentes, donde cada uno es auto-contenido y altamente reutilizable.
Ahora bien ¿Qué pensarás si te cuento que hoy en día se ha llevado este enfoque a un nuevo nivel? La mayoría de los frameworks frontend soportan actualmente SSR y esto nos abre todo un nuevo abanico de posibilidades. Podremos construir nuestro frontend con componentes con todas las ventajas que ello implica como usar Storybook (yay)! Aunque debemos saber que esto no es gratuito, ya que necesitaremos que nuestro servidor, más allá del lenguaje con el que hayamos construido nuestro backend y si es compilado o interpretado, deberá ejecutar node
para compilar cada página.
Es importante que notemos también que varios frameworks backend están soportando actualmente integración con su contraparte frontend para lograr el SSR 😉.
¿Cuándo utilizar cada enfoque?
Aquí daré mi opinión estrictamente subjetiva, por lo que te recomiendo que hagas una evaluación pormenorizada según tu caso de uso específico y no te dejes llevar ni por mis ideas ni las de ningún otro autor que encuentres. Ten en cuenta que fallar en una decisión de diseño tan temprana suele ocasionar un gran impacto en el futuro crecimiento de tu proyecto.
¿Qué aspectos creo que deberíamos tener en cuenta para elegir un enfoque u otro?
- ¿El contenido debe ser indexado por motores de búsqueda? (Dicho de otra forma: ¿es una plataforma pública o privada?)
- ¿Cuándo cambiará el contenido de cada sección?
Encuentro especialmente atractiva la idea de una SPA para aplicaciones backoffice, ya que su contenido es privado y se espera que cambie constantemente; gran parte del mismo tampoco debería ser almacenado en cachés (al menos no las entidades de negocio) ni compartido en ningún portal público.
Para el caso de las aplicaciones públicas, como vimos, quizá construir una SPA no sea la mejor opción. Y es aquí donde se abre un debate entre un enfoque full-stack ó SSR. Creo que la decisión dependerá principalmente de la complejidad inicial y plazos del proyecto: ¿se justifica destinar tiempo y dinero a una aplicación que integre tecnología frontend o será suficiente con una aplicación full stack tradicional? Será tu responsabilidad encontrar la respuesta.
Por último, te recomiendo que leas este artículo de Michael Pratt en el que comparte su experiencia con SPAs.