Minimizar o impacto de uma extensão no tempo de carregamento da página

Scripts de conteúdo são arquivos JavaScript que sua extensão injeta em páginas da Web e que são executados no contexto dessas páginas da Web. Usando scripts de conteúdo, sua extensão pode acessar e modificar uma página da Web renderizada lendo ou alterando o DOM.

Os scripts de conteúdo podem, no entanto, ter um impacto perceptível no desempenho de uma página da Web, por exemplo, diminuindo o tempo de carregamento da página. Isso pode acontecer se o script de conteúdo executar muito código enquanto a página está carregando.

Este artigo fornece práticas recomendadas que podem ajudá-lo a minimizar o impacto sobre o desempenho da sua extensão nas páginas da Web que os usuários visitam.

Traçar o perfil do script de conteúdo da sua extensão

Para criar o perfil do desempenho do script de conteúdo da extensão, use o Microsoft Edge DevTools ou a ferramenta de rastreamento do Edge, conforme descrito nas seções a seguir.

Criar perfil do seu script de conteúdo usando o DevTools do Microsoft Edge

O DevTools fornece um conjunto de recursos para inspecionar, depurar e criar perfil do código que uma página da Web usa. O DevTools também pode ser usado para criar o perfil do código da sua extensão.

Nesta seção, você aprenderá a usar a ferramenta Desempenho no DevTools para criar o perfil do script de conteúdo da sua extensão. Para saber mais sobre a ferramenta Desempenho, consulte Analisar o desempenho do tempo de execução (tutorial).

  1. Para abrir o DevTools, clique com o botão direito do mouse na página da Web e selecione Inspecionar. Ou pressione Ctrl+Shift+I (Windows, Linux) ou Command+Option+I (macOS). O DevTools é aberto.

  2. No DevTools, na Barra de Atividades, selecione a guia Desempenho (ícone da ferramenta Desempenho). Se essa guia não estiver visível, selecione Mais ferramentas (ícone de Mais ferramentas) >Desempenho.

  3. Para iniciar a gravação de um perfil de desempenho, clique no botão Gravar (ícone de gravação).

  4. Recarregue a página para capturar os dados de criação de perfil que correspondem ao tempo de carregamento da página e, quando a página terminar de carregar, clique no botão Parar (ícone Parar) para encerrar a gravação. O DevTools exibe o perfil de desempenho gravado:

    O perfil de desempenho gravado exibido na ferramenta Desempenho do DevTools

  5. Para procurar os eventos de desempenho causados pelo script de conteúdo, pressione Ctrl+F no Windows/Linux ou Command+F no macOS. A caixa de texto Localizar aparece na parte inferior da ferramenta Desempenho .

  6. Digite Avaliar script e pressione Enter até que a ferramenta Desempenho realce os eventos de desempenho causados pelo script de conteúdo. Você saberá que encontrou o evento de desempenho correto quando o rótulo Script no painel Resumo mostrar o nome do script de conteúdo:

    O evento Avaliar desempenho do script devido ao script de conteúdo da extensão em execução durante o carregamento da página

Criar perfil do seu script de conteúdo usando a ferramenta de rastreamento de borda

