Estensioni di Chrome: estensione dell'API per supportare la navigazione istantanea

Dave Tapuska
Dave Tapuska

TL;DR: L'API Extensions è stata aggiornata per supportare la cache back-forward, precaricando le navigazioni. Scopri di più nella sezione seguente.

Chrome si sta adoperando per rendere la navigazione veloce. Tecnologie di navigazione istantanea come la cache back/forward (fornita su computer in Chrome 96) e le regole di speculazione (fornite in Chrome 103) migliorano l'esperienza sia nel futuro che nel passato. In questo post esploreremo gli aggiornamenti che abbiamo apportato alle API delle estensioni del browser per adeguarsi a questi nuovi flussi di lavoro.

Comprendere i tipi di pagine

Prima dell'introduzione della cache back-forward e del prerendering, una singola scheda aveva una sola pagina attiva. Era sempre quella che era visibile. Se un utente torna alla pagina precedente, la pagina attiva viene eliminata (Pagina B) mentre la pagina precedente della cronologia viene ricostruita completamente (Pagina A). Le estensioni non dovevano preoccuparsi di quale parte del ciclo di vita si trovassero le pagine del ciclo di vita, perché ne esisteva solo una per ogni scheda, ovvero lo stato attivo/visibile.

Eliminazione della pagina attiva
Eliminazione della pagina attiva.

Con la cache back-forward e il prerendering, non esiste più una relazione one-to-one tra schede e pagine. Ora, ogni scheda archivia più pagine e pagine di transizione tra gli stati, invece di essere distrutte e ricostruite.

Ad esempio, una pagina potrebbe iniziare la sua vita come pagina sottoposta a prerendering (non visibile), passare a una pagina attiva (visibile) quando l'utente fa clic su un link, per poi essere archiviata nella cache back-forward (non visibile) quando l'utente passa a un'altra pagina, il tutto senza che la pagina venga eliminata. Più avanti in questo articolo esamineremo le nuove proprietà esposte per aiutare le estensioni a capire a quale stato si trovano le pagine.

Tipi di pagine
Tipi di pagine.

Tieni presente che una scheda può avere una serie di pagine sottoposte a prerendering (non una sola), una singola pagina attiva (visibile) e una serie di pagine memorizzate nella cache Indietro/Avanti.

Cosa cambia per gli sviluppatori di estensioni?

ID frame == 0

In Chromium, il frame più alto/principale è il frame più esterno.

Gli autori delle estensioni che presuppongono che il frameId del frame più esterno sia 0 (una best practice precedente) potrebbero avere problemi. Poiché ora una scheda può avere più frame più esterni (pagine prerenderizzate e memorizzate nella cache), l'ipotesi che ci sia un singolo frame più esterno per una scheda non è corretta. frameId == 0 continuerà a rappresentare il frame più esterno della pagina attiva, ma i frame più esterni delle pagine altre nella stessa scheda saranno diversi da zero. Per risolvere il problema, è stato aggiunto un nuovo campo frameType. Consulta la sezione "Come faccio a determinare se un frame è il frame più esterno?" di questo post.

Ciclo di vita dei frame e dei documenti

Un altro concetto problematico con le estensioni è il ciclo di vita del frame. Un frame ospita un documento (che è associato a un URL di cui è stato eseguito il commit). Il documento può cambiare (ad esempio navigando), ma il frameId no, quindi è difficile associare qualcosa che si è verificato in un documento specifico solo con i frameId. Stiamo introducendo il concetto di documentId, che è un identificatore univoco per ogni documento. Se un frame viene esplorato e apre un nuovo documento, l'identificatore cambia. Questo campo è utile per determinare quando le pagine cambiano il proprio stato del ciclo di vita (tra prerendering/attivo/cache) perché rimane lo stesso.

Eventi di navigazione web

Gli eventi nello spazio dei nomi chrome.webNavigation possono attivarsi più volte sulla stessa pagina a seconda del ciclo di vita in cui si trova. Consulta le sezioni "Come posso capire in quale ciclo di vita si trova la pagina?" e "Come faccio a determinare quando viene effettuata la transizione di una pagina?".

Come faccio a capire in quale ciclo di vita si trova la pagina?

