Portali pratici: navigazione sul Web senza interruzioni

Scopri in che modo l'API Portals proposta può migliorare l'esperienza utente di navigazione.

Yusuke Utsunomiya
Yusuke Utsunomiya

Assicurarsi che le pagine vengano caricate rapidamente è fondamentale per offrire una buona esperienza utente. Un'area che spesso trascuriamo sono le transizioni di pagina, ovvero ciò che i nostri utenti vedono quando passano da una pagina all'altra.

Una nuova proposta relativa all'API per la piattaforma web chiamata Portals mira a aiutarti a tal fine semplificando l'esperienza degli utenti sul tuo sito.

Guarda i portali in azione:

Embedding e navigazione fluidi con i portali. Creato da Adam Argyle.

Cosa abilitano i portali

Le applicazioni a pagina singola (SPA) offrono transizioni piacevoli, ma la loro creazione è più complessa. Le applicazioni multipagina (MPA) sono molto più facili da creare, ma alla fine hai schermate vuote tra le pagine.

I portali offrono il meglio di entrambi i mondi: la bassa complessità di un MPA con le transizioni senza interruzioni di un'SPA. Pensa a loro come a un <iframe> in quanto consentono l'embedding, ma, a differenza di un <iframe>, includono anche funzionalità per accedere ai loro contenuti.

I fatti parlano da soli: innanzitutto, dai un'occhiata a cosa abbiamo mostrato al Chrome Dev Summit 2018:

Con le navigazioni classiche, gli utenti devono attendere con una schermata vuota fino a quando il browser non ha completato il rendering della destinazione. Con i portali, gli utenti possono usufruire di un'animazione, mentre <portal> esegue il pre-rendering dei contenuti e crea un'esperienza di navigazione fluida.

Prima dei portali, avremmo potuto visualizzare un'altra pagina utilizzando un <iframe>. Avremmo anche potuto aggiungere animazioni per spostare il frame all'interno della pagina. ma non ti consente di accedere ai contenuti. I portali colmano questa lacuna, consentendo casi d'uso interessanti.

Prova i Portal

Attivazione tramite about://flags

Prova i portali in Chrome 85 e versioni successive capovolgendo un flag sperimentale:

  • Attiva il flag about://flags/#enable-portals per le navigazioni con la stessa origine.
  • Per testare le navigazioni multiorigine, abilita anche il flag about://flags/#enable-portals-cross-origin.

In questa prima fase dell'esperimento sui portali, ti consigliamo inoltre di utilizzare una directory di dati utente completamente separata per i test impostando il flag della riga di comando --user-data-dir. Una volta attivati i portali, verifica in DevTools che sia presente il nuovo HTMLPortalElement.

Uno screenshot della console DevTools che mostra HTMLPortalElement

Implementare i portali

Vediamo un esempio di implementazione di base.

// 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();
});

È semplicissimo. Prova questo codice nella console di DevTools. Dovresti aprire la pagina di Wikipedia.

Una GIF della demo dello stile del portale di anteprima

Se vuoi realizzare qualcosa come quello che abbiamo mostrato al Chrome Dev Summit e che funzioni come la demo qui sopra, il seguente snippet sarà di tuo interesse.

// 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);

È inoltre facile eseguire il rilevamento delle funzionalità per migliorare progressivamente un sito web utilizzando i portali.

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

Se vuoi provare rapidamente l'esperienza dei portali, prova a usare uskay-portals-demo.glitch.me. Assicurati di accedervi con Chrome 85 o versioni successive e di attivare il flag sperimentale.

  1. Inserisci un URL di cui vuoi visualizzare l'anteprima.
  2. La pagina verrà incorporata come elemento <portal>.
  3. Fai clic sull'anteprima.
  4. L'anteprima verrà attivata dopo un'animazione.

Una GIF che mostra l&#39;uso della demo sugli glitch con i Portali

Consulta le specifiche

Stiamo discutendo attivamente della specifica dei portali nel gruppo della community Web Incubation (WICG). Per iniziare rapidamente, dai un'occhiata ad alcuni degli scenari chiave. Di seguito sono riportate le tre funzionalità importanti con cui prendere dimestichezza:

  • L'elemento <portal>: l'elemento HTML stesso. L'API è molto semplice. È costituito dall'attributo src, dalla funzione activate e da un'interfaccia per la messaggistica (postMessage). activate accetta un argomento facoltativo per passare i dati a <portal> al momento dell'attivazione.
  • Interfaccia portalHost: aggiunge un oggetto portalHost all'oggetto window. In questo modo puoi verificare se la pagina è incorporata come elemento <portal>. Fornisce inoltre un'interfaccia per l'invio di messaggi (postMessage) all'host.
  • Interfaccia PortalActivateEvent: un evento che viene attivato quando <portal> viene attivato. Esiste una funzione interessante chiamata adoptPredecessor che puoi utilizzare per recuperare la pagina precedente come elemento <portal>. In questo modo, puoi creare navigazioni fluide ed esperienze composte tra due pagine.

Andiamo oltre il pattern di utilizzo di base. Di seguito è riportato un elenco non esaustivo di cosa puoi fare con i portali, oltre al codice di esempio.

Personalizzare lo stile quando è incorporato come elemento <portal>

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

Messaggistica tra l'elemento <portal> e 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
});

Attivazione dell'elemento <portal> e ricezione dell'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;
});

Recupero del predecessore

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

Sapere che la tua pagina è stata adottata come predecessore

// 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
    });
  }
});

Combinando tutte le funzionalità supportate da Portali, puoi creare esperienze utente davvero straordinarie. Ad esempio, la demo riportata di seguito mostra come i portali possono offrire un'esperienza utente fluida tra un sito web e i contenuti incorporati di terze parti.

Casi d'uso e piani

Speriamo che questo breve tour dei Portal ti sia piaciuto. Non vediamo l'ora di scoprire cosa creerai. Ad esempio, potresti voler iniziare a utilizzare i portali per navigazioni non banali, come il pre-rendering della pagina dei tuoi prodotti più venduti da una pagina di schede di categorie di prodotti.

Un'altra cosa importante da sapere è che i portali possono essere utilizzati nelle navigazioni cross-origin, proprio come un <iframe>. Pertanto, se hai più siti web che fanno riferimento l'uno all'altro, puoi utilizzare anche i portali per creare una navigazione senza interruzioni tra due siti web diversi. Questo caso d'uso cross-origin è molto specifico per i portali e può persino migliorare l'esperienza utente delle SPA.

I feedback sono ben accetti

I portali sono pronti per la sperimentazione in Chrome 85 e versioni successive. I feedback della community sono fondamentali per la progettazione di nuove API, quindi provale e dicci cosa ne pensi. Se hai richieste di funzionalità o feedback, visita il repository GitHub di WICG.