A ferramenta de rastreamento de borda, disponível na edge://tracing URL, é uma ferramenta poderosa que pode fornecer uma análise detalhada do desempenho da extensão. Nesta seção, você aprenderá a usar a ferramenta de rastreamento de borda para entender o impacto de sua extensão no tempo de carregamento da página. Para saber mais sobre essa ferramenta de rastreamento, que se baseia na ferramenta Perfetto , consulte Perfetto UI nos documentos de rastreamento do Perfetto.

  1. Para abrir a ferramenta de Rastreamento de bordas, abra uma nova guia ou janela e vá para edge://tracing. A interface do usuário de rastreamento é aberta.

  2. Para iniciar um novo rastreamento, no canto superior esquerdo da ferramenta, clique no botão Gravar . A caixa de diálogo Registrar um novo rastreamento é aberta.

  3. Selecione o botão de opção Selecionar configurações manualmente . A lista de categorias é exibida.

  4. Para capturar informações detalhadas sobre a compilação e execução do script de conteúdo da sua extensão, selecione todas as seguintes categorias:

    • extensões
    • v8
    • DevTools
    • devtools. linha do tempo
  5. Clique no botão Gravar . A caixa de diálogo é fechada e a ferramenta de Rastreamento de borda começa a gravar o rastreamento.

  6. Abra uma nova guia e carregue uma página da Web afetada pela sua extensão. A ferramenta de rastreamento coleta dados sobre o impacto no desempenho da sua extensão na página da Web.

  7. Abra a guia em que a ferramenta de rastreamento de borda está sendo executada e clique no botão Parar . As novas informações de rastreamento aparecem na ferramenta.

Filtrar os resultados

Os rastreamentos registrados pela ferramenta de rastreamento do Edge fornecem muitas informações sobre o navegador, bem como sua extensão.

Para filtrar as informações para mostrar apenas o que é relevante para a página da Web que sua extensão afetou:

  1. edge://tracing Na página, pressione Shift+Esc para abrir a caixa de diálogo Gerenciador de Tarefas do Navegador.

  2. Na caixa de diálogo Gerenciador de Tarefas do Navegador , pesquise a guia que corresponde à página da Web que sua extensão afetou e anote o número na coluna ID do Processo . Feche a caixa de diálogo.

  3. Na barra de ferramentas da ferramenta de rastreamento de borda, clique em Processos e marque a caixa de seleção que corresponde à ID do processo que você anotou. Desmarque todas as outras caixas de seleção.

  4. No canto superior direito da ferramenta de rastreamento de borda, clique no campo de pesquisa, digite ScriptInjection::InjectJS e pressione Enter repetidamente até que um evento que corresponda à sua extensão seja realçado no painel inferior.

    O painel inferior exibe a hora de início e a duração total do evento:

    A ferramenta de rastreamento de borda mostrando um evento de injeção de script

Procure os principais eventos

Para continuar analisando o impacto no desempenho do script de conteúdo da sua extensão na página da Web, procure os seguintes eventos principais dentro do evento ScriptInjection::InjectJS :

  • v8.compile - mostra o tempo de compilação do seu script de conteúdo.
  • v8.run - Indica o tempo de execução do script compilado.

Adicione apenas o código de script de conteúdo necessário para a funcionalidade da sua extensão

O script de conteúdo da extensão é executado no contexto da página da Web. Para minimizar o impacto do script de conteúdo nessa página da Web, certifique-se de adicionar apenas, no script de conteúdo, a quantidade mínima de código que sua extensão precisa executar no contexto da página da Web. Audite o código em seu script de conteúdo e remova estruturas, ferramentas, bibliotecas ou outros códigos herdados que não são necessários para que seu script de conteúdo seja executado no Microsoft Edge.

Você pode usar técnicas de carregamento lento e divisão de código para minimizar a quantidade de código que é executado em seu script de conteúdo:

  • O carregamento lento é o processo de carregar seu código somente quando necessário, com base nas ações do usuário, no conteúdo da página ou na lógica da extensão.

  • A divisão de código é o processo de dividir seu código em partes menores, ou módulos, que podem ser carregados separadamente ou sob demanda.

Se sua extensão for pequena o suficiente, você não precisará de uma ferramenta de build para dividir seu código. Se sua extensão for maior e se seu código for mais complexo de gerenciar, use uma ferramenta de build para dividir seu código em partes menores. As ferramentas de build podem ajudá-lo a organizar seu código em unidades lógicas, que podem ser carregadas sob demanda. Por exemplo, você pode usar webpack para dividir seu código em pontos de entrada e importações dinâmicas:

  • Os pontos de entrada são carregados em cada carregamento de página.

  • As importações dinâmicas só são carregadas sob demanda, como quando o usuário interage com a página da Web ou com a interface do usuário da extensão:

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

