x
1

Single-page application



Una single-page application (SPA), o aplicación de página única, es una aplicación web ó un sitio web que cabe en una sola página con el propósito de dar una experiencia más fluida a los usuarios, como si fuera una aplicación de escritorio. En un SPA todos los códigos de HTML, JavaScript, y CSS se cargan una sola vez[1]​, los recursos necesarios se cargan dinámicamente cuando lo requiera la página, normalmente como respuesta a las acciones del usuario. La página no tiene que cargarse de nuevo en ningún punto del proceso y tampoco es necesario transferir a otra página las peticiones, aunque las tecnologías modernas (como el pushState() API del HTML5) permiten la navegabilidad en páginas lógicas dentro de la aplicación. La interacción con las aplicaciones de página única pueden involucrar comunicaciones dinámicas con el servidor web que está detrás.

El término single-page application fue utilizado por Steve Yen en 2005, aunque el concepto ya había sido discutido en el año 2003.[2]​ Stuart Morris escribió una página web de página única slashdotslash.com que tenía las mismas metas y funciones en el año 2002[3]​ En el mismo año Lucas Birdeau, Kevin Hakman, Michael Peachey y Evan Yeh describieron las implementaciones de aplicaciones de página única en la patente estadounidense 8,136,109.[4]

Los navegadores modernos que pueden parsear HTML5 permiten a los desarrolladores cambiar la Interfaz del usuario y las aplicaciones lógicas de los servidores hacia los clientes. Bibliotecas de código abierto soportan la creación de un SPA sin forzar al desarrollador entrar a lo profundo de JavaScript y pelearse con los problemas de la tecnología.

Existen varias técnicas que están disponibles y que pueden hacer que el navegador retenga en una sola página una aplicación que requiere comunicación con el servidor.

Frameworks de JavaScript para los navegadores web como AngularJS, Ember.js, Meteor.js, ExtJS y React han adoptado los principios de SPA.

La técnica más prominente que se está utilizando es asynchronous JavaScript and XML (Ajax).[1]​ Predomina el uso del objeto XMLHttpRequest de JavaScript, otras aplicaciones de AJAX incluyen el uso de IFRAME o elementos de script HTML. Bibliotecas populares como jQuery, normalizan el comportamiento de AJAX entre diferentes navegadores y productores, haciendo que Ajax se haga más popular.

WebSockets son tecnologías de comunicación en tiempo real entre el cliente y el servidor y forma parte de la especificación de HTML5. Es superior a AJAX en términos de rendimiento y simplicidad.[7]

Aunque este método es antiguo, las llamadas asíncronas al servidor también pueden ser logrados utilizando tecnologías de los plug-ins de los navegadores com Silverlight, Flash, o Java applets.

Las peticiones a los servidores normalmente resultan en datos crudos (XML o JSON), o son HTMLs nuevos que están siendo regresados. En los casos donde el HTML regresa como resultado, JavaScript en el cliente actualiza el área parcial de DOM (Document Object Model). Cuando el dato crudo es regresado, el JavaScript de lado del cliente procesa el XML o el JSON para hacer la traducción de los datos crudos a un HTML la cual es usada para actualizar la información del área parcial del DOM.

Un SPA se mueve lógicamente del servidor al cliente. Esto resulta en el rol del servidor web evolucionando en un servicio Web o un API de datos. Este cambio arquitectónico ha sido llamado como "Arquitectura de Servidor Delgado" para remarcar que la complejidad ha sido trasladado del servidor a los clientes, con el argumento de que esto reduce la complejidad del sistema.

El servidor sigue la memoria del estado de los clientes en la página. De esta forma, cuando llega una petición al servidor, los servidores mandan el HTML adecuado y con los cambios concretos hacia los clientes para que puedan transicionar al estado correspondiente (normalmente agregando/borrando/actualizando parte del DOM del cliente). Al mismo tiempo, el servidor de estados se actualiza. La mayor parte de la lógica se ejecuta en el servidor y el HTML también es procesado en el servidor. En algunos casos, el servidor simula el navegador web, recibiendo eventos y realizando cambios delta en el estado del servidor la cual se propaga automáticamente hacia el cliente.

Este enfoque necesita más memoria del servidor y procesamiento del servidor, pero la ventaja es que el modelo de desarrollo es simple porque a) la aplicación está completamente codificado en el servidor, y b) los datos y el estado en el servidor están almacenados en el mismo espacio de la memoria sin que sean necesarios los puentes de comunicación entre el servidor y el cliente.

Es el variante del servidor de estados. En este caso, el cliente envía los datos que representa el estado al servidor, usualmente a través de peticiones de AJAX. Usando estos datos, el servidor puede reconstruir el estado del cliente y determinar la parte de la página que necesita ser modificado, lo genera con los datos necesarios la cual es enviado de vuelta al cliente para que pueda transicionar a otro estado, modificando el árbol de DOM según el acción del cliente que activó la petición.

Este enfoque requiere que se envíe más información al servidor y puede requerir más recursos computacionales por petición para poder reconstruir parcial o completamente la página del cliente en el servidor. Al mismo tiempo, este enfoque es más escalable porque no hay páginas de cliente que se almacenen en el servidor, por lo tanto las peticiones AJAX pueden transferirse a otro nodo del servidor sin la necesidad de compartir los datos de la sesión.

Algunos SPA's pueden ejecutarse utilizando los archivos locales a través del esquema URI. Esto permite a los usuarios descargar un SPA del servidor y ejecutar el archivo desde un almacenamiento local, sin tener que depender de la conectividad al servidor. Si algún SPA requiere guardar y actualizar los datos, debe utilizar almacenamiento web, el cual está basado en los navegadores; Estas aplicaciones se beneficiaron con los avances de HTML5 respecto a este.[8]

Como el SPA es una evolución lejos del modelo "stateless page-redraw" en la cual se basaron para diseñar a los navegadores, algunos cambios han surgido. Cada uno de estos problemas tiene una solución efectiva[9]​ con:

Por la falta de ejecución de JavaScript en los crawlers de los motores de Búsqueda populares[14][15]​ SEO (Search engine optimization) ha tenido problemas para páginas públicas que adoptaron el modelo SPA.[16]

Google hace el crawling de los URLs que contienen fragmentos de hash empezando por#!.[17]​ Esto permite el uso de fragmentos de hash dentro de un solo URL de un SPA. Los comportamientos especiales deben ser implementados por el sitio de SPA para permitir la extracción de metadatos relevantes para el crawler del motor de la búsqueda. Para algunos motores de búsqueda que no soportan la esquema de hash en URL, los URL en hash del SPA permanecen invisibles.

Alternativamente, las aplicaciones pueden procesar la primera página durante el cargado en el servidor y las actualizaciones subsecuentes en el cliente. Esto es tradicionalmente difícil, porque el código de rendering podría tener que ser escrito en otro lenguaje o framework en el servidor y en el cliente. Usando plantillas sin lógica o usando la compilación cruzada de un lenguaje a otro, o usando el mismo lenguaje en el servidor y en el cliente podría ayudar a incrementar la cantidad de código que puede ser compartido.

Como la compatibilidad de SEO no es trivial en los SPAs, no es conveniente utilizar SPAs en los contextos en donde la indexación para los motores de búsqueda son un requisito. Los casos de uso incluyen aplicaciones que manejan datos privados y escondidos atrás de un sistema de autentificación. En los casos en donde estas aplicaciones son productos de consumidores, se utilizan modelos como "redibujado de página" como en las páginas de publicidad donde suficiente metadato de la aplicación aparece en el motor de búsqueda. Blogs, foros de soporte, y otros artefactos de redibujado también se juntan alrededor del SPA donde los motores puedan hacer búsquedas con los términos relevantes.

Otro enfoque utilizado por los servidores de framwork Server-centric que es como ItsNat que se basa en Java para el render de los hypertextos en el servidor utilizando la misma tecnología de lenguaje y plantilla. En el enfoque, el servidor conoce con precisión el estado de DOM del cliente, y cualquier cambio o actualización requerida es generado en el servidor y luego transportado por AJAX, el mismo JavaScript cambia de estado al cliente ejecutando los métodos de DOM. Los desarrolladores pueden decidir en qué estados de página son capaces de ser leídos por el crawler para el SEO y deben poder generar el estado requerido en tiempo de cargado y en HTML en lugar de JavaScript. En casos de ItsNat, esto es automático ya que ItsNat mantiene el árbol de DOM del cliente en el servidor como W3C DOM de Java; y procesando el árbol en el servidor genera HTML plano en tiempo de cargado y los DOMs para las peticiones de AJAX. Esta dualidad es muy importante para SEO porque los desarrolladores pueden construir con el mismo código de Java y plantillas basados en HTML en el servidor; en el tiempo de cargado, el HTML convencional es generado por ItsNat haciendo que el DOM sea compatible con SEO. Desde la versión 1.3,[18]​ ItsNat provee un modo sin estados, en donde el DOM del cliente no se almacena en el servidor, ya que en ese modo el DOM del estado es parcialmente o completamente reconstruido en el servidor cuando se procesan las peticiones AJAX y requiere que el cliente envíe los datos completos de DOM de su estado; el modo sin estados también puede ser compatible con SEO porque esa compatibilidad sucede en el tiempo de cargado de la página inicial sin haber sido afectado por los modos de estado.

Hay varias alternativas para hacer que la página sea capaz de crawling. Ellas involucran la creación de páginas HTML separadas que hagan el espejo de los contenidos de SPA. El servidor podría crear una versión basada en HTML del sitio y entregarlo a los crawlers, o también es posible usar un navegador sin cabeza como PhantomJS para ejecutar aplicaciones de JavaScript y mostrar el resultado en HTML.

