Experiencia práctica con portales: navegación sin interrupciones en la Web

Obtén información sobre cómo la API de portales propuesta puede mejorar tu UX de navegación.

Yusuke Utsunomiya
Ysuke Utsunomiya

Asegurarse de que tus páginas se carguen rápido es clave para ofrecer una buena experiencia del usuario. Sin embargo, un área que solemos pasar por alto son las transiciones de páginas, es decir, lo que nuestros usuarios ven cuando alternan entre páginas.

El objetivo de una nueva propuesta de API de plataforma web llamada Portals es optimizar la experiencia a medida que los usuarios navegan por tu sitio.

Observa los portales en acción:

Incorporaciones y navegación sin inconvenientes con portales. Creado por Adam Argyle.

Qué habilitan los portales

Las aplicaciones de una sola página (SPA) ofrecen transiciones atractivas, pero su compilación implica una mayor complejidad. Las aplicaciones de varias páginas (MPA) son mucho más fáciles de crear, pero terminan con pantallas en blanco entre las páginas.

Los portales ofrecen lo mejor de ambos mundos: la baja complejidad de una MPA con las transiciones perfectas de una SPA. Piensa en ellas como <iframe>, ya que permiten la incorporación, pero a diferencia de <iframe>, también incluyen funciones para navegar a su contenido.

Ver para creer: primero mira lo que mostramos en la Chrome Dev Summit 2018:

Con las navegaciones clásicas, los usuarios tienen que esperar con la pantalla en blanco hasta que el navegador termine de renderizar el destino. Con los portales, los usuarios pueden experimentar una animación, mientras que <portal> renderiza previamente el contenido y crea una experiencia de navegación fluida.

Antes de los portales, se podría haber renderizado otra página con un <iframe>. También podríamos haber agregado animaciones para mover el marco por la página. Sin embargo, el objeto <iframe> no te permitirá navegar a su contenido. Los portales reducen esta brecha, lo que permite casos de uso interesantes.

Prueba los portales

Habilitación mediante about://flags

Para probar los portales en Chrome 85 y versiones posteriores, gira una bandera experimental:

  • Habilita la marca about://flags/#enable-portals para las navegaciones del mismo origen.
  • Para probar las navegaciones de origen cruzado, además, habilita la marca about://flags/#enable-portals-cross-origin.

Durante esta fase inicial del experimento de Portals, también recomendamos usar un directorio de datos del usuario completamente independiente para tus pruebas mediante la configuración de la marca de línea de comandos --user-data-dir. Una vez que los portales estén habilitados, confirma en Herramientas para desarrolladores que tienes el nuevo HTMLPortalElement brillante.

Captura de pantalla de la consola de Herramientas para desarrolladores que muestra el HTMLPortalElement

Implementar portales

Veamos un ejemplo de implementación básica.

// Create a portal with the wikipedia page, and embed it
// (like an iframe). You can also use the <portal> tag instead.
portal = document.createElement('portal');
portal.src = 'https://en.wikipedia.org/wiki/World_Wide_Web';
portal.style = '...';
document.body.appendChild(portal);

// When the user touches the preview (embedded portal):
// do fancy animation, e.g. expand …
// and finish by doing the actual transition.
// For the sake of simplicity, this snippet will navigate
// on the `onload` event of the Portals element.
portal.addEventListener('load', (evt) => {
   portal.activate();
});

Es así de sencillo. Prueba este código en la consola de Herramientas para desarrolladores; se debería abrir la página de Wikipedia.

GIF de demostración del estilo del portal de vista previa

Si quisieras crear algo como lo que mostramos en la Chrome Dev Summit y que funciona igual que la demostración anterior, te interesará el siguiente fragmento.

// Adding some styles with transitions
const style = document.createElement('style');
style.innerHTML = `
  portal {
    position:fixed;
    width: 100%;
    height: 100%;
    opacity: 0;
    box-shadow: 0 0 20px 10px #999;
    transform: scale(0.4);
    transform-origin: bottom left;
    bottom: 20px;
    left: 20px;
    animation-name: fade-in;
    animation-duration: 1s;
    animation-delay: 2s;
    animation-fill-mode: forwards;
  }
  .portal-transition {
    transition: transform 0.4s;
  }
  @media (prefers-reduced-motion: reduce) {
    .portal-transition {
      transition: transform 0.001s;
    }
  }
  .portal-reveal {
    transform: scale(1.0) translateX(-20px) translateY(20px);
  }
  @keyframes fade-in {
    0%   { opacity: 0; }
    100% { opacity: 1; }
  }
`;
const portal = document.createElement('portal');
// Let's navigate into the WICG Portals spec page
portal.src = 'https://wicg.github.io/portals/';
// Add a class that defines the transition. Consider using
// `prefers-reduced-motion` media query to control the animation.
// https://developers.google.com/web/updates/2019/03/prefers-reduced-motion
portal.classList.add('portal-transition');
portal.addEventListener('click', (evt) => {
  // Animate the portal once user interacts
  portal.classList.add('portal-reveal');
});
portal.addEventListener('transitionend', (evt) => {
  if (evt.propertyName == 'transform') {
    // Activate the portal once the transition has completed
    portal.activate();
  }
});
document.body.append(style, portal);

