Apps web progresivas en sitios de varios orígenes

Desafíos y soluciones alternativas para compilar apps web progresivas en sitios de varios orígenes.

Demián Renzulli
Demián Renzulli

Información general

En el pasado, el uso de arquitecturas de origen múltiple tenía algunas ventajas, pero en el caso de las apps web progresivas, ese enfoque plantea muchos desafíos. En particular, la política del mismo origen impone restricciones para compartir elementos como service workers, cachés, permisos y lograr una experiencia independiente en varios orígenes. En este artículo, se describen los usos buenos y malos de múltiples orígenes, y se explican los desafíos y las soluciones para compilar apps web progresivas en sitios de varios orígenes.

Usos buenos y malos de múltiples orígenes

Existen algunos motivos legítimos para que los sitios empleen una arquitectura de origen múltiple, principalmente relacionada con la provisión de un conjunto independiente de aplicaciones web o con el objetivo de crear experiencias completamente aisladas entre sí. También hay usos que se deben evitar.

Lo bueno

Veamos primero las razones útiles:

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

  • Aplicaciones web independientes: Uso de diferentes subdominios para brindar experiencias cuyo propósito difiere considerablemente del sitio en el origen principal. Por ejemplo, en un sitio de noticias, la app web de crucigramas se podría publicar intencionalmente desde https://crosswords.example.com, además de 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 realizas ninguna de estas acciones, 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 siguen estructurándose de esta manera sin ningún motivo en particular o por motivos "heredados". Un ejemplo es el uso de subdominios para separar de forma arbitraria partes de un sitio que deberían formar parte de una experiencia unificada.

Los siguientes patrones, por ejemplo, no son muy recomendables:

  • 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 política en https://politics.example.com, etc. En el caso de un sitio de comercio electrónico, usar algo como https://category.example.com para categorías de producto, https://product.example.com para páginas de productos, etcétera

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

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

Desafíos y soluciones alternativas para las AWP de diferentes orígenes

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

Trabajadores de servicio

El origen de la URL de la secuencia de comandos del service worker debe ser el mismo que el origen de la página que llama a register(). Esto significa que, por ejemplo, una página en https://www.example.com no puede llamar a register() con una URL de 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 la que pertenece. Esto significa que, si el service worker está alojado en https://www.example.com, solo podrá controlar las URLs de ese origen (según la ruta definida en el parámetro de alcance), pero no controlará ninguna página de otros subdominios, como, por ejemplo, las de https://section.example.com.

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

Almacenar en caché

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

Aquí encontrarás algunas sugerencias para administrar las cachés de forma correcta en situaciones como esta:

  • Aprovechar el almacenamiento en caché del navegador: Siempre se recomienda usar las prácticas recomendadas tradicionales del almacenamiento en caché del navegador. Esta técnica ofrece el beneficio adicional de reutilizar recursos almacenados en caché en distintos 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.

  • Haz que la instalación de service worker sea liviana: Si mantienes varios service workers, evita que los usuarios paguen un gran costo de instalación cada vez que naveguen a un nuevo origen. En otras palabras: solo los recursos prealmacenados en caché que son absolutamente necesarios.

Permisos

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

Como no hay forma de compartir permisos entre orígenes, la única solución en este caso es solicitar permiso en cada subdominio en el que se requiera una función determinada (p.ej., ubicación). Por ejemplo, en el caso del envío web, puedes mantener una cookie para hacer un seguimiento de si el usuario aceptó el permiso en otro subdominio, y así evitar solicitarlo de nuevo.

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 para las subpáginas, no para la URL principal de la app.

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

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

  1. Escucha el evento beforeinstallprompt.
  2. Evita que aparezca el mensaje llamando a event.preventDefault().

De esa manera, te aseguras de que el mensaje no aparezca en partes no deseadas del sitio, mientras puedes seguir mostrándolo, 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 proveedor y versión del navegador. Por ejemplo, las versiones más recientes de Chrome abren una pestaña personalizada de Chrome cuando un usuario sale del alcance en modo independiente.

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

  1. Es posible que la URL nueva, https://login.example.com, se abra dentro de 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 superior.
  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, finalmente, quitar el iframe del DOM.

Conclusión

La política del mismo origen impone muchas restricciones para los sitios compilados sobre varios orígenes que desean lograr una experiencia de AWP coherente. Por esa razón, para proporcionar la mejor experiencia a los usuarios, te recomendamos que no dividas los sitios en diferentes orígenes.

En el caso de los sitios existentes que ya están compilados de esta manera, puede ser difícil hacer que las AWP de origen múltiple funcionen correctamente, pero exploramos algunas posibles soluciones alternativas. Cada uno puede tener ventajas y desventajas, por lo que debe ser útil cuando decida qué enfoque utilizar en su sitio web.

Cuando evalúes una estrategia a largo plazo o rediseñar el sitio, considera migrar a un origen único, a menos que haya una razón importante para mantener la arquitectura de origen múltiple.

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.