Carregue seu script de conteúdo apenas nas páginas e quadros necessários

Talvez sua extensão não precise ser executada em todas as páginas da Web que o usuário visita. Para reduzir a quantidade de código executado quando as páginas da Web são carregadas, configure sua extensão para carregar scripts de conteúdo somente nas páginas e quadros em que eles são necessários.

Para configurar as páginas e os quadros em que seus scripts de conteúdo são carregados, defina padrões de URL no arquivo de manifesto de extensão usando a matches propriedade na content_scripts seção. Para saber mais, consulte Injetar com declarações estáticas em Scripts de conteúdo na documentação de extensões do Chrome.

Você também pode usar a API de chrome.scripting extensões para injetar programaticamente seu script de conteúdo na página da Web. Essa API permite que você injete seu script de conteúdo com base nas ações do usuário, no conteúdo da página da Web ou na lógica da extensão. Para saber mais, consulte chrome.scripting na documentação das extensões do Chrome.

Use as seguintes práticas recomendadas ao configurar onde seus scripts de conteúdo são carregados:

  • Use os padrões de URL mais específicos possíveis para as propriedades e exclude_matches no seu arquivo de manifesto matches de extensão. Por exemplo, se o script de conteúdo só precisar ser executado em páginas da Web do domínio example.com, use https://example.com/* em vez de "*://*/*.

  • Para controlar se o script de conteúdo é executado apenas no quadro de nível superior ou também em quadros aninhados da página da Web que correspondem a um padrão de URL, use a propriedade no arquivo de manifesto all_frames de extensão.

    • Por padrão, all_frames é false, o que significa que seu script de conteúdo só será executado no quadro de nível superior.

    • Se o script de conteúdo precisar acessar ou modificar o DOM em quadros aninhados, defina all_frames como true. Isso aumenta a quantidade de código que é executado em uma página da Web.

Carregue scripts de conteúdo somente quando necessário

Para reduzir a quantidade de código carregado e executado em cada página da Web e economizar memória e recursos de CPU, carregue seus scripts de conteúdo apenas quando necessário, em vez de em cada carregamento de página.

Configurar quando carregar scripts de conteúdo em seu arquivo de manifesto de extensão

Para controlar quando o script de conteúdo da sua extensão deve ser carregado, use a propriedade no arquivo de manifesto run_at da sua extensão.

Por padrão, essa propriedade é definida como o document_idle valor, o que significa que o script de conteúdo será carregado e executado depois que a página terminar de carregar e o DOM estiver pronto. Esse é o valor recomendado para a maioria dos scripts de conteúdo. O document_idle valor garante que o script de conteúdo não interfira no processo de carregamento da página.

Para carregar e executar o script de conteúdo antes que a página esteja totalmente carregada, use os document_start valores ou document_end . Esses valores são úteis em casos como modificar o layout ou o estilo da página da Web, mas também podem causar problemas de desempenho ou de compatibilidade com outros scripts na página.

Carregar programaticamente scripts de conteúdo em tempo de execução

Para carregar programaticamente seus scripts de conteúdo em tempo de execução, somente quando necessário, use a chrome.scripting API . A chrome.scripting API fornece mais controle sobre quando e onde seu script de conteúdo é carregado.

Por exemplo, você pode usar a API para carregar o chrome.scripting script de conteúdo somente depois que o usuário interagir com a página da Web ou a interface do usuário da extensão, como ao clicar no botão de uma extensão ou clicar em uma parte da página da Web.

Se você usar a chrome.scripting API quando o usuário interagir com a página da Web, considere cuidadosamente se precisa carregar repetidamente seu script de conteúdo toda vez que a interação acontecer. Carregar scripts de conteúdo com muita frequência pode causar problemas ou erros na experiência do usuário.