Ambas técnicas requieren de trabajos manuales y pueden terminar siendo un dolor de cabeza para el mantenimiento de las páginas complejas. También hay varias trampas de SEO. si el HTML generado del servidor es muy diferente al SPA del contenido, entonces la página será penalizado. Corriendo PhantomJS para mostrar el HTML puede alentar la velocidad de la respuesta de las páginas la cual los motores de búsqueda, en especial Google, lo baja del ranking.[19]

Una forma de incrementar la cantidad de código que deben ser compartidos entre los servidores y los clientes es usar las plantillas sin lógica como Mustache o Handlebars. Estas plantillas pueden interpretarse en lenguajes diferentes, como Ruby en el servidor y JavaScript en el cliente, aunque para compartir las plantillas se necesita duplicar la lógica de negocio utilizada para elegir las plantillas correctas y llenarlas con datos. Interpretar esas plantillas puede impactar negativamente en rendimiento cuando solamente se está actualizando una pequeña parte de la página, así como un valor de la entrada de texto dentro de una plantilla muy grande. Reemplazar una plantilla completa también podría molestar la selección del usuario o la posición del cursor, mientras que solamente actualizar el dato no lo afectaría. Para evitar estos problemas las aplicaciones utilizan data binding o manipulación granular del DOM para solamente actualizar las partes apropiadas de la página en lugar de redibujar toda la plantilla.

Por la propia definición del SPA, una aplicación de página única rompe el diseño de los navegadores que utiliza los botones adelante/atrás. Esto presenta un obstáculo en la usabilidad cuando el usuario aprieta el botón de atrás, se estaría esperando la pantalla anterior de SPA pero en lugar de eso abriría la página anterior al que accedió antes de entrar a la aplicación SPA.

La solución tradicional para SPA ha sido cambiar el URL del navegador con el hash que identifica el fragmento de acuerdo al estado actual de la pantalla. Esto puede ser logrado a través de JavaScript, y causa que se construyan eventos en el historial de URL del navegador. Mientras que SPA sea capaz de redibujar la misma pantalla con la información contenida en el hash del URL el comportamiento esperado se mantiene.

Para resolver esto de otra forma, las especificaciones de HTML5 introdujeron los métodos pushState y replaceState que proveen un acceso programático al URL actual y al historial del navegador.

Las herramientas de análisis como Google Analytics dependen mucho de las páginas que se cargan en un navegador iniciado por un cambio de URL. En un SPA, después de que la primera página se carga, la aplicación pasa a manejar internamente todas las páginas siguientes y los cambios en el contenido, así que el navegador nunca activa una recarga completa de la página, ni se agregan entradas a la historia del navegador. Es por ello que la herramienta de análisis en cuestión no tiene ni idea de quién está haciendo qué en esa página.

Es posible agregar los eventos de carga a un sitio SPA utilizando las funciones de historial de HTML5; esto ayuda a integrar las analíticas. La dificultad está en manejarlos y asegurar que todo sea rastreado con precisión. Esto involucra revisar reportes faltantes y entradas dobles. La buena noticia es que no hay necesidad de construir todo desde cero. Hay varias integraciones de analíticas de código abierto para Angular que están disponibles en la red, localizando la mayoría de los proveedores de analíticas. Los desarrolladores deben integrarlos en la aplicación y asegurarse de que todo esté funcionando correctamente, pero no hay necesidad de empezar todo de cero.[19]

Los SPAs tiene una velocidad de carga más lenta que las aplicaciones basadas en el servidor. Esto es porque la primera descarga tiene de traer a todos los frameworks y el código de la aplicación antes de dibujar lo que se requiere para el navegador de HTML. Una aplicación basada en el servidor solamente necesita enviar el HTML que se requiere al navegador, reduciendo la latencia y el tiempo de descarga.

Hay varias formas de incrementar la velocidad de un SPA, así como módulos de lazy-loading que los descarga cuando se necesita. Pero no es posible alejarse del hecho que los SPAs tienen que descargar los frameworks, el código de la aplicación y probablemente el API para los datos antes de mostrar algo en el navegador.[19]​ Esto es algo así como el escenario de "Págame ahora o págame después". La pregunta del rendimiento y el tiempo de espera permanece en la decisión del desarrollador.

Un SPA se carga completo durante el cargado de la página inicial y luego las regiones se reemplazan o se actualizan con los fragmentos de las nuevas páginas según petición del servidor. Para evitar descargas excesivas de características inutilizadas, un SPA descarga progresivamente las características cuando se necesiten, pueden ser fragmentos de las páginas o módulos completos de la pantalla.

De esta forma existe una analogía entre los "estados" de un SPA y las "páginas" de un sitio web tradicional. Como la navegación de estados en la misma página es análogo a la navegación de las páginas, en teoría, cualquier página de sitio web podría convertirse a un sitio de página única reemplazando las páginas solamente en las partes donde se generen un cambio. El enfoque de SPA en la página web es similar a Single Document Interface (SDI), que es una técnica para las aplicaciones de escritorio.



Escribe un comentario o lo que quieras sobre Single-page application (directo, no tienes que registrarte)


Comentarios
(de más nuevos a más antiguos)


Aún no hay comentarios, ¡deja el primero!