Como o provedor de recomendações de conteúdo Taboola usou o LoAF para melhorar o INP em até 36% para os sites parceiros editores.

Como o uso da API Long Animation Frames (LoAF) e a adoção de uma estratégia de rendimento inteligente permitiu que a Taboola melhorasse a capacidade de resposta do site dos editores sem comprometer a performance dos anúncios.

David Belford
David Belford

Interação com a próxima exibição (INP, na sigla em inglês) é uma métrica que avalia a capacidade de resposta de um site à entrada do usuário. O INP mede o tempo desde o início de uma interação (como ao clicar, tocar ou digitar) até o feedback visual resultante. O INP deve substituir a latência na primeira entrada (FID, na sigla em inglês) como Core Web Vitals em março de 2024 (link em inglês).

A Taboola é a maior plataforma de descoberta de conteúdo do mundo, gerando 500 mil recomendações a cada segundo na Web aberta. Essas recomendações permitem que os 9.000 editores parceiros exclusivos da Taboola gerem receita e engajem seus públicos-alvo. Os editores renderizam recomendações nas páginas usando JavaScript.

Como o JavaScript de terceiros pode afetar a capacidade de uma página de responder rapidamente à entrada do usuário, o Taboola investiu muito na redução do tamanho dos arquivos JavaScript e do tempo de execução. O Taboola está redesenhando todo o seu mecanismo de renderização, além de usar APIs de navegador diretamente, sem abstrações, para minimizar o impacto no INP.

Este estudo de caso abrange a jornada de Taboola para melhorar o INP usando a nova API Long Animation Frames (LoAF) para medir seu impacto na capacidade de resposta da página no campo e os esforços subsequentes para aplicar otimizações específicas para melhorar a experiência do usuário.

TBT como substituto do INP

O Tempo total de bloqueio (TBT, na sigla em inglês) é uma métrica com base em laboratório que identifica onde a linha de execução principal ficou bloqueada por tempo suficiente para afetar a capacidade de resposta da página. As métricas de campo que medem a capacidade de resposta, como o INP, podem ser afetadas por um TBT alto. Uma investigação feita por Annie Sullivan sobre a correlação entre TBT e INP em dispositivos móveis indica que os sites têm mais chances de alcançar boas pontuações de INP quando o tempo de bloqueio da linha de execução principal é minimizado.

Essa correlação, aliada às preocupações dos editores com o alto TBT, levou a Taboola a concentrar sua atenção em minimizar sua contribuição para essa métrica.

Captura de tela de uma auditoria do Lighthouse para tempo da linha de execução principal bloqueado. A linha de execução principal foi bloqueada por vários scripts durante 2.630 milissegundos, e o JavaScript de terceiros contribuiu com 712 milissegundos para esse tempo. O script release.js do Taboola é responsável pela maior parte do tempo de bloqueio de terceiros em 691 milissegundos.
Com o mecanismo antigo do Taboola, scripts como RELEASE.js bloqueiam a linha de execução principal por 691 milissegundos.

Usando o TBT como métrica alternativa para o INP, a Taboola começou a monitorar e otimizar o tempo de execução do JavaScript para limitar o possível impacto nas Core Web Vitals. Ela começou fazendo o seguinte:

  • Identificar e otimizar scripts problemáticos no campo usando a API Long Tasks.
  • Estimar contribuições de TBT usando a PageSpeed Insights API para avaliar de 10 a 15 mil URLs por dia.

No entanto, Taboola notou que analisar o TBT com essas ferramentas tinha algumas limitações:

  • A API Long Tasks não pode atribuir a tarefa ao domínio de origem ou a um script específico, dificultando a identificação das origens de tarefas longas.
  • A API Long Tasks identifica apenas tarefas longas, em vez de uma combinação de tarefas e mudanças de layout que podem causar um atraso na renderização.

Para enfrentar esses desafios, o Taboola participou do teste de origem da API Long Animation Frames (LoAF) para entender melhor o impacto real do impacto na capacidade de resposta da entrada do usuário. Os testes de origem dão acesso a recursos novos ou experimentais, permitindo que os desenvolvedores testem recursos emergentes que os usuários podem testar por um tempo limitado.

É essencial destacar que o aspecto mais difícil desse desafio foi melhorar com sucesso o INP sem comprometer nenhum KPI(indicador principal de desempenho) de anúncios ou causar atrasos nos recursos para nossos editores.

Como usar o LoAF para avaliar o impacto do INP

