Texto longo, leia o resumo: a API Extensions foi atualizada para oferecer suporte ao cache de avanço e retorno e as navegações de pré-carregamento. Veja os detalhes abaixo.
O Chrome está trabalhando duro para tornar a navegação mais rápida. Tecnologias de navegação instantânea, como cache de avanço e retorno (enviada em computadores no Chrome 96) e regras de especulação (enviadas no Chrome 103), melhoram a experiência de avanço e retorno. Nesta postagem, vamos falar sobre as atualizações que fizemos nas APIs de extensões do navegador para acomodar esses novos fluxos de trabalho.
Como entender os tipos de páginas
Antes da introdução do cache de avanço e retorno e da pré-renderização, uma guia individual tinha apenas uma página ativa. Essa sempre estava visível. Se o usuário retornar à página anterior, a página ativa será destruída (Página B) e a anterior no histórico será completamente reconstruída (Página A). As extensões não precisavam se preocupar com a parte das páginas de ciclo de vida, porque havia apenas uma para uma guia, o estado ativo/visível.
Com o cache de avanço e retorno e a pré-renderização, não há mais uma relação de um para um entre guias e páginas. Agora, cada guia armazena várias páginas e transições de páginas entre estados, em vez de serem destruídas e reconstruídas.
Por exemplo, uma página pode começar sua vida como uma página pré-renderizada (invisível), fazer a transição para uma página ativa (visível) quando o usuário clicar em um link e ser armazenada no cache de avanço e retorno (invisível) quando o usuário navegar para outra página, tudo isso sem que a página seja destruída. Posteriormente neste artigo, analisaremos as novas propriedades expostas para ajudar as extensões a entender em que as páginas de estado estão.
Uma guia pode ter uma série de páginas pré-renderizadas (não apenas uma), uma única página ativa (visível) e uma série de páginas de avanço e retorno armazenadas em cache.
O que vai mudar para os desenvolvedores de extensões?
FrameId == 0
No Chromium, nos referimos ao frame principal/principal como o mais externo.
Os autores de extensões que presumem que o frameId
do frame mais externo é 0 (uma prática recomendada anterior) podem ter problemas.
Como uma guia agora pode ter vários frames mais externos (páginas pré-renderizadas e
armazenadas em cache), a suposição de que há um único frame mais externo
para uma guia não está correta. frameId == 0
continuará a representar o frame mais externo da página active, mas os frames mais externos de outras páginas na mesma guia serão diferentes de zero. Um novo campo frameType foi
adicionado para corrigir esse problema. Consulte a seção “Como determinar se um frame é o frame mais externo?”
desta postagem.
Ciclo de vida de frames x documentos
Outro conceito problemático com extensões é o ciclo de vida do frame. Um frame hospeda um documento (que está associado a um URL confirmado). O documento pode mudar (por exemplo, navegando), mas o frameId não. Por isso, é difícil associar que algo aconteceu em um documento específico apenas com frameIds. Estamos introduzindo um conceito de documentId, que é um identificador exclusivo para cada documento. Se um frame for navegado e abrir um novo documento, o identificador será alterado. Esse campo é útil para determinar quando as páginas mudam o estado do ciclo de vida (entre pré-renderizado/ativo/armazenado em cache) porque ele permanece o mesmo.
Eventos de navegação na Web
Eventos no namespace chrome.webNavigation
podem ser disparados várias vezes na
mesma página, dependendo do ciclo de vida em que estão. Consulte as seções Como saber em que ciclo de vida a página está? e Como determinar quando uma página faz a transição?.
Como saber em que ciclo de vida a página está?
O tipo DocumentLifecycle
foi adicionado a várias APIs de extensões em que o frameId
estava
disponível anteriormente. Se o tipo DocumentLifecycle
estiver presente em um evento
(como onCommitted
),
o valor dele será o estado em que o evento foi gerado. É possível consultar
informações dos métodos WebNavigation
getFrame()
e getAllFrames()
, mas usar o valor do evento é sempre preferível. Se você usar
qualquer um dos métodos, esteja ciente de que o estado do frame pode mudar entre o momento em que o evento
foi gerado e quando as promessas retornadas pelos dois métodos forem resolvidas.
O DocumentLifecycle
tem os seguintes valores:
"prerender
" : não é apresentado ao usuário no momento, mas está se preparando para possivelmente ser exibido ao usuário."active"
: exibido no momento para o usuário."cached"
: armazenado no cache de avanço e retorno."pending_deletion"
: o documento está sendo destruído.
Como determino se um frame é o mais externo?
Anteriormente, as extensões podem ter verificado se frameId == 0
para determinar
se o evento ocorrendo era para o frame mais externo ou não. Quando uma guia tem várias páginas, temos vários frames mais externos. Por isso, a definição de frameId é problemática. Você nunca vai receber eventos sobre um frame de avanço e retorno armazenado em cache. No entanto, para frames pré-renderizados, o frameId
será diferente de zero para o frame mais externo. Portanto, usar frameId == 0
como sinal para
determinar se ele é o frame mais externo está incorreto.
Para ajudar com isso, introduzimos um novo tipo chamado
FrameType
.
Agora ficou fácil determinar se o frame é realmente o mais externo.
FrameType
tem os seguintes valores:
"outermost_frame"
: normalmente chamado de frame superior. Observe que há vários deles. Por exemplo, se você tem uma página pré-renderizada e armazenada em cache, cada uma tem um frame mais externo que pode ser chamado de frame superior."fenced_frame"
: reservado para uso futuro."sub_frame"
: normalmente, um iframe.
É possível combinar DocumentLifecycle
com FrameType
e determinar se um frame é
o mais externo ativo. Exemplo:
js
tab.documentLifecycle == “active” && frameType == “outermost_frame”
Como resolver problemas de tempo de uso com frames?
Como mencionamos acima, um frame hospeda um documento e ele pode navegar para um novo
documento, mas o frameId
não muda. Isso cria problemas quando você
recebe um evento com apenas frameId
. Se você pesquisar o URL
do frame, ele pode ser diferente de quando o evento ocorreu. Isso é chamado
de problema de tempo de uso.
Para resolver isso, introduzimos documentId
(e parentDocumentId
).
O método webNavigation.getFrame()
agora torna a frameId
opcional se um documentId
for fornecido O
documentId
muda sempre que um frame é navegado.
Como determino quando uma página faz a transição?
Há sinais explícitos para determinar quando uma página faz a transição entre estados.
Vamos conferir os eventos WebNavigation
.
Na primeira navegação de uma página, há quatro eventos na ordem listada abaixo. Esses quatro eventos podem ocorrer com o estado DocumentLifecycle
sendo "prerender"
ou "active"
.
onBeforeNavigate
onCommitted
onDOMContentLoaded
onCompleted
Isso é ilustrado no diagrama abaixo, que mostra a mudança de documentId
para "xyz"
quando a página pré-renderizada se torna a ativa.
Quando uma página faz a transição do Cache de avanço e retorno ou da pré-renderização para o
estado ativo, há mais três eventos (mas DocumentLifecyle
sendo "active"
).
onBeforeNavigate
onCommitted
onCompleted
O documentId
vai permanecer o mesmo dos eventos originais. Isso é
ilustrado acima quando documentId
== xyz é ativado. Os mesmos eventos de navegação são disparados, exceto pelo evento onDOMContentLoaded
porque a página já foi carregada.
Se você tiver comentários ou dúvidas, sinta-se à vontade para perguntar no grupo chromium-extensions.