Server Side Rendering

Server Side Rendering

En este artículo explicaremos qué es el Server Side Rendering y cuándo deberíamos usarlo.

Si estás trabajando con un framework de desarrollo web más o menos moderno lo más probable que es que hayas oído hablar del término Server Side Rendering por lo que es probable que, si no lo has visto anteriormente, no sepas de qué se está hablando y sobre todo por qué se está mencionando tanto en el desarrolo frontend.

Server Side Rendering (a partir de ahora SSR), que podemos traducir al español como renderizado del lado del servidor, no es más que un método que permitirá construir archivos en el backend como respuesta a una petición de un cliente con el objetivo de mejorar dos cosas:

  • por una parte el SEO.

  • por otra parte aumentar la velocidad de carga de nuestra aplicación, es decir, la primera vez que nuestro sitio es visitado.

Cómo se crean aplicaciones web.

Para poder entender cómo funciona SSR lo primero en lo que tenemos que pensar es en cómo se crean aplicaciones web hoy en día. Una de las formas que tenemos para ello (siendo la más habitual) que una aplicación tenga un proyecto de frontend y otro de backend separados. Para la creación de la aplicación en el backend se pueden utilizar frameworks como Express, django, spring, ruby on rails, etc. mientras que en el frontend se usan comúnmente frameworks de JavaScript como React, Vue, Angular, Svelte o incluso JavaScript puro (lo que se conoce como Vanilla JavaScript).

Para poder realizar la comunicación entre el frontend y el backend se pueden crear API en el backend que al consultarla lo que harán será devolvernos datos en formato JSON. De esta manera el funcionamiento de una petición a nuestra aplicación se podría comportar así:

  1. El navegador visita por primera vez nuestra página web.

  2. El servidor sirve archivos en formato HTML, CSS y JavaScript como resultado de esta primera petición.

  3. Con toda esta información el navegador va a ser capaz de crear el esqueleto de nuestra aplicación web lo que implica que ninguno de estos archivos será necesario volverlos a pedir en próximas interacciones del usuario.

  4. Así las siguiente peticiones que se realicen desde nuestra aplicación hacia el servidor serán peticiones HTTP para consultar o modificar datos (normalmente peticiones GET, POST, etc.) que se llevan a cabo utilizando datos en formato JSON.

Por lo tanto en esta primera petición lo que se hace es crear todos los archivos necesarios para poder renderizar nuestra aplicación en el navegador y es a partir de ahí que se van realizando distintas peticiones HTTP para poder ir renderizando nuevos datos. Es más, como todo el código de la aplicación está en el navegador del cliente cuando se produce un cambio de página el resultado de este cambio ya está en el navegador (no es necesario hacer una nueva petición al servidor) y es por eso que se conoce como Client Side Rendering (CSR).

El CSR tiene una serie de ventajas en lo que respecta a la mejora de la experiencia de usuario puesto que el usuario no espera una página nueva en cada interacción y los datos al llegar simplemente en formato JSON son más rápidos y, por lo general, no pesan tanto como en el caso de enviar archivos HTML, CSS y JavaScript.

Además al seguir esta aproximación el frontend y el backend se pueden desarrollaro por separado cada uno con su lenguaje de programación y sin que interfieran entre sí. A parte, la misma API que nos ofrece el backend puede pasar a ser utilizada en otras aplicaciones de cliente como podrían ser aplicaciones que se ejecuten en el móvil, aplicaciones de escritorio, etc.

Esto en la práctica se traduce en que JavaScript es el lenguaje principal a la hora de crear interfaces de usuario y lo más probable es que si estamos acostumbrados a trabajar con frameworks de JavaScript modernos lo más probable es que nos encontremos en el código fuente de nuestra página principal algo como lo que se puede ver en la siguiente imagen:

donde podemos ver que tenemo un único <div> que será donde montaremos nuestra aplicación y luego dos elementos <script> uno que será para cargar el código del framework con el que estamos trabajando y otro para cargar el código de nuestra aplicación.

Ahora bien, este enfoque presenta también una serie de desventajas. Por ejemple los crawlers (arañas) de los metabuscadores (como Google) tienen mucho más complicado entender cómo es el contenido de nuestra página y por lo tanto no podrán extraer cosas como párrafos, títulos, etc. puesto que lo único que tendrán será un <div> y dos elementos <script> sin que tengamos ninguna garantía de que el código vaya a ser ejecutado en el crawler.

Nota: el problema que acabamos de describir viene derivado de que las Single Page Application (SPA), es decir, el tipo de aplicaciones que estamos describiendo por lo general no vienen acompañadas de metadatos, no tienen varias urls únicas que identifiquen las diferentes secciones de las aplicaciones lo que en última instancia las hace muy complicadas de indexar.

Nota: tenemos que pensar en que los buscadores y las herramientas que utilizan para indexar la web han mejorado a lo largo de los años el problema que acabamos de describir sigue existiendo en el tiempo.