Um frame de animação longo ocorre quando uma atualização de renderização é atrasada em mais de 50 milissegundos. Ao identificar as causas de atualizações lentas da interface do usuário, em vez de apenas tarefas longas, a Taboola conseguiu analisar o impacto na capacidade de resposta da página em campo. Observar o LoAF permitiu que Taboola:

  1. Atribuir entradas a tarefas específicas do Taboola.
  2. Observe problemas de desempenho em recursos específicos antes de implantá-los na produção.
  3. Colete dados agregados para comparar diferentes versões de código em testes A/B e gerar relatórios sobre as principais métricas de sucesso.

O JavaScript a seguir é uma versão simplificada usada na produção para coletar LoAF para isolar o impacto do Taboola.

function loafEntryAnalysis (entry) {
  if (entry.blockingDuration === 0) {
    return;
  }

  let taboolaIsMajor = false;
  const hasInteraction = entry.firstUIEventTimestamp > 0;
  let taboolaDuration = 0;
  const nonTaboolaLoafReport = {};
  const taboolaLoafReport = {};

  entry.scripts.forEach((script) => {
    const taboolaScriptBlockingDuration = handleLongAnimationFrameScript(script, taboolaLoafReport, nonTaboolaLoafReport);
    taboolaDuration += taboolaScriptBlockingDuration;

    if (taboolaScriptBlockingDuration > 0 || taboolaDuration > entry.duration / 2) {
      taboolaIsMajor = true;
    }
  });

  generateToboolaLoafReport(taboolaLoafReport, nonTaboolaLoafReport, hasInteraction, taboolaIsMajor);

  if (hasInteraction) {
    const global = _longAnimationFramesReport.global;
    global.inpBlockingDuration = Math.max(global.inpBlockingDuration, entry.blockingDuration);

    if (taboolaIsMajor) {
      global.taboolaInpBlockingDuration = Math.max(global.taboolaInpBlockingDuration, entry.blockingDuration);
    }
  }
}

const observer = new PerformanceObserver(list => {
  for (const entry of list.getEntries()) {
    loafEntryAnalysis(entry);
  }
});

observer.observe({ type: 'long-animation-frame', buffered: true });
  • O uso da função loafEntryAnalysis permitiu que o Taboola identificasse as entradas em que ele é uma das principais influências.
  • O Taboola é considerado um dos principais responsáveis se mais da metade da duração total do script for causada pelo Taboola ou se um script do Taboola levar mais de 50 milissegundos para ser executado.
  • Uma firstUIEventTimeStamp será gerada se a interação do usuário for atrasada devido a um frame de animação longo. A duração de bloqueio mais longa é considerada a pontuação INP geral. Também podemos identificar quando o Taboola acionou um firstUIEventTimeStamp para calcular uma pontuação INP do Taboola.

Os dados coletados com o LoAF ajudaram o Taboola a criar a tabela de atribuição a seguir, que identifica áreas onde pode aplicar oportunidades de rendimento.

Script Duração (milissegundos)
vpaid/units/33_6_8/infra/cmTagINLINE_INSTREAM.js:106517 997
vpaid/units/33_6_8/infra/cmTagFEED_MANAGER.js:496662 561
vpaid/vPlayer/player/v15.8.6/OvaMediaPlayer.js:44631 336
libtrc/impl.20231212-23-RELEASE.js:821090 857
publisher_name/pmk-20220605.5.js:7728 336
libtrc/card-interference-detector.20231219-7-RELEASE.es6.js:183 239
Entradas do script LoAF capturadas pelo Taboola RUM

TRECS Engine: a nova estratégia de rendimento

Além de usar o LoAF para entender melhor as oportunidades de otimização de script, a Taboola vem redesenhando todo o mecanismo de renderização para minimizar significativamente a execução do JavaScript e o tempo de bloqueio.

O TRECS (Taboola Recommendations Extensible Client Service) mantém a renderização do lado do cliente e o código JS atual do editor, além de reduzir o número e o tamanho dos arquivos obrigatórios necessários para carregar as recomendações do Taboola.

Depois que as tarefas de bloqueio de renderização são identificadas com o LoAF, o "Esmaecimento de desempenho" pode dividir essas tarefas antes de ceder à linha de execução principal usando scheduler.postTask(). Esse design garante que trabalhos essenciais voltados ao usuário, como atualizações de renderização, possam ser executados o mais rápido possível, independentemente de tarefas atuais que possam estar ocupando a linha de execução principal.

Este é o snippet em JS do executor de tarefas "Performance Fader":

