Minimizar el impacto de una extensión en el tiempo de carga de la página
Los scripts de contenido son archivos JavaScript que la extensión inserta en páginas web y que se ejecutan en el contexto de estas páginas web. Mediante scripts de contenido, la extensión puede acceder a una página web representada y modificarla leyendo o cambiando el DOM.
Sin embargo, los scripts de contenido pueden tener un impacto notable en el rendimiento de una página web, por ejemplo, al ralentizar el tiempo de carga de la página. Esto puede ocurrir si el script de contenido ejecuta una gran cantidad de código mientras se carga la página.
En este artículo se proporcionan procedimientos recomendados que pueden ayudarle a minimizar el impacto en el rendimiento de la extensión en las páginas web que visitan los usuarios.
Generación de perfiles del script de contenido de la extensión
Para generar perfiles del rendimiento del script de contenido de la extensión, use Microsoft Edge DevTools o la herramienta de seguimiento de Edge, como se describe en las secciones siguientes.
Generación de perfiles del script de contenido mediante Microsoft Edge DevTools
DevTools proporciona un conjunto de características para inspeccionar, depurar y generar perfiles del código que usa una página web. DevTools también se puede usar para generar perfiles del código de la extensión.
En esta sección, aprenderá a usar la herramienta Rendimiento en DevTools para generar perfiles del script de contenido de la extensión. Para obtener más información sobre la herramienta Rendimiento , consulte Introducción a la herramienta rendimiento.
Para abrir DevTools, haga clic con el botón derecho en la página web y, a continuación, seleccione Inspeccionar. O bien, presione Ctrl+Mayús+I (Windows, Linux) o Comando+Opción+I (macOS). Se abre DevTools.
En DevTools, en la barra de actividad, seleccione la pestaña Rendimiento (). Si esa pestaña no está visible, seleccione Más herramientas () >Rendimiento.
Para empezar a grabar un perfil de rendimiento, haga clic en el botón Grabar ().
Vuelva a cargar la página para capturar los datos de generación de perfiles correspondientes al tiempo de carga de la página y, después, una vez que la página haya terminado de cargarse, haga clic en el botón Detener () para finalizar la grabación. DevTools muestra el perfil de rendimiento grabado:
Para buscar los eventos de rendimiento causados por el script de contenido, presione Ctrl+F en Windows/Linux o Comando+F en macOS. El cuadro de texto Buscar aparece en la parte inferior de la herramienta Rendimiento .
Escriba Evaluate script (Evaluar script ) y presione Entrar hasta que la herramienta Rendimiento resalte los eventos de rendimiento causados por el script de contenido. Sabrá que ha encontrado el evento de rendimiento correcto cuando la etiqueta Script del panel Resumen muestra el nombre del script de contenido:
Generación de perfiles del script de contenido mediante la herramienta de seguimiento perimetral
La herramienta de seguimiento perimetral, disponible en la edge://tracing
dirección URL, es una herramienta eficaz que puede proporcionar un análisis detallado del rendimiento de la extensión. En esta sección, aprenderá a usar la herramienta de seguimiento perimetral para comprender el impacto de la extensión en el tiempo de carga de la página. Para obtener más información sobre esta herramienta de seguimiento, que se basa en la herramienta Perfetto , consulte Perfetto UI en perfetto Tracing Docs.
Para abrir la herramienta de seguimiento perimetral, abra una nueva pestaña o ventana y vaya a
edge://tracing
. Se abre la interfaz de usuario de seguimiento.Para iniciar un nuevo seguimiento, en la esquina superior izquierda de la herramienta, haga clic en el botón Grabar . Se abre el cuadro de diálogo Grabar un nuevo seguimiento .
Seleccione el botón de opción Seleccionar manualmente la configuración . Aparece la lista de categorías.
Para capturar información detallada sobre la compilación y ejecución del script de contenido de la extensión, seleccione todas las categorías siguientes:
- Extensiones
- v8
- devtools
- devtools.timeline
Haga clic en el botón Grabar . El cuadro de diálogo se cierra y la herramienta de seguimiento perimetral comienza a grabar el seguimiento.
Abra una nueva pestaña y cargue una página web a la que afecta la extensión. La herramienta de seguimiento recopila datos sobre el impacto en el rendimiento de la extensión en la página web.
Abra la pestaña donde se ejecuta la herramienta de seguimiento perimetral y, a continuación, haga clic en el botón Detener . La nueva información de seguimiento aparece en la herramienta.
Filtrar los resultados
Los seguimientos que registra la herramienta de seguimiento de Edge proporcionan una gran cantidad de información sobre el explorador, así como sobre la extensión.
Para filtrar la información para mostrar solo lo que es relevante para la página web que ha afectado a la extensión:
En la
edge://tracing
página, presione Mayús+Esc para abrir el cuadro de diálogo Administrador de tareas del explorador .En el cuadro de diálogo Administrador de tareas del explorador , busque la pestaña correspondiente a la página web que afectó a la extensión y anote el número en la columna Id. de proceso . Cierre el cuadro de diálogo.
En la barra de herramientas de la herramienta de seguimiento perimetral, haga clic en Procesosy, a continuación, seleccione la casilla correspondiente al identificador de proceso que anotó. Desactive todas las demás casillas.
En la esquina superior derecha de la herramienta de seguimiento perimetral, haga clic en el campo de búsqueda, escriba ScriptInjection::InjectJS y, a continuación, presione Entrar repetidamente hasta que se resalte un evento correspondiente a la extensión en el panel inferior.
En el panel inferior se muestra la hora de inicio y la duración total del evento:
Buscar eventos clave
Para seguir analizando el impacto en el rendimiento del script de contenido de la extensión en la página web, busque los siguientes eventos clave dentro del evento ScriptInjection::InjectJS :
- v8.compile : muestra el tiempo de compilación del script de contenido.
- v8.run : indica el tiempo de ejecución del script compilado.
Agregue solo el código de script de contenido necesario para la funcionalidad de la extensión.
El script de contenido de la extensión se ejecuta en el contexto de la página web. Para minimizar el impacto del script de contenido en esa página web, asegúrese de agregar solo, en el script de contenido, la cantidad mínima de código que la extensión necesita ejecutar en el contexto de la página web. Audite el código en el script de contenido y quite marcos heredados, herramientas, bibliotecas u otro código que el script de contenido no necesita para ejecutarse en Microsoft Edge.
Puede usar técnicas de carga diferida y división de código para minimizar la cantidad de código que se ejecuta en el script de contenido:
La carga diferida es el proceso de cargar el código solo cuando es necesario, en función de las acciones del usuario, el contenido de la página o la lógica de extensión.
La división de código es el proceso de dividir el código en fragmentos más pequeños, o módulos, que se pueden cargar por separado o a petición.
Si la extensión es lo suficientemente pequeña, no necesitará una herramienta de compilación para dividir el código. Si la extensión es mayor y el código es más complejo de administrar, use una herramienta de compilación para dividir el código en fragmentos más pequeños. Las herramientas de compilación pueden ayudarle a organizar el código en unidades lógicas, que se pueden cargar a petición. Por ejemplo, puede usar webpack para dividir el código en puntos de entrada e importaciones dinámicas:
Los puntos de entrada se cargan en cada carga de página.
Las importaciones dinámicas solo se cargan a petición, como cuando el usuario interactúa con la página web o con la interfaz de usuario de la extensión:
// When the user clicks on the page. document.addEventListener("click", async () => { // Dynamically load the code that's needed to handle the click event. const module = await import("chunk.js"); // Do something with the newly loaded module code. });
Cargue solo el script de contenido en las páginas y marcos necesarios.
Es posible que la extensión no tenga que ejecutarse en todas las páginas web que visita el usuario. Para reducir la cantidad de código que se ejecuta cuando se cargan páginas web, configure la extensión para cargar scripts de contenido solo en las páginas y marcos donde se necesitan.
Para configurar las páginas y los marcos donde se cargan los scripts de contenido, defina patrones de dirección URL en el archivo de manifiesto de extensión mediante la matches
propiedad de la content_scripts
sección . Para obtener más información, consulte Inserción de scripts en scripts de contenido en la documentación de extensiones de Chrome.
También puede usar la chrome.scripting
API de extensiones para insertar mediante programación el script de contenido en la página web. Esta API permite insertar el script de contenido en función de las acciones del usuario, el contenido de la página web o la lógica de extensión. Para más información, consulte chrome.scripting en la documentación de extensiones de Chrome.
Use los siguientes procedimientos recomendados al configurar dónde se cargan los scripts de contenido:
Use los patrones de dirección URL más específicos posibles para las propiedades y
exclude_matches
en elmatches
archivo de manifiesto de extensión. Por ejemplo, si el script de contenido solo necesita ejecutarse en páginas web del dominio example.com, usehttps://example.com/*
en lugar de "*://*/*
.Para controlar si el script de contenido solo se ejecuta en el marco de nivel superior o también en marcos anidados de la página web que coincida con un patrón de dirección URL, use la propiedad en el
all_frames
archivo de manifiesto de extensión. De forma predeterminada, esta propiedad se establecefalse
en , lo que significa que el script de contenido solo se ejecutará en el marco de nivel superior. Si el script de contenido necesita tener acceso al DOM en marcos anidados o modificarlo, establezca esta propiedadtrue
en . Tenga en cuenta que la configuraciónall_frames
paratrue
aumenta la cantidad de código que se ejecuta en una página web.
Carga de scripts de contenido solo cuando sea necesario
Para reducir la cantidad de código que se carga y que se ejecuta en cada página web, y para ahorrar memoria y recursos de CPU, cargue solo los scripts de contenido cuando sea necesario, en lugar de en cada carga de página.
Configuración de cuándo cargar scripts de contenido en el archivo de manifiesto de extensión
Para controlar cuándo se debe cargar el script de contenido de la extensión, use la propiedad en el run_at
archivo de manifiesto de la extensión.
De forma predeterminada, esta propiedad se establece en el document_idle
valor , lo que significa que el script de contenido se cargará y se ejecutará una vez que la página haya terminado de cargarse y el DOM esté listo. Este es el valor recomendado para la mayoría de los scripts de contenido. El document_idle
valor garantiza que el script de contenido no interferirá con el proceso de carga de páginas.
Para cargar y ejecutar el script de contenido antes de que la página esté totalmente cargada, use los document_start
valores o document_end
. Estos valores son útiles en casos como la modificación del diseño o el estilo de la página web, pero también pueden causar problemas de rendimiento o problemas de compatibilidad con otros scripts de la página.
Carga mediante programación de scripts de contenido en tiempo de ejecución
Para cargar mediante programación los scripts de contenido en tiempo de ejecución, solo cuando sea necesario, use la chrome.scripting
API . La chrome.scripting
API proporciona más control sobre cuándo y dónde se carga el script de contenido.
Por ejemplo, puede usar la API para cargar el chrome.scripting
script de contenido solo después de que el usuario haya interactuado con la página web o la interfaz de usuario de extensión, como al hacer clic en el botón de una extensión o al hacer clic en una parte de la página web.
Si usa la chrome.scripting
API cuando el usuario interactúa con la página web, asegúrese de considerar cuidadosamente si necesita cargar repetidamente el script de contenido cada vez que se produzca la interacción. La carga de scripts de contenido con demasiada frecuencia puede provocar problemas o errores en la experiencia del usuario.
Evitar el bloqueo de llamadas o tareas sincrónicas de ejecución prolongada
El bloqueo de llamadas y tareas sincrónicas de ejecución prolongada puede retrasar la carga de la página web o ralentizar otros aspectos de una página web, así como afectar negativamente a la capacidad de respuesta de la interfaz de usuario.
Las llamadas de bloqueo son operaciones de JavaScript que impiden la ejecución de otro código hasta que se completan. Por ejemplo, el uso de las XMLHttpRequest
API , localStorage
o chrome.storage.sync
(que son sincrónicas) impide que la página web ejecute otro código.
Las tareas sincrónicas de ejecución prolongada son tareas sincrónicas que tardan mucho tiempo en completarse, lo que impide que el explorador ejecute otro código de página web mientras se ejecutan. Esto puede incluir cálculos complejos, bucles o manipulaciones de cadenas.
Use código asincrónico o no de bloqueo, como Fetch API, JavaScript Promises o Web Workers siempre que sea posible. El código asincrónico o sin bloqueo permite la ejecución de otro código mientras se espera la finalización de una tarea, sin bloquear el proceso del explorador que ejecuta la página web.
Tenga en cuenta que, aunque el uso de trabajos web para mover la lógica de código compleja a otro subproceso es una buena práctica, es posible que siga ralentizando los dispositivos que tienen un número bajo de núcleos de CPU o que ya están ocupados.
A continuación se muestra un ejemplo con fetch API. Mientras se capturan los datos, el explorador no está bloqueado y puede ejecutar otro código:
// Asynchronously load data from a JSON file.
fetch("data.json")
.then(response => response.json())
.then(data => {
// Do something with the data.
});
Almacenar datos de forma asincrónica
Para almacenar datos en la extensión, use la chrome.storage.local
API en lugar de la localStorage
API, que es una API sincrónica. La chrome.storage.local
API es asincrónica y puede almacenar y recuperar datos de forma más eficaz, sin afectar al rendimiento de la página web donde se ejecuta la extensión. Por ejemplo, puede usar el chrome.storage.local.get
método para recuperar un valor almacenado anteriormente y, a continuación, usar el resultado en una función de devolución de llamada:
chrome.storage.local.get("key", result => {
// Do something with the result.
});
Envío asincrónico de mensajes
Para comunicarse entre el script de contenido y la página en segundo plano de la extensión, u otro script de contenido, use los chrome.runtime.sendMessage
métodos o chrome.tabs.sendMessage
. Estos métodos son asincrónicos y no bloquean, y permiten enviar y recibir mensajes entre las distintas partes de la extensión. Puede usar promesas o devoluciones de llamada para controlar la respuesta de los mensajes. Por ejemplo, puede usar el chrome.runtime.sendMessage
método para enviar un mensaje a la página en segundo plano y, a continuación, usar el objeto devuelto Promise
para procesar la respuesta:
chrome.runtime.sendMessage({type: 'request', data: 'some data'})
.then(response => {
// Do something with the response.
});
Ejecución de tareas intensivas fuera del subproceso principal
Use Trabajos web para ejecutar tareas intensivas en el script de contenido sin bloquear el subproceso que usa el explorador para representar la página web. Mediante trabajos web, el código que ejecuta las tareas intensivas se ejecuta en un subproceso independiente. Los trabajos web pueden mejorar el rendimiento y la capacidad de respuesta del script de contenido y de las páginas web en las que se ejecuta.
Tenga en cuenta que la creación de un trabajo web crea un nuevo subproceso, que usa nuevos recursos en los dispositivos. El uso de demasiados recursos en dispositivos de gama baja puede provocar problemas de rendimiento.
Para comunicarse entre el script de contenido y Web Worker, use las postMessage
API y onmessage
. Por ejemplo, para crear un nuevo trabajo web y enviarle un mensaje, use el código siguiente:
// Create a new Web Worker.
cons worker = new Worker('worker.js');
// Send a message to the Web Worker.
worker.postMessage({type: 'task', data: 'some data'});
Para recibir mensajes en el trabajo web y enviar mensajes de vuelta:
// Listen to messages that are sent to the Web Worker.
onmessage = event => {
const type = event.data.type;
const data = event.data.data;
// Do something with the type and data.
// ...
// Send a message back.
postMessage({type: 'result', data: 'some result'});
};
Recursos adicionales
Documentos de extensión de Chrome:
MDN: