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, durante il precaricamento delle navigazioni. Scopri di più nella sezione seguente.

Chrome si sta adoperando per rendere la navigazione veloce. Navigazione istantanea come la cache back-forward (spedizione su computer in Chrome 96) e regole di speculazione (fornito in Chrome 103) migliora sia l'esperienza futura che quella futura un'esperienza senza intervento manuale. In questo post esploreremo gli aggiornamenti che abbiamo apportato al browser le API delle estensioni per soddisfare questi nuovi flussi di lavoro.

Comprendere i tipi di pagine

Prima dell'introduzione della cache back-forward e del prerendering, un utente aveva una sola pagina attiva. Era sempre quella che era visibile. Se l'utente torna alla pagina precedente, la pagina attiva viene eliminata (Pagina B) mentre la pagina precedente della cronologia sarà completamente ricostruita (Pagina A). Le estensioni non hanno dovuto preoccuparsi di quale parte delle pagine del ciclo di vita venissero perché ce n'era solo uno per ogni scheda, lo stato attivo/visibile.

Eliminazione della pagina attiva
Eliminazione della pagina attiva.

Con la cache back-forward e il prerendering, non è più relazione tra schede e pagine. Ogni scheda memorizza pagine e pagine passano da uno stato all'altro invece di essere distrutte e ricostruito.

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

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 attiva (visibile) e una serie di pagine memorizzate nella cache back-forward.

Cosa cambia per gli sviluppatori di estensioni?

ID frame == 0

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

Autori delle estensioni che presuppongono il valore frameId del frame più esterno è 0 (una best practice precedente) potrebbero verificarsi problemi. Dato che una scheda ora può avere più frame più esterni (prerenderizzati e memorizzati nella cache pagine), il presupposto che ci sia un unico obiettivo il frame di una scheda non è corretto. frameId == 0 continuerà a rappresentare il frame più esterno della pagina attiva, ma i frame più esterni della altre pagine nella stessa scheda saranno diverse da zero. Un nuovo campo frameType ha per risolvere il problema. Consulta la sezione "Come faccio a determinare se un fotogramma è 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 frame. Un frame ospita un documento (che è associato a un URL di cui è stato eseguito il commit). Il documento può cambiare, ad esempio navigando, al contrario del frameId, quindi è difficile associare che sia successo qualcosa in un documento specifico con solo frameIds. Stiamo introducendo un concetto di documentId che è un identificatore univoco per ogni documento. Se un frame viene esplorato apre un nuovo documento e l'identificatore cambierà. Questo campo è utile per determinare quando le pagine cambiano il proprio stato del ciclo di vita (tra prerendering/attivo/cached) perché rimane invariato.

Eventi di navigazione web

Eventi nello spazio dei nomi chrome.webNavigation può attivarsi più volte stessa pagina a seconda del ciclo di vita in cui si trova. Consulta "Come faccio a capire in quale ciclo di vita si trova la pagina?" e "Come faccio a determinare quando viene eseguita la transizione di una pagina?".

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

La DocumentLifecycle è stato aggiunto a una serie di API di estensioni in cui frameId era disponibili 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 informazioni dal WebNavigation getFrame() e getAllFrames() ma è sempre preferibile utilizzare il valore dell'evento. Se utilizzi entrambi i metodi devono essere consapevoli che lo stato del frame può cambiare tra il momento in cui l'evento e quando vengono risolte le promesse da entrambi i metodi.

La DocumentLifecycle ha i seguenti valori:

  • "prerender" : la presentazione all'utente non è attualmente disponibile, ma si sta preparando a essere visualizzata dall'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 più frame più esterni, quindi la definizione di frameId è problematico. Non riceverai mai eventi relativi a una cache back-forward frame. Tuttavia, per i frame sottoposti a prerendering, l'elemento frameId verrà diverso da zero per il frame più esterno. Quindi, utilizzare frameId == 0 come indicatore determinare se si tratta del frame più esterno non è corretto.

Per facilitare questa operazione, abbiamo introdotto un nuovo tipo chiamato FrameType quindi stabilire se il frame è effettivamente quello più esterno è facile. FrameType ha i seguenti valori:

  • "outermost_frame": generalmente indicato come il frame più in alto. Tieni presente che ce ne sono multipli. Ad esempio, se disponi di un prerendering e di una cache pagine, ognuna con 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: tab.documentLifecycle === “active” && frameType === “outermost_frame”.

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

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

Per risolvere questo problema, abbiamo introdotto documentId (e parentDocumentId). L'elemento webNavigation.getFrame() ora il metodo frameId facoltativo se viene fornito un documentId. La documentId cambierà 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 primissima navigazione in una pagina, vedrai quattro eventi in ordine elencati di seguito. Tieni presente che questi quattro eventi potrebbero verificarsi con Lo stato di DocumentLifecycle è "prerender" o "active".

onBeforeNavigate
onCommitted
onDOMContentLoaded
onCompleted

Ciò è illustrato nel diagramma seguente, che mostra la variazione 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
L'elemento documentId cambia quando la pagina sottoposta a prerendering diventa pagina attiva.

Quando una pagina esegue la transizione dalla cache back-forward o dal prerendering stato attivo ci saranno altri tre eventi (ma con DocumentLifecyle ossia "active").

onBeforeNavigate
onCommitted
onCompleted

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

Per eventuali commenti o domande, non esitate a contattarci nella estensioni-chromium gruppo.