También es fácil realizar una detección de funciones para mejorar progresivamente un sitio web mediante portales.

if ('HTMLPortalElement' in window) {
  // If this is a platform that have Portals...
  const portal = document.createElement('portal');
  ...
}

Si quieres experimentar con rapidez cómo son los portales, intenta usar uskay-portals-demo.glitch.me. Asegúrese de acceder a ella con Chrome 85 o versiones posteriores, y active la marca experimental.

  1. Ingresa la URL de la que quieres obtener una vista previa.
  2. La página se incorporará como un elemento <portal>.
  3. Haz clic en la vista previa.
  4. La vista previa se activará después de una animación.

GIF de demostración de la falla de uso de portales

Consulta las especificaciones

Estamos analizando la especificación de los portales en el Web Incubation Community Group (WICG). Para ponerte al día rápidamente, observa algunas de las situaciones clave. Estas son las tres funciones importantes con las que debes familiarizarte:

  • El elemento <portal>: El elemento HTML en sí. La API es muy sencilla. Consiste en el atributo src, la función activate y una interfaz para mensajería (postMessage). activate toma un argumento opcional para pasar datos a <portal> cuando se activa.
  • La interfaz portalHost: Agrega un objeto portalHost al objeto window. Esto te permite comprobar si la página está incorporada como un elemento <portal>. También proporciona una interfaz para enviar mensajes (postMessage) al host.
  • La interfaz de PortalActivateEvent: es un evento que se activa cuando se activa <portal>. Hay una función ordenada llamada adoptPredecessor que puedes usar para recuperar la página anterior como un elemento <portal>. Esto te permite crear navegaciones fluidas y experiencias compuestas entre dos páginas.

Veamos más allá del patrón de uso básico. A continuación, no se incluye una lista exhaustiva de lo que puedes lograr con los portales junto con el código de muestra.

Personaliza el estilo cuando se incorpora como un elemento <portal>

// Detect whether this page is hosted in a portal
if (window.portalHost) {
  // Customize the UI when being embedded as a portal
}

Mensajes entre el elemento <portal> y portalHost

// Send message to the portal element
const portal = document.querySelector('portal');
portal.postMessage({someKey: someValue}, ORIGIN);

// Receive message via window.portalHost
window.portalHost.addEventListener('message', (evt) => {
  const data = evt.data.someKey;
  // handle the event
});

Cómo activar el elemento <portal> y recibir el evento portalactivate

// You can optionally add data to the argument of the activate function
portal.activate({data: {somekey: 'somevalue'}});

// The portal content will receive the portalactivate event
// when the activate happens
window.addEventListener('portalactivate', (evt) => {
  // Data available as evt.data
  const data = evt.data;
});

Cómo recuperar el predecesor

// Listen to the portalactivate event
window.addEventListener('portalactivate', (evt) => {
  // ... and creatively use the predecessor
  const portal = evt.adoptPredecessor();
  document.querySelector('someElm').appendChild(portal);
});

Saber que tu página fue adoptada como predecesora

// The activate function returns a Promise.
// When the promise resolves, it means that the portal has been activated.
// If this document was adopted by it, then window.portalHost will exist.
portal.activate().then(() => {
  // Check if this document was adopted into a portal element.
  if (window.portalHost) {
    // You can start communicating with the portal element
    // i.e. listen to messages
    window.portalHost.addEventListener('message', (evt) => {
      // handle the event
    });
  }
});

Si combinas todas las funciones compatibles con los portales, puedes crear experiencias del usuario muy sofisticadas. Por ejemplo, la siguiente demostración demuestra cómo los portales pueden brindar una experiencia del usuario sin inconvenientes entre un sitio web y el contenido incorporado de terceros.

Casos de uso y planes

Esperamos que te haya gustado este breve recorrido por los portales. Estamos ansiosos por ver tus sensaciones. Por ejemplo, te recomendamos que comiences a usar portales para navegaciones no triviales, como renderizar previamente la página de tu producto más vendido desde una página de fichas de categorías de productos.

Otro aspecto importante que debes saber es que los portales se pueden usar en las navegaciones de origen cruzado, al igual que en un <iframe>. Por lo tanto, si tienes varios sitios web que se comparan entre sí, también puedes utilizar portales para crear navegaciones perfectas entre dos sitios web diferentes. Este caso de uso de origen cruzado es muy exclusivo de los portales y hasta puede mejorar la experiencia del usuario de las SPA.

Recibimos comentarios

Los portales están listos para la experimentación en Chrome 85 y versiones posteriores. Los comentarios de la comunidad son fundamentales para el diseño de nuevas APIs, así que pruébalas y danos tu opinión. Si quieres solicitar funciones o enviar comentarios, visita el repositorio de GitHub de WICG.