TL;DR: l'API Extensions è stata aggiornata per supportare la cache back-forward e il precaricamento delle navigazioni. Scopri di più nella sezione seguente.
Chrome si impegna a fondo per rendere la navigazione veloce. Le tecnologie di navigazione istantanea come la cache back-forward (implementata su computer in Chrome 96) e le regole di speculazione (implementate in Chrome 103) migliorano sia l'esperienza di navigazione avanti che quella di navigazione indietro. In questo post esploreremo gli aggiornamenti che abbiamo apportato alle API di estensioni del browser per supportare questi nuovi flussi di lavoro.
Informazioni sui tipi di pagine
Prima dell'introduzione della cache back-forward e del prerendering, un singolo tab aveva una sola pagina attiva. Questo era sempre quello visibile. Se un utente torna alla pagina precedente, la pagina attiva viene distrutta (pagina B) e la pagina precedente nella cronologia viene ricostruita completamente (pagina A). Le estensioni non dovevano preoccuparsi di quale parte del ciclo di vita riguardassero le pagine perché ne esisteva una sola per una scheda, lo stato attivo/visibile.
Con la cache back-forward e il prerendering, non esiste più un rapporto uno a uno tra schede e pagine. Ora ogni scheda memorizza più pagine e le pagine passano da uno stato all'altro anziché essere distrutte e ricostruite.
Ad esempio, una pagina potrebbe iniziare la sua vita come pagina pre-visualizzata (non visibile), passare a una pagina attiva (visibile) quando l'utente fa clic su un link e poi essere memorizzata nella cache di navigazione (non visibile) quando l'utente passa a un'altra pagina, il tutto senza che la pagina venga mai distrutta. Più avanti in questo articolo esaminare le nuove proprietà esposte per aiutare le estensioni a capire in quali pagine di stato si trovano.
Tieni presente che una scheda può avere una serie di pagine pre-renderizzate (non solo una), una singola pagina attiva (visibile) e una serie di pagine memorizzate nella cache di Avanti/Indietro.
Cosa cambia per gli sviluppatori di estensioni?
FrameId == 0
In Chromium, il frame principale/superiore è il frame più esterno.
Gli autori di estensioni che presumono che frameId
del frame più esterno sia 0 (una best practice precedente) potrebbero riscontrare problemi.
Poiché ora una scheda può avere più frame esterni (pagine pre-renderizzate e memorizzate nella cache), l'assunto che esista un singolo frame esterno per una scheda è errato. frameId == 0
continuerà a rappresentare il frame più esterno della pagina attiva, ma i frame più esterni delle altre pagine nella stessa scheda non saranno nulli. 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 rispetto ai documenti
Un altro concetto problematico con le estensioni è il ciclo di vita del frame. Un frame ospita un documento (associato a un URL impegnato). Il documento può cambiare (ad esempio durante la navigazione), ma frameId no, pertanto è difficile associare un evento a un documento specifico solo con frameId. Stiamo introducendo il concetto di documentId, che è un identificatore univoco per ogni documento. Se viene visualizzato un frame e si apre un nuovo documento, l'identificatore cambia. Questo campo è utile per determinare quando le pagine cambiano stato nel ciclo di vita (tra prerendering/attivo/in cache) perché rimane invariato.
Eventi di navigazione sul web
Gli eventi nello spazio dei nomi chrome.webNavigation
possono essere attivati più volte nella stessa pagina a seconda del ciclo di vita in cui si trovano. Consulta le sezioni "Come faccio a capire in quale ciclo di vita si trova la pagina?" e "Come faccio a determinare quando una pagina passa da uno stato all'altro?".
Come faccio a capire in quale fase del ciclo di vita si trova la pagina?
Il tipo DocumentLifecycle
è stato aggiunto a una serie di API di estensioni in cui era precedentemente disponibile frameId
. 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 dei metodi WebNavigation
getFrame()
e getAllFrames()
, ma è sempre preferibile utilizzare il valore dell'evento. Se utilizzi uno di questi metodi, tieni presente che lo stato del frame potrebbe cambiare tra il momento in cui è stato generato l'evento e la risoluzione delle promesse restituite da entrambi i metodi.
DocumentLifecycle
ha i seguenti valori:
"prerender
" : non viene attualmente presentato all'utente, ma è in preparazione per essere eventualmente mostrato."active"
: attualmente visualizzato dall'utente."cached"
: memorizzato nella cache Avanti/Indietro."pending_deletion"
: il documento viene distrutto.
Come faccio a determinare se un frame è il frame più esterno?
In precedenza, le estensioni potrebbero aver controllato se frameId == 0
per determinare se l'evento si verifica per il frame più esterno o meno. Con più pagine
in una scheda ora abbiamo più frame esterni, quindi la definizione di frameId
è problematica. Non riceverai mai eventi relativi a un frame memorizzato nella cache con opzione Indietro/Avanti. Tuttavia, per i frame pre-renderizzati, frameId
sarà diverso da zero per il frame più esterno. Pertanto, l'utilizzo di frameId == 0
come indicatore per determinare se si tratta del frame più esterno non è corretto.
Per aiutarti, abbiamo introdotto un nuovo tipo chiamato
FrameType
in modo che sia facile determinare se il frame è effettivamente il frame più esterno.
FrameType
ha i seguenti valori:
"outermost_frame"
: in genere indicato come frame più alto. Tieni presente che esistono più valori. Ad esempio, se hai pagine pre-elaborate e memorizzate nella cache, ognuna ha un frame più esterno che potrebbe essere chiamato frame principale."fenced_frame"
: riservato per l'uso futuro."sub_frame"
: in genere un iframe.
Possiamo combinare DocumentLifecycle
con FrameType
e determinare se un frame è
il frame esterno attivo. Ad esempio: tab.documentLifecycle === “active” && frameType === “outermost_frame”
.
Come faccio a risolvere i problemi relativi all'ora di utilizzo con le cornici?
Come abbiamo detto sopra, un frame ospita un documento e può passare a un nuovo
documento, ma frameId
non cambierà. Ciò crea problemi quando ricevi un evento con solo un frameId
. Se cerchi l'URL
del frame, potrebbe essere diverso da quello al momento dell'evento. Si tratta di un
problema di momento di utilizzo.
Per risolvere il problema, abbiamo introdotto documentId
(e parentDocumentId
).
Il metodo webNavigation.getFrame()
ora rende facoltativo frameId
se viene fornito documentId
. Il valore documentId
cambia ogni volta che viene visualizzato un frame.
Come faccio a determinare quando avviene una transizione di pagina?
Esistono indicatori espliciti per determinare quando una pagina passa da uno stato all'altro.
Diamo un'occhiata agli eventi WebNavigation
.
Per la prima navigazione in qualsiasi pagina, vedrai quattro eventi nell'ordine elencato di seguito. Tieni presente che questi quattro eventi potrebbero verificarsi con lo stato DocumentLifecycle
pari a "prerender"
o "active"
.
onBeforeNavigate
onCommitted
onDOMContentLoaded
onCompleted
Questo è illustrato nel diagramma seguente, che mostra il passaggio da documentId
a "xyz"
quando la pagina pre-renderizzata diventa la pagina attiva.
Quando una pagina passa dalla cache back-forward o dal prerendering allo stato attivo, vengono generati altri tre eventi (ma con DocumentLifecyle
uguale a "active"
).
onBeforeNavigate
onCommitted
onCompleted
documentId
rimarrà invariato rispetto agli eventi originali. Questo è 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 chiedere nel gruppo chromium-extensions.