Evite bloquear chamadas ou executar tarefas síncronas de longa duração

O bloqueio de chamadas e tarefas síncronas de longa duração pode atrasar o carregamento da página da Web ou tornar outros aspectos de uma página da Web mais lentos, além de afetar negativamente a capacidade de resposta da interface do usuário.

As chamadas de bloqueio são operações JavaScript que impedem a execução de outro código até que sejam concluídas. Por exemplo, usar as XMLHttpRequestAPIs , localStorage, ou chrome.storage.sync (que são síncronas) impede que a página da Web execute outro código.

Tarefas síncronas de longa execução são tarefas síncronas que levam muito tempo para serem concluídas, impedindo que o navegador execute outro código de página da Web enquanto elas estão em execução. Isso pode incluir cálculos complexos, loops ou manipulações de cadeia de caracteres.

Use código assíncrono ou sem bloqueio, como a API de Busca, Promessas JavaScript ou Web Workers, sempre que possível. O código assíncrono ou sem bloqueio permite a execução de outro código enquanto aguarda a conclusão de uma tarefa, sem bloquear o processo do navegador que executa a página da Web.

Embora o uso de Web Workers para mover sua lógica de código complexo para outro encadeamento seja uma boa prática, ele ainda pode reduzir a velocidade de dispositivos que têm uma contagem baixa de núcleos de CPU ou que já estão ocupados.

Abaixo está um exemplo usando a API de Busca. Enquanto os dados estão sendo buscados, o navegador não está bloqueado e pode executar outro código:

// Asynchronously load data from a JSON file.
fetch("data.json")
  .then(response => response.json())
  .then(data => {
    // Do something with the data.
  });

Armazenar dados de forma assíncrona

Para armazenar dados em sua extensão, use a chrome.storage.local API em vez da localStorage API, que é uma API síncrona. A chrome.storage.local API é assíncrona e pode armazenar e recuperar dados com mais eficiência, sem afetar o desempenho da página da Web em que a extensão está sendo executada. Por exemplo, você pode usar o chrome.storage.local.get método para recuperar um valor armazenado anteriormente e, em seguida, usar o resultado em uma função de retorno de chamada:

chrome.storage.local.get("key", result => {
  // Do something with the result.
});

Enviar mensagens de forma assíncrona

Para se comunicar entre o script de conteúdo e a página de plano de fundo da extensão ou um outro script de conteúdo, use os chrome.runtime.sendMessage métodos or chrome.tabs.sendMessage . Esses métodos são assíncronos e sem bloqueio, e permitem que você envie e receba mensagens entre as diferentes partes da sua extensão. Você pode usar promessas ou retornos de chamada para lidar com a resposta das mensagens. Por exemplo, você pode usar o chrome.runtime.sendMessage método para enviar uma mensagem para a página de plano de fundo e, em seguida, usar o objeto retornado Promise para processar a resposta:

chrome.runtime.sendMessage({type: 'request', data: 'some data'})
  .then(response => {
    // Do something with the response.
  });

Executar tarefas intensivas fora do thread principal

Use Trabalhos da Web para executar tarefas intensivas em seu script de conteúdo sem bloquear o thread que o navegador usa para renderizar a página da Web. Usando Web Workers, o código que executa as tarefas intensivas é executado em um thread separado. Os Web Workers podem melhorar o desempenho e a capacidade de resposta do seu script de conteúdo e das páginas da Web em que ele é executado.

A criação de um Web Worker cria um novo thread, que usa novos recursos nos dispositivos. O uso de muitos recursos em dispositivos de baixo custo pode levar a problemas de desempenho.

Para se comunicar entre o script de conteúdo e o Web Worker, use as postMessage APIs and onmessage . Por exemplo, para criar um novo Web Worker e enviar uma mensagem a ele, use o seguinte código:

// 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 receber mensagens no seu Web Worker e enviá-las de volta:

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

Confira também

Documentos da extensão do Chrome:

MDN: