Cambios en el comportamiento de BFCache con puertos de mensajes de extensión

Mingyu Lei
Mingyu Lei

La memoria caché atrás/adelante (o BFCache) es una optimización del navegador que permite las navegaciones instantáneas hacia adelante y hacia atrás. Haremos cambios en Chrome BFCache que podrían afectar a las extensiones que usan puertos de mensajes. Si tienes una extensión de Chrome que usa mensajes para comunicarse entre las secuencias de comandos de contenido y la extensión, sigue leyendo para obtener información sobre cómo probar y adaptarla.

Puerto de mensajes de extensión

Las extensiones se comunican con la secuencia de comandos de contenido o con otras extensiones a través del envío de mensajes. Los mensajes se pueden enviar con solicitudes únicas llamando a runtime.sendMessage() y tabs.sendMessage(), o con un puerto de mensajes reutilizable. Mientras el puerto esté activo, tanto la secuencia de comandos de contenido como la secuencia de comandos en segundo plano de la extensión pueden volver a usarlo para enviarse mensajes entre sí.

Para obtener más información, consulta Paso de mensajes.

Memoria caché atrás/adelante

Cuando sales de una página que es apta para BFCache, el navegador permite que la página con todo su estado permanezca en la memoria, pero en el estado no completamente activo. Si el usuario realiza una navegación de historial (atrás o adelante) a la página almacenada en caché, el navegador intentará restablecerla desde la BFCache. Esto hace que la navegación sea más rápida y mejora la experiencia de navegación del usuario.

Mientras la página está en BFCache, se encuentra en un estado inmovilizado en el que no se permite la ejecución de JavaScript. Esto significa que no puede procesar los mensajes que recibe.

Para obtener más información, consulta Caché atrás/adelante.

Impacto de los puertos de mensajes de extensión en BFCache

En resumen, la extensión que envía mensajes a una página en BFCache puede provocar la expulsión de la caché y afectar el rendimiento.

Cuando se almacena una página con un puerto de mensaje de extensión abierto en BFCache, el puerto permanece abierto. Una vez que se restablece la página desde BFCache, los trabajadores del servicio de extensión pueden seguir usando la referencia anterior del puerto de mensajes para publicar mensajes en la secuencia de comandos de contenido.

Sin embargo, si la extensión intenta publicar un mensaje a través de ese puerto de mensaje mientras la página aún está en BFCache, el mensaje se envía, pero no se entrega por completo porque el controlador está inmovilizado. Es un desafío para la extensión razonar y abordar esta situación, ya que poner en cola y descartar el mensaje tienen sus propios problemas.

Para evitar problemas relacionados con los mensajes perdidos, en la implementación actual de Chrome, se expulsa la página host de BFCache y se descarta el mensaje. Si el usuario vuelve a la página, esta se cargará de forma actualizada, lo que permitirá que la extensión configure una conexión nueva.

Por otro lado, esta implementación restringe las situaciones en las que se aplica BFCache, lo que limita las ganancias de rendimiento, especialmente para las extensiones con mecanismos de transmisión o de verificación de estado que envían mensajes con regularidad a todas las conexiones. Además, como la expulsión se activa cuando la extensión envía un mensaje a la secuencia de comandos de contenido, los desarrolladores web no tienen forma de evitar que se expulsen sus páginas.

Para mejorar el rendimiento general, planeamos implementar un nuevo comportamiento de los puertos de mensajes.

Nuevo comportamiento: Se cierra el canal de mensajes cuando la página se almacena en BFCache.

A partir de Chrome 123, cuando se almacena una página con un puerto de mensaje de extensión abierto en BFCache, el canal de mensajes subyacente se cierra de forma proactiva desde el lado de la secuencia de comandos de contenido. Como resultado, se cerrarán todos los puertos de mensajes y la extensión recibirá un evento onDisconnect.

Como el canal está cerrado, no se enviarán mensajes a la página mientras esté en BFCache. Por lo tanto, la página no se desalojará debido a la extensión.