Il tipo DocumentLifecycle è stato aggiunto a una serie di API di estensioni in cui frameId era disponibile in precedenza. Se il tipo DocumentLifecycle è presente in un evento (ad esempio onCommitted), il suo valore è lo stato in cui è stato generato l'evento. Puoi sempre eseguire query sulle informazioni tratte dai metodi WebNavigation getFrame() e getAllFrames(), ma è sempre preferibile utilizzare il valore dell'evento. Se utilizzi uno dei due metodi, tieni presente che lo stato del frame potrebbe cambiare da quando è stato generato l'evento a quello in cui vengono risolte le promesse da entrambi i metodi.

L'elemento DocumentLifecycle ha i seguenti valori:

  • "prerender" : questa funzionalità non è attualmente presentata all'utente, ma è in fase di preparazione per essere mostrata all'utente.
  • "active": attualmente mostrata all'utente.
  • "cached": archiviata nella cache back-forward.
  • "pending_deletion": il documento è in fase di eliminazione.

Come faccio a determinare se un frame è quello più esterno?

In precedenza, le estensioni potrebbero aver controllato se frameId == 0 per determinare se l'evento che si verifica riguarda o meno il frame più esterno. Con più pagine in una scheda ora abbiamo diversi frame più esterni, quindi la definizione di frameId è problematica. Non riceverai mai eventi relativi a un frame memorizzato nella cache back-forward. Tuttavia, per i frame sottoposti a prerendering, il valore frameId sarà diverso da zero per il frame più esterno. Di conseguenza, usare frameId == 0 come indicatore per determinare se si tratta del frame più esterno è errato.

Per aiutarti, abbiamo introdotto un nuovo tipo chiamato FrameType. Ora è facile determinare se il frame è davvero il frame più esterno. FrameType ha i seguenti valori:

  • "outermost_frame": generalmente indicato come il frame più in alto. Tieni presente che esistono multipli di questi. Ad esempio, se hai pagine sottoposte a prerendering e memorizzate nella cache, ognuna ha un frame più esterno che potrebbe essere chiamato frame più in alto.
  • "fenced_frame": riservato per un uso futuro.
  • "sub_frame": generalmente un iframe.

Possiamo combinare DocumentLifecycle con FrameType e determinare se un frame è il frame più esterno attivo. Ad esempio: js tab.documentLifecycle == “active” && frameType == “outermost_frame”.

Come si risolvono i problemi relativi al tempo di utilizzo dei frame?

Come abbiamo detto sopra, un frame ospita un documento e può passare a un nuovo documento, ma frameId non cambierà. Questo crea problemi quando ricevi un evento solo con frameId. Se cerchi l'URL del frame, potrebbe essere diverso da quando si è verificato l'evento, questo è chiamato problema di tempo di utilizzo.

Per risolvere questo problema, abbiamo introdotto documentId (e parentDocumentId). Il metodo webNavigation.getFrame() ora rende frameId facoltativo se viene fornito un documentId. L'elemento documentId cambia ogni volta che esplori un frame.

Come faccio a determinare quando viene eseguita la transizione di una pagina?

Esistono indicatori espliciti per determinare quando una pagina passa da uno stato all'altro.

Diamo un'occhiata agli eventi di WebNavigation.

Per una prima navigazione in una pagina, vedrai quattro eventi nell'ordine elencato di seguito. Tieni presente che questi quattro eventi potrebbero verificarsi con lo stato DocumentLifecycle "prerender" o "active".

onBeforeNavigate
onCommitted
onDOMContentLoaded
onCompleted

Ciò è illustrato nel diagramma seguente, che mostra il passaggio di documentId a "xyz" quando la pagina sottoposta a prerendering diventa attiva.

Il valore documentId cambia quando la pagina sottoposta a prerendering diventa la pagina attiva
documentId cambia quando la pagina sottoposta a prerendering diventa la pagina attiva.

Quando una pagina passa dalla cache back-forward o dal prerendering allo stato attivo, ci sono altri tre eventi (ma DocumentLifecyle è "active").

onBeforeNavigate
onCommitted
onCompleted

documentId rimarrà uguale a quello degli eventi originali. Ciò è illustrato sopra quando si attiva documentId == xyz. Tieni presente che vengono attivati gli stessi eventi di navigazione, ad eccezione dell'evento onDOMContentLoaded, perché la pagina è già stata caricata.

Per eventuali commenti o domande, non esitare a contattarci sul gruppo chromium-extensions.