Otro de los problemas que están asociados a las SPA es que un usuario malicioso de nuestras aplicaciones podría llegar a ejecutar un ataque de Cross-Site Scripting siempre que consiguiese inyectar código JavaScript en nuestra aplicación (por ejemplo, estableciendo un valor de un campo de un formulario como un script de JavaScript que vaya a ser evaluado cuando el formulario vaya a ser enviado).

Y otro de los problemas que pueden aparecer, aunque este es bastante improbable es que puede haber usuario que, por la razón que sea, tengan deshabilitado JavaScript en su navegador y por lo tanto no podrán ejecutar nuestra aplicación por lo que no podrán ver nuestro sitio.

Soluciones

Alguna de las soluciones que podemos adoptar para poder solucionar los problemas que acabamos de describir consisten en hacer lo que se conoce como pre-rendering o Server Side Rendering lo que quiere decir que aunque la interfaz puede seguir utilizando JavaScript para generar la interfaz de usuario (y las interacciones de los usuarios con la aplicación) la carga inicial de la misma (los archivos que se necesitarán) serán creados previamente en el servidor, lo que se traduce en que al navegador llegará un un archivo HTML con código y no uno vacío como se puede ver en la siguiente imagen:

Esta manera de hacer las cosas nos va a traer alguna serie de ventajas como que las páginas así generadas serán fáciles de indexar puesto que ahora los crawlers cuando realicen las peticiones de la página ya van a tener el contenido y por lo tanto van a poder extraer la información que necesiten (párrafos, enlaces, encabezados, etc.), además cada una de estas páginas puede tener una url única (no como el caso de las SPA que todas ellas tienen la misma URL) lo que hacen que sean SEO amigables.

Pero no tenemos que quedarnos exclusivamente ahí porque tenemos que pensar que la carga de nuestra página en el navegador será mucho más rápida puesto que tenemos la interfaz generada desde el backend (lo que significa que no se tiene que generar en el frontend lo que permitirá que sea mucho más rápida).

Tenemos que pensar que SSR es un concepto y no una tecnología por lo que va a poder ser implementada en cualquier framework de frontend aunque es cierto que algunos de estos frameworks lo ponen mucho más fácil que otros. Por ejemplo, estos son algunos de los frameworks modernos que utilizan Server Side Rendering:

  • Así de los frameworks derivados de React tenemos que utilizan SSR: NextJS, Remix, Blitzjs, Redwoodjs y Gatsby.

  • En el caso de Svelte tenemos Svektekit y Routify.

  • En Vue tenemos NuxtJS y Quasar.

  • En VueJS tenemos Solid Start.

Es más tenemos que pensar que podríamos usar SSR tan sólo usando JavaScript gracias a un plugin para Vite llamado Vite SSR.

Lo destacable de todo estos es que todos estos frameworks utilizan NodeJS como entorno de desarrollo por lo que es posible que ejecutemos nuestro código como parte de un servidor de, por ejemplo, Express y ser nosotros los que nos encargásemos de implementar el SSR.

Nota: también es posible implementar SSR en el backend que no utilice JavaScript como podría ser con el uso de Laravel o de Django siempre resulta mucho más complicado de lograrlo entre otras cosas porque no hay tanta información que nos enseñe cómo hacerlo. Así pues una de las estrategias que a veces se utiliza es implemetar el backend en el lenguaje de programación que nosotros queramos (pensemos en por ejemplo Java) y lo que haremos será unir este backend con nuestro frontend a través de un servidor de NodeJS donde sea fácil implementar SSR y que será el que se situará entre el usuario y la API con el fin de facilitar la información asociada a las peticiones de los usuarios.

Nota: con el último esquema que acabamos de definir podríamos estar ante un stack muy versátil puesto que podríamos tener Server Side Rendering (SSR), Client Side Rendering (CSR) e incluso Static Site Generation (SSG).

Resumen

Si en la aplicación backend que estemos desarrollando tenemos contenido que no cambia mucho y lo que nos gustaría es que la carga inicial de la misma fuese muy rápida y que además sea indexable por buscadores (SEO) podemos decidir implementar SSR para esas páginas.

Por ejemplo, los artículos que forman parte de un blog, la página en la que se describe un producto dentro de un ecommerce, sitios de noticias e incluso toda la información que queremos que aparezca en los buscadores siempre deberíamos decantarnos por una estrategia de SSR.

Ahora bien si tenemos contenido que es altamente interactivo (pensamos por ejemplo en un dashboard en el que se estén mostrando información de estadísticas en tiempo real, un feed dentro de una red social o una aplicación de streaming) y el SEO no es tan importante en estos casos es mucho más interesante utilizar CSR. Al final con esto estaremos aliviando la carga de trabajo del servidor puesto que estaremos evitando que tenga que realizar todo el proceso de creación de las diferentes páginas.

De hecho en la mayoría de los frameworks de los que hemos hablado a lo largo de este artículo nos van a ofrecer posibilidades de utilizar CSR o SSR. De cualquier manera la forma más o menos habitual de crear las aplicaciones web es mediante CSR y una vez que se tiene dominado el framework con el que se está trabajando tratar de migrar las diferentes páginas que se están usando como SSR.