Incluso después de que se restablezca la página desde BFCache, no se volverá a abrir el canal de mensajes cerrado. La práctica recomendada para los autores de extensiones es escuchar los eventos del ciclo de vida de la página y configurar una conexión nueva cuando la página se restablece desde BFCache, como se muestra en el siguiente ejemplo.

// 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();
  }
});

Obtén más información sobre la conversación de WECG con representantes de diferentes navegadores (en el problema 474).

¿Me afecta esta vulnerabilidad?

El nuevo comportamiento estará disponible detrás de una marca en Chrome 123 para que puedas probar tu código. Consulta el cronograma para obtener más información. Sigue los pasos que se indican a continuación para probar la extensión. Ten en cuenta que solo proporciona una prueba simple y te recomendamos que ejecutes Chrome con la función habilitada durante un período, ya que puede ser difícil predecir qué funciones de la extensión pueden causar problemas.

Prueba el comportamiento nuevo

Para habilitar de forma forzosa el experimento en Chrome 123, haz lo siguiente:

  1. Inicia Chrome con la siguiente marca, que aplica el comportamiento nuevo:

    --enable-features=DisconnectExtensionMessagePortWhenPageEntersBFCache
    
  2. Ve a una página y, si es necesario, interactúa con la extensión para que una secuencia de comandos de contenido abra un puerto para la extensión.

  3. Sal y vuelve. La página debería restablecerse ahora, pero el canal de mensajes entre la secuencia de comandos de contenido y el trabajador de servicio debería estar desconectado.

  4. Prueba si la extensión sigue funcionando como de costumbre. De lo contrario, debes volver a conectarte de forma manual, como se muestra en la sección anterior.

Identifica problemas simples con el comportamiento anterior

Antes de este cambio, Chrome mostraba una advertencia si intentabas enviar un mensaje a un puerto asociado con una página en la bfcache. Esto puede ser útil para identificar algunos, pero no todos los problemas que involucran mensajes del segundo plano a la página.

  1. Asegúrate de que la versión de Chrome sea al menos 123. Lo ideal es usar Chrome Canary, que tiene una advertencia adicional para facilitar las pruebas.
  2. Inicia Chrome con la siguiente marca, que aplica el comportamiento anterior:

    --disable-features=DisconnectExtensionMessagePortWhenPageEntersBFCache
    
  3. Ve a una página apta para BFCache sin que se ejecute la extensión (por ejemplo, un sitio simple como https://example.com/). Sigue el instructivo de BFCache para asegurarte de que se restablezca desde BFCache.

  4. Instala y habilita la extensión, y vuelve a probar la elegibilidad de BFCache. Puedes navegar de forma manual, esperar el tiempo suficiente para que tu extensión publique un mensaje en la página BFCached y volver a navegar.

  5. Si la página tuvo que cargarse nueva en lugar de desde BFCache debido a un desalojo y el problema que impide el restablecimiento es "ExtensionSentMessageToCachedFrame", es posible que la extensión se vea afectada por este cambio.

    En Chrome Canary 124.0.6315.0 y versiones posteriores, también verás la siguiente advertencia en la página:

    Se muestra una advertencia cuando no se restablece una página desde BFCache.
    Advertencia que se muestra cuando no se restablece una página desde BFCache.

Una vez que se confirme que la extensión publica mensajes en la página BFCache, puedes seguir los pasos de la sección anterior para forzar la habilitación del experimento y observar si se produce algún error lógico.

Cronograma de lanzamiento

Planeamos implementar gradualmente el nuevo comportamiento a partir de Chrome 123. Este es el plan detallado:

Fecha Logro planificado
15 de febrero Comienza el experimento del nuevo comportamiento en Chrome 123 Canary y Dev.
7 de marzo Comienza el experimento del nuevo comportamiento en Chrome 123 beta.
18 de marzo Lanza el nuevo comportamiento para el 4% de los usuarios en Chrome 123 estable.
25 de marzo Lanza el nuevo comportamiento para el 50% de los usuarios en Chrome 123 estable.
2 de abril El experimento finaliza y se establece el comportamiento nuevo como predeterminado.