Apps web progresivas en sitios de varios orígenes

Desafíos y soluciones alternativas para compilar apps web progresivas en sitios de orígenes múltiples

Demián Rezulli
Demián Renzulli

Información general

En el pasado, existían algunas ventajas sobre el uso de arquitecturas de varios orígenes, pero para las apps web progresivas, ese enfoque presenta muchos desafíos. En particular, la política de mismo origen impone restricciones para compartir elementos como service worker y cachés, permisos y lograr una experiencia independiente en varios orígenes. En este artículo, se describen los usos buenos y malos de varios orígenes, y se explican los desafíos y las soluciones alternativas para compilar aplicaciones web progresivas en sitios de varios orígenes.

Usos correctos e incorrectos de varios orígenes

Existen algunas razones legítimas para que los sitios empleen una arquitectura de orígenes múltiples, principalmente relacionadas con la provisión de un conjunto independiente de aplicaciones web, o para crear experiencias que estén completamente aisladas entre sí. También hay usos que deben evitarse.

Lo bueno

Veamos primero las razones útiles:

  • Localización / idioma: Puede utilizar un dominio de nivel superior con código de país para separar sitios que se publicarán en diferentes países (p.ej., https://www.google.com.ar) o utilizar subdominios para dividir los sitios segmentados a diferentes ubicaciones (p.ej.: https://newyork.craigslist.org) o para ofrecer contenido en un idioma específico (p.ej., https://en.wikipedia.org).

  • Apps web independientes: Uso de diferentes subdominios para proporcionar experiencias cuyo propósito difiera considerablemente del sitio en el origen principal. Por ejemplo, en un sitio de noticias, la app de crucigramas podría entregarse intencionalmente desde https://crosswords.example.com, instalarse y usarse como una AWP independiente, sin tener que compartir ningún recurso o funcionalidad con el sitio web principal.

Lo malo

Si no haces nada de esto, es probable que usar una arquitectura de origen múltiple sea una desventaja a la hora de compilar apps web progresivas.

A pesar de esto, muchos sitios se siguen estructurando de esta manera sin un motivo en particular o por razones "heredadas". Un ejemplo es el uso de subdominios para separar de manera arbitraria partes de un sitio que deberían formar parte de una experiencia unificada.

Por ejemplo, no se recomienda usar los siguientes patrones:

  • Secciones del sitio: Separar las diferentes secciones de un sitio en subdominios. En los sitios de noticias, es común ver la página principal en https://www.example.com, mientras que la sección de deportes se encuentra en https://sports.example.com, la de política en https://politics.example.com, etcétera. En el caso de un sitio de comercio electrónico, puedes usar un elemento como https://category.example.com para categorías de productos, https://product.example.com para páginas de productos, etcétera.

  • Flujo de usuarios: Otro enfoque que no se recomienda es separar diferentes partes más pequeñas del sitio, como las páginas para los flujos de acceso o de compra en subdominios. Por ejemplo, mediante https://login.example.com y https://checkout.example.com.

En los casos en que no sea posible migrar a un origen único, a continuación se incluye una lista de desafíos y (cuando sea posible), soluciones alternativas que se pueden considerar al compilar apps web progresivas.

Desafíos y soluciones alternativas para AWP de distintos orígenes

Cuando se crea un sitio web en varios orígenes, proporcionar una experiencia unificada de AWP es un desafío, principalmente debido a la política del mismo origen, que impone una serie de restricciones. Veámoslos de a uno por vez.

Trabajadores de servicio

El origen de la URL de la secuencia de comandos del service worker debe ser el mismo que el de la página que llama a register(). Esto significa que, por ejemplo, una página ubicada en https://www.example.com no puede llamar a register() con la URL de un service worker en https://section.example.com.

Otra consideración es que un service worker solo puede controlar páginas alojadas en el origen y la ruta de acceso a las que pertenece. Esto significa que, si el service worker se aloja en https://www.example.com, solo puede controlar las URLs de ese origen (según la ruta de acceso definida en el parámetro de alcance), pero no podrá controlar ninguna página de otros subdominios, como las de https://section.example.com.

En este caso, la única solución alternativa es usar varios service worker (uno por origen).

Almacenamiento en caché

El objeto de la caché, indexDB y localStorage también están limitados a un origen único. Esto significa que no es posible acceder a las memorias caché que pertenecen a https://www.example.com, por ejemplo, desde https://www.section.example.com.

Aquí encontrarás algunas de las acciones que puedes realizar para administrar las cachés de forma correcta en situaciones como estas:

  • Aprovecha el almacenamiento en caché del navegador: Siempre se recomienda usar prácticas recomendadas tradicionales del almacenamiento en caché del navegador. Esta técnica proporciona el beneficio adicional de reutilizar recursos almacenados en caché entre los orígenes, lo que no se puede hacer con la caché del service worker. Si deseas conocer las prácticas recomendadas para usar la caché HTTP con service workers, puedes consultar esta publicación.

  • Asegúrate de que la instalación del service worker sea liviana: si realizas el mantenimiento de varios service worker, evita que los usuarios paguen un importe elevado de instalación cada vez que naveguen a un origen nuevo. En otras palabras: solo prealmacena en caché los recursos que son absolutamente necesarios.

Permisos

Los permisos también tienen alcance en los orígenes. Esto significa que, si un usuario otorgó un permiso determinado al https://section.example.com de origen, este no se transferirá a otros orígenes, como https://www.example.com.

Debido a que no hay manera de compartir permisos entre orígenes, la única solución es solicitar permiso en cada uno de los subdominios en los que se requiere una función determinada (p.ej., la ubicación). En el caso de acciones como el web push, puede conservar una cookie para hacer un seguimiento de si el usuario aceptó el permiso en otro subdominio, y así evitar solicitarlo nuevamente.

Instalación

Para instalar una AWP, cada origen debe tener su propio manifiesto con un start_url relativo a sí mismo. Esto significa que un usuario que reciba la solicitud de instalación en un origen determinado (es decir, https://section.example.com) no podrá instalar la AWP con un start_url en otro (es decir, https://www.example.com). En otras palabras, los usuarios que reciban la solicitud de instalación en un subdominio solo podrán instalar AWP de las subpáginas, no de la URL principal de la app.

También existe el problema de que el mismo usuario podría recibir varios mensajes de instalación cuando navega por el sitio, si cada subdominio cumple con los criterios de instalación, y solicita al usuario que instale la AWP.

Para mitigar este problema, puedes asegurarte de que la instrucción se muestre solo en el origen principal. Cuando un usuario visita un subdominio que pasa los criterios de instalación, sucede lo siguiente:

  1. Escuchar evento de beforeinstallprompt
  2. Evita que aparezca el mensaje y llame a event.preventDefault().

De esta manera, te aseguras de que la solicitud no se muestre en partes no deseadas del sitio, mientras puedes seguir mostrándola, por ejemplo, en el origen principal (p.ej., la página principal).

Modo independiente

Mientras navegas en una ventana independiente, el navegador se comportará de manera diferente cuando el usuario salga del alcance establecido por el manifiesto de la AWP. El comportamiento depende de cada versión del navegador y proveedor. Por ejemplo, las versiones más recientes de Chrome abren una pestaña personalizada de Chrome cuando un usuario sale del alcance en el modo independiente.

En la mayoría de los casos, no hay una solución para esto, pero se puede aplicar para pequeñas partes de la experiencia que se alojan en subdominios (por ejemplo, flujos de trabajo de acceso):

  1. La URL nueva, https://login.example.com, podría abrirse en un iframe de pantalla completa.
  2. Una vez que se completa la tarea dentro del iframe (por ejemplo, el proceso de acceso), se puede usar postMessage() para pasar la información resultante del iframe a la página principal.
  3. Como paso final, una vez que la página principal recibe el mensaje, se puede cancelar el registro de los objetos de escucha y se puede quitar el iframe del DOM.

Conclusión

La política del mismo origen impone muchas restricciones a los sitios creados sobre varios orígenes que desean lograr una experiencia de AWP coherente. Por ese motivo, para proporcionar la mejor experiencia a los usuarios, recomendamos no dividir los sitios en orígenes diferentes.

Para los sitios existentes que ya se desarrollaron de esta manera, puede resultar difícil hacer que las AWP de origen múltiple funcionen correctamente, pero ya exploramos algunas posibles soluciones. Cada uno puede tener desventajas, así que usa tu criterio cuando decidas qué enfoque adoptar en tu sitio web.

Cuando evalúes una estrategia a largo plazo o el rediseño del sitio, considera migrar a un origen único, a menos que haya un motivo importante para mantener la arquitectura de varios orígenes.

Agradecemos sus opiniones y sugerencias técnicas: Penny Mclachlan, Paul Covell, Dominick Ng, Alberto Medina, Pete LePage, Joe Medley, Cheney Tsai, Martin Schierle y Andre Bandarra.