Mudanças no comportamento do BFCache com as portas de mensagem da extensão

O cache de avanço e retorno (ou BFCache) é uma otimização do navegador que permite a navegação instantânea para frente e para trás. Estamos fazendo mudanças no BFCache do Chrome que podem afetar as extensões que usam portas de mensagem. Se você tem uma extensão do Chrome que usa mensagens para fazer a comunicação entre scripts de conteúdo e sua extensão, continue lendo para saber como testar e adaptar sua extensão.

Porta de mensagem da extensão

As extensões se comunicam com o script de conteúdo ou com outras extensões pela transmissão de mensagens. As mensagens podem ser enviadas usando solicitações únicas chamando runtime.sendMessage() e tabs.sendMessage() ou usando uma porta de mensagem reutilizável. Enquanto a porta estiver ativa, o script de conteúdo e o script de segundo plano da extensão poderão reutilizá-la para postar mensagens entre si.

Para mais informações, consulte Transmissão de mensagens.

Cache de avanço e retorno

Ao sair de uma página qualificada para BFCache, o navegador permite que a página com todo o estado permaneça na memória, mas no estado não totalmente ativo. Se o usuário executar uma navegação no histórico (voltar ou avançar) até a página em cache, o navegador tentará restaurar a página do BFCache. Isso torna a navegação mais rápida e melhora a experiência do usuário.

Enquanto a página estiver no BFCache, ela vai ficar em um estado congelado, em que nenhuma execução do JavaScript é permitida. Isso significa que ele não processa as mensagens recebidas.

Para mais informações, consulte Cache de avanço e retorno.

Impacto das portas de mensagens de extensão no BFCache

Em resumo, a extensão que envia mensagens para uma página no BFCache pode causar a remoção do cache e afetar o desempenho.

Quando uma página com uma porta de mensagem de extensão aberta é armazenada no BFCache, a porta permanece aberta. Depois que a página for restaurada do BFCache, a referência antiga da porta da mensagem ainda poderá ser usada pelos service workers da extensão para postar mensagens no script de conteúdo.

No entanto, se a extensão tentar postar uma mensagem por essa porta enquanto a página ainda estiver no BFCache, a mensagem será enviada, mas não totalmente entregue, porque o gerenciador será congelado. Para a extensão, é difícil raciocinar e resolver essa situação, porque tanto enfileirar quanto descartar a mensagem têm seus próprios problemas.

Para evitar problemas relacionados a mensagens perdidas, na implementação atual do Chrome, ele elimina a página do host do BFCache e descarta a mensagem. Se o usuário voltar para a página, ela será carregada de novo, permitindo que a extensão configure uma nova conexão.

Por outro lado, essa implementação restringe os cenários em que o BFCache se aplica, limitando os ganhos de desempenho, especialmente para extensões com mecanismos de transmissão ou sinal de funcionamento que enviam regularmente mensagens para todas as conexões. Além disso, como a remoção é acionada quando a extensão envia uma mensagem para o script de conteúdo, os desenvolvedores da Web não têm como impedir que as páginas sejam removidas.

Para melhorar o desempenho geral, planejamos introduzir um novo comportamento de porta de mensagens.

Novo comportamento: fechar o canal de mensagens quando a página estiver armazenada no BFCache

A partir do Chrome 123, quando uma página com uma porta de mensagem de extensão aberta é armazenada no BFCache, o canal de mensagem subjacente é fechado de maneira proativa pelo script de conteúdo. Como resultado, todas as portas de mensagens serão fechadas, e a extensão receberá um evento onDisconnect.

Como o canal está fechado, nenhuma mensagem será enviada à página enquanto ela estiver no BFCache. Portanto, a página não será removida devido à extensão.

Mesmo depois que a página for restaurada do BFCache, o canal de mensagem fechado não será reaberto. A prática recomendada para os autores de extensões é detectar os eventos de ciclo de vida da página e configurar uma nova conexão quando a página for restaurada do BFCache, conforme mostrado no exemplo a seguir.

// content script

let port;

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // The page is restored from BFCache, set up a new connection.
    port = chrome.runtime.connect();
  }
});

Leia mais sobre a conversa do WECG com representantes de diferentes navegadores (no problema 474).

Meu ambiente foi afetado por essa vulnerabilidade?

O novo comportamento estará disponível por meio de uma sinalização no Chrome 123 para que você possa testar seu código. Confira mais informações no cronograma. Siga as etapas a seguir para testar sua extensão. Ele oferece apenas um teste simples. Recomendamos que você execute o Chrome com o recurso ativado por um período, já que pode ser difícil prever quais recursos da extensão podem causar problemas.

  1. Confira se a versão do Chrome é pelo menos a 123. O ideal é usar o Chrome Canary, que tem um aviso extra para facilitar os testes.
  2. Inicie o Chrome com a seguinte flag:

    --disable-features=DisconnectExtensionMessagePortWhenPageEntersBFCache
    
  3. Acesse uma página qualificada para o BFCache sem a extensão em execução (por exemplo, um site simples, como https://example.com/). Siga o tutorial do BFCache (em inglês) para garantir que ele seja restaurado do BFCache.

  4. Instale e ative a extensão e teste a qualificação do BFCache novamente. É possível sair manualmente, aguardar um tempo suficiente até que a extensão poste uma mensagem na página BFCached e voltar.

  5. Se a página tiver que ser carregada novamente em vez de pelo BFCache devido a uma remoção e o problema que impede a restauração for "ExtensionSentMessageToCachedFrame", a extensão poderá ser afetada por essa mudança.

    No Chrome Canary 124.0.6315.0 e versões mais recentes, você também verá o seguinte aviso na página:

    Aviso mostrado quando uma página não é restaurada do BFCache.
    Aviso mostrado quando uma página não é restaurada do BFCache.

Depois de confirmar que a extensão está postando mensagens na página BFCache, siga estas etapas para forçar a ativação do experimento e observar se alguma lógica falha.

  1. Inicie o Chrome com a seguinte flag:

    --enable-features=DisconnectExtensionMessagePortWhenPageEntersBFCache
    
  2. Acesse a página que não foi restaurada do BFCache devido a "ExtensionSentMessageToCachedFrame".

  3. Saia e volte. A página será restaurada agora, mas o canal de mensagem entre o script de conteúdo e o service worker será desconectado.

  4. Teste se a extensão ainda funciona normalmente. Caso contrário, reconecte-se manualmente, conforme demonstrado na seção anterior.

Cronograma de lançamento

Planejamos ampliar gradualmente o novo comportamento a partir do Chrome 123. Confira o plano detalhado:

Data Marco planejado
15 de fevereiro Inicie o experimento para o novo comportamento no Chrome Canary e Dev.
1 de março Inicie o experimento para o novo comportamento no Chrome Beta.
18 de março Lançaremos o novo comportamento para 4% dos usuários no Chrome Stable.
25 de março Lançar o novo comportamento para 50% dos usuários no Chrome Stable.
2 de abril O experimento termina, e o novo comportamento é o padrão.