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

Publicado el 19 de agosto de 2019

En el pasado, las arquitecturas de múltiples orígenes tenían algunas ventajas. En el caso de las apps web progresivas, ese enfoque presenta muchos desafíos. En particular, la política del mismo origen impone restricciones para compartir elementos como service workers y cachés, permisos y para lograr una experiencia independiente en varios orígenes.

Descubre los usos correctos e incorrectos de varios orígenes, y explica los desafíos y las soluciones alternativas para compilar apps web progresivas en sitios de varios orígenes.

Usos correctos e incorrectos de varios orígenes

Existen algunos motivos legítimos para que los sitios empleen una arquitectura de varios orígenes, principalmente relacionados con proporcionar un conjunto independiente de aplicaciones web o crear experiencias que estén completamente aisladas entre sí. También hay usos que se deben evitar.

Lo bueno

Primero, consulta los motivos útiles:

  • Localización o idioma: Usar 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 usar subdominios para dividir los sitios segmentados para diferentes ubicaciones (p.ej.: https://newyork.craigslist.org) o para ofrecer contenido en un idioma específico (p.ej., https://en.wikipedia.org).

  • Aplicaciones web independientes: Se usan diferentes subdominios para proporcionar experiencias cuyo propósito difiere considerablemente del sitio en el origen principal. Por ejemplo, en un sitio de noticias, la app web de crucigramas podría entregarse de forma intencional desde https://crosswords.example.com, y se podría instalar y usar como una AWP independiente, sin tener que compartir ningún recurso ni funcionalidad con el sitio web principal.

Lo malo

Si no haces ninguna de estas cosas, es probable que usar una arquitectura de varios orígenes sea una desventaja cuando compiles apps web progresivas.

A pesar de esto, muchos sitios siguen estructurándose de esta manera sin un motivo en particular o por razones de "legado". Un ejemplo es usar subdominios para separar de forma arbitraria partes de un sitio que deberían ser parte de una experiencia unificada.

Por ejemplo, se desaconsejan los siguientes patrones:

  • Secciones del sitio: Separar 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, usa algo como https://category.example.com para las categorías de productos, https://product.example.com para las 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, con https://login.example.com y https://checkout.example.com.

En los casos en los que no es posible migrar a un solo origen, a continuación, se incluye una lista de desafíos y, cuando es posible, soluciones alternativas que se pueden considerar cuando se compilan apps web progresivas.

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

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

Service workers

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 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 las páginas alojadas en el origen y la ruta de acceso a los 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 controlará ninguna página en otros subdominios, como, por ejemplo, los de https://section.example.com.

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

Almacenamiento en caché

El objeto Cache, indexedDB y localStorage también están restringidos a un solo 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.

Estas son algunas de las acciones que puedes realizar para administrar las cachés de forma correcta en situaciones como esta:

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

  • Mantén la instalación de service workers ligera: Si mantienes varios service workers, evita que los usuarios paguen un costo de instalación alto cada vez que naveguen a un origen nuevo. En otras palabras, solo almacena en caché previa los recursos que sean 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, 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 aquí es solicitar permiso en cada uno de los subdominios en los que se requiere una función determinada (p.ej., la ubicación). Para funciones como las notificaciones push web, puedes mantener una cookie para hacer un seguimiento de si el usuario aceptó el permiso en otro subdominio y evitar volver a solicitarlo.

Instalación

Para instalar una PWA, cada origen debe tener su propio manifiesto con un start_url que sea relativo a sí mismo. Esto significa que un usuario que reciba el mensaje de instalación en un origen determinado (p. ej., https://section.example.com) no podrá instalar la AWP con un start_url en otro diferente (p. ej., https://www.example.com). En otras palabras, los usuarios que reciban el mensaje 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 varios mensajes de instalación cuando navega por el sitio, si cada subdominio cumple con los criterios de instalación y le solicita al usuario que instale la AWP.

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

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

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

Modo independiente

Cuando se navega en una ventana independiente, el navegador se comportará de manera diferente cuando el usuario se mueva fuera del alcance establecido por el manifiesto de la AWP. El comportamiento depende de la versión y el proveedor de cada navegador. 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 una solución alternativa para pequeñas partes de la experiencia que se alojan en subdominios (por ejemplo, flujos de trabajo de acceso):

  1. La nueva URL, https://login.example.com, podría abrirse 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 cualquier 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, por último, quitar el iframe del DOM.

Conclusión

La política del mismo origen impone muchas restricciones para los sitios creados sobre múltiples orígenes que desean lograr una experiencia de AWP coherente. Por ese motivo, para brindar 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 se crearon de esta manera, puede ser difícil hacer que las PWA de varios orígenes funcionen correctamente, pero exploramos algunas posibles soluciones alternativas. Cada una puede tener ventajas y desventajas, por lo que debes usar tu criterio para decidir qué enfoque adoptar en tu sitio web.

Cuando evalúes una estrategia a largo plazo o un 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 especialmente a Penny Mclachlan, Paul Covell, Dominick Ng, Alberto Medina, Pete LePage, Joe Medley, Cheney Tsai, Martin Schierle y Andre Bandarra por sus revisiones técnicas y sugerencias.