Extensões do Chrome: ampliação da API para oferecer suporte à navegação instantânea

Dave Tapuska
Dave Tapuska

Texto longo, leia o resumo: A API Extensions foi atualizada para oferecer suporte ao cache de avanço e retorno. pré-carregamento de navegações. Veja os detalhes abaixo.

O Chrome tem trabalhado muito para tornar a navegação mais rápida. Navegação instantânea tecnologias, como cache de avanço e retorno (enviado para computadores em Chrome 96) e Regras de especulação (enviados no Chrome 103) melhoram tanto as etapas anteriores quanto as futuras do usuário. Nesta postagem, vamos explorar as atualizações que fizemos no navegador APIs de extensão para acomodar esses novos fluxos de trabalho.

Noções básicas sobre os tipos de páginas

Antes da introdução do cache de avanço e retorno e da pré-renderização, uma pessoa tinha apenas uma página ativa. Sempre foi aquela que esteve visível. Se um o usuário retornar para a página anterior, a página ativa será destruída (Página B) e a página anterior no histórico seria completamente reconstruída (Página A). As extensões não precisavam se preocupar com a parte do ciclo de vida das páginas. porque havia apenas um para cada guia, o estado ativo/visível.

Remoção da página ativa
Remoção da página ativa.

Com o cache de avanço e retorno e a pré-renderização, não há mais uma interação relação entre guias e páginas. Na verdade, cada guia armazena páginas e páginas fazem a transição 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 (não visível), passar para uma página ativa (visível) quando o usuário clicar em um link e, em seguida, ser armazenados no cache de avanço e retorno (não visível) quando o usuário navegar para outra página, tudo sem que ela jamais seja destruída. Mais adiante neste artigo vamos conferir as novas propriedades expostas para ajudar as extensões a entender o que páginas de estado em que estão.

Tipos de páginas
Tipos de páginas.

Uma guia pode ter uma série de páginas pré-renderizadas (não apenas uma), uma única active (visível) e uma série de páginas "Voltar/Avançar" em cache.

O que vai mudar para os desenvolvedores de extensões?

FrameId == 0

No Chromium, nos referimos ao frame principal/superior como o frame mais externo.

Autores de extensão que pressupõem o frameId do frame mais externo é 0 (uma prática recomendada anterior) pode apresentar problemas. Como uma guia agora pode ter vários frames externos (pré-renderizados e armazenados em cache do Google), a suposição de que existe uma rede o frame de uma guia está incorreto. frameId == 0 continuará representando o frame mais externo da página ativa, mas os frames mais externos da outras páginas na mesma guia serão diferentes de zero. Um novo campo frameType tem foi adicionado para corrigir esse problema. Consulte a seção "Como determinar se um frame é o mais externo?" desta postagem.

Ciclo de vida de frames versus documentos

Outro conceito problemático com as extensões é o ciclo de vida 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. é difícil associar que algo aconteceu em um documento específico com apenas frameIds. Apresentamos o conceito de um documentId que é um identificador exclusivo para cada documento. Se um frame for navegado e abre um novo documento, o identificador é alterado. Esse campo é útil para determinar quando as páginas mudam o estado do ciclo de vida (entre pré-renderizar/ativo/em cache) porque ele permanece o mesmo.

Eventos de navegação na Web

Eventos no namespace chrome.webNavigation pode disparar várias vezes na mesma página, dependendo do ciclo de vida. Consulte "Como faço para saber em qual ciclo de vida a página está?" e Como determinar quando uma página faz a transição?.

Como faço para saber em qual ciclo de vida a página está?

O DocumentLifecycle o tipo foi adicionado a várias APIs de extensões em que o frameId foi disponíveis anteriormente. Se o tipo DocumentLifecycle estiver presente em um evento (como onCommitted), Seu valor é o estado em que o evento foi gerado. Sempre é possível consultar informações do WebNavigation getFrame() e getAllFrames() métodos, mas é preferível usar o valor do evento. Se você usar qualquer método, saiba que o estado do frame pode mudar entre o momento em que o evento foi gerado e quando as promessas são retornadas pelos dois métodos é resolvida.

O DocumentLifecycle tem os seguintes valores:

  • "prerender" : não é apresentado ao usuário no momento, mas está em preparação para possivelmente ser exibido.
  • "active": exibido ao 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 que ocorre é para o frame mais externo ou não. Com várias páginas em uma guia, agora temos vários frames mais externos, então a definição de frameId é problemático. Você nunca receberá eventos sobre um recurso de Voltar/Avançar em cache frame. No entanto, para frames pré-renderizados, o frameId será valores diferentes de zero para o frame mais externo. Usar frameId == 0 como um indicador para e determinar se é o frame mais externo está incorreto.

Para ajudar com isso, apresentamos 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 conhecido como o frame superior. Observe que há vários deles. Por exemplo, se você tiver um objeto pré-renderizado e armazenado em cache páginas, cada uma com um frame mais externo que pode ser chamado de frame superior.
  • "fenced_frame": reservado para uso futuro.
  • "sub_frame": normalmente é um iframe.

Podemos combinar DocumentLifecycle com FrameType e determinar se um frame é o frame mais externo ativo. Exemplo: tab.documentLifecycle === “active” && frameType === “outermost_frame”

Como resolvo problemas de tempo de uso com frames?

Como dissemos acima, um frame hospeda um documento e o frame pode navegar para uma nova documento, mas o frameId não vai mudar. Isso cria problemas quando você receber um evento com apenas um frameId. Se você pesquisar o URL do frame, pode ser diferente de quando o evento ocorreu, isto é chamado um problema de tempo de uso.

Para resolver isso, apresentamos o documentId. (e parentDocumentId). O webNavigation.getFrame() agora torna o frameId opcional se um documentId for fornecido. O O documentId muda sempre que um frame é navegado.

Como determino quando uma página faz uma transição?

Há sinais explícitos para determinar quando uma página faz a transição entre estados.

Vamos dar uma olhada nos eventos WebNavigation.

Na primeira navegação de qualquer página, você verá quatro eventos na ordem listadas abaixo. Observe que esses quatro eventos podem ocorrer com O estado DocumentLifecycle é "prerender" ou "active".

onBeforeNavigate
onCommitted
onDOMContentLoaded
onCompleted

Isso é ilustrado no diagrama abaixo, que mostra a mudança de documentId como "xyz" quando a página pré-renderizada se torna ativa.

O documentId muda quando a página pré-renderizada se torna ativa.
O documentId muda quando a página pré-renderizada se torna o página ativa.

Quando uma página transita do cache de avanço e retorno ou de pré-renderização para o ativo, haverá mais três eventos (mas com DocumentLifecyle sendo "active").

onBeforeNavigate
onCommitted
onCompleted

O evento documentId vai ser o mesmo dos eventos originais. Isso é ilustrado acima quando documentId == xyz é ativado. Observe que o os mesmos eventos de navegação são acionados, exceto para onDOMContentLoaded porque a página já foi carregada.

Se você tiver comentários ou perguntas, faça perguntas no chromium-extensions (em inglês) grupo.