/**
* Send a task to run using the Fader. The task will run using the browser Scheduler, by the configuration settings, or immediately.
* @param task
* @param isBlocker
*/
function sendTaskToFader (task, isBlocker = true) {
  const publisherFaderChoice = fillOptimizationGlobals(); // Loading publisher choice
  const applyYielding = publisherFaderChoice === OptimizationFaderType.Responsiveness;

  if (applyYielding) {
    return runAsPostTask(task, isBlocker);
  }

  return runImmediately(task);
}

/**
* Yielding method using scheduler.postTask and falling back to setTimeout when it's not availabe based on the publisher choice
*/
function runAsPostTask (task, isBlocker = true) {
  if ('scheduler' in window && 'postTask' in scheduler) {
    const priority = isBlocker ? 'user-blocking': 'background';

    return window?.scheduler?.postTask(task, { priority });
  }

  const publisherChoiceEnableFallback = fillPublisherChoices();

  if (publisherChoiceEnableFallback) {
    return new Promise(resolve => {
      window.setTimeout(() => {
        resolve(task());
      }, 0);
    });
  }

  return runImmediately(task);
}

A função sendTaskToFader:

  • Usa runAsPostTask, que usa scheduler.postTask() internamente (se a API estiver disponível) ou volta para setTimeout.
  • Essa função encapsula chamadas de função em seções de código que causam frames de animação longos e INP. Ele divide as seções de código em tarefas mais curtas, reduzindo o INP.

Métricas de negócios

Graças ao LoAF, a Taboola conseguiu entender melhor o impacto dela na INP. A ferramenta também destacou oportunidades de otimização de script que poderiam ser usadas como parte do novo mecanismo TRECS.

Para determinar o impacto do TRECS e do Performance Fader, a Taboola realizou um teste A/B medindo o INP em relação ao mecanismo atual sem gerar resultados em um painel de editores parceiros.

A tabela a seguir mostra resultados de INP em milissegundos no 75o percentil de quatro editores anônimos na rede Taboola.

Editores INP com TRECS + Fader de desempenho INP com o mecanismo atual Diminuição do INP (%)
Editor A 48 75 36%
Editor B 153 163 6%
Editor C 92 135 33%
Editor D 37 52 29%

Felizmente, as métricas de negócios, como taxa de cliques do anúncio e receita por mil impressões (RPM), não foram afetadas negativamente quando o TRECS e o desaparecimento gradativo foram ativados no painel de testes. Com essa melhoria positiva no INP sem nenhum resultado negativo como esperado nos KPIs de anúncios, a Taboola vai melhorar gradualmente a percepção dos editores sobre o produto.

Outra execução do Lighthouse para o mesmo cliente, destacada anteriormente, demonstra uma melhoria significativa no tempo de bloqueio da linha de execução principal pelo Taboola ao usar o novo mecanismo.

Captura de tela de uma auditoria do Lighthouse para tempo de execução principal bloqueado depois que os novos mecanismos TRECS e Performance Fader foram aplicados para melhorar o tempo de bloqueio da linha de execução principal. A auditoria foi reduzida para apenas 206 milissegundos, em comparação com 712 antes das otimizações.
O novo mecanismo do Taboola ajudou scripts como o RELEASE.js a reduzir o TBT em 485 ms (-70%).

Isso demonstra que o uso do LoAF para identificar causas de INP e implantar as técnicas de rendimento subsequentes com o Fader de desempenho permite que os parceiros da Taboola alcancem o máximo de sucesso no desempenho dos anúncios e da página.

Conclusão

Otimizar o INP é um processo complexo, especialmente quando scripts de terceiros são usados em sites parceiros. Antes da otimização começar, a atribuição do INP a scripts específicos remove quaisquer suposições e possíveis danos a outras métricas de desempenho do site.A API LoAF provou ser uma ferramenta valiosa para identificar e resolver problemas de INP, especialmente para terceiros incorporados, permitindo identificar oportunidades específicas de melhoria do SDK e eliminar interferências de outras tecnologias presentes na página.

Quando usada com uma boa estratégia de rendimento, como scheduler.postTask(), o LoAF pode ajudar você a observar e entender a causa da baixa capacidade de resposta da página, o que, por sua vez, fornece as informações necessárias para melhorar o INP do seu site.

Agradecimentos especiais a Gilberto Cocchi, Noam Rosenthal e Rick Viscomi do Google, e Dedi Hakak, Anat Dagan e Omri Ariav da equipe de Engenharia e Produtos da Taboola pela contribuição para esse trabalho.