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 a API Long Animation Frames (LoAF) e a adoção de uma estratégia de rendimento inteligente permitiram que a Taboola melhorasse a capacidade de resposta dos sites dos editores sem comprometer a performance dos anúncios.

David Belford
David Belford

A métrica Interaction to Next Paint (INP) avalia a capacidade de resposta de um site em relação à entrada do usuário. O INP mede o tempo entre o início de uma interação do usuário, como clicar, tocar ou digitar, até o feedback visual resultante. A INP vai substituir o First Input Delay (FID) como uma Core Web Vital em março de 2024.

A Taboola é a plataforma de descoberta de conteúdo líder mundial, que gera 500 mil recomendações por segundo na Web aberta. Com essas recomendações,os 9.000 parceiros de editores exclusivos da Taboola podem gerar receita e engajar os 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 responder rapidamente à entrada do usuário, a Taboola investiu muito na redução do tamanho dos arquivos JavaScript e do tempo de execução. A Taboola reformulou todo o mecanismo de renderização e passou a usar APIs do navegador diretamente, sem abstrações, para minimizar o impacto no INP.

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

TBT como proxy de INP

O Tempo total de bloqueio (TBT, na sigla em inglês) é uma métrica baseada em laboratório que identifica onde a linha de execução principal foi 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 a INP, podem ser afetadas por um TBT alto. Uma investigação de 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, combinada com as preocupações dos editores da Taboola em relação ao TBT alto, fez com que a empresa se concentrasse em minimizar a contribuição para essa métrica.

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

Usando a TBT como métrica de proxy para a INP, a Taboola começou a monitorar e otimizar o tempo de execução do JavaScript para limitar o impacto potencial nas Core Web Vitals. Eles começaram fazendo o seguinte:

  • Identifique e otimize scripts problemáticos no campo usando a API Long Tasks.
  • Estimar as contribuições de TBT usando a API PageSpeed Insights para avaliar de 10.000 a 15.000 URLs por dia.

No entanto, a Taboola percebeu que a análise de TBT com essas ferramentas tinha algumas limitações:

  • A Long Tasks API não pode atribuir a tarefa ao domínio de origem ou a um script específico, o que dificulta 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, a Taboola participou do teste de origem da API Long Animation Frames (LoAF) para entender melhor o impacto real na capacidade de resposta à 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 tempo limitado.

O aspecto mais difícil desse desafio foi melhorar o INP sem comprometer nenhum KPI de anúncios(indicador principal de desempenho) ou causar atrasos nos recursos dos nossos editores.

Como usar a LoAF para avaliar o impacto da INP

Um frame de animação longo ocorre quando uma atualização de renderização é atrasada por 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 no campo. Com a observação de LoAF, a Taboola conseguiu:

  1. Atribuir entradas a tarefas específicas da 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 informe as principais métricas de sucesso.

O JavaScript a seguir é uma versão simplificada usada na produção para coletar LoAF e isolar o impacto da 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 a Taboola identificasse entradas em que ela é uma grande colaboradora.
  • A Taboola é considerada uma grande colaboradora se mais da metade da duração total do script for causada por ela ou se um script da Taboola levar mais de 50 milissegundos para ser executado.
  • Um firstUIEventTimeStamp é gerado se a interação do usuário for atrasada devido a um frame de animação longo. A maior duração de bloqueio é considerada a pontuação geral de INP. Também podemos identificar quando a Taboola acionou uma firstUIEventTimeStamp para calcular uma pontuação de INP da Taboola.

Os dados coletados com o LoAF ajudaram a Taboola a criar a tabela de atribuição a seguir, que identifica áreas em que é possível aplicar oportunidades produtivas.

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 de script LoAF capturadas pelo RUM da Taboola

Motor TRECS: a nova estratégia de rendimento

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

O serviço de cliente extensível das recomendações da Taboola (TRECS, na sigla em inglês) 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 da Taboola.

Depois que as tarefas de bloqueio de renderização forem identificadas usando o LoAF, o "Performance Fader" poderá dividir essas tarefas antes de passar para a linha de execução principal usando scheduler.postTask(). Esse design garante que o trabalho crucial voltado ao usuário, como renderizar atualizações, possa ser executado o mais rápido possível, independentemente de tarefas que possam estar ocupando a linha de execução principal.

Este é o snippet 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() em segundo plano (se a API estiver disponível) ou volta para setTimeout.
  • Essa função envolve chamadas de função em seções de código que causam frames de animação longos e INP. Ele divide essas seções de código em tarefas mais curtas e, assim, reduz o INP.

Métricas de negócios

Graças ao LoAF, a Taboola conseguiu entender melhor o impacto da 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 que comparava o INP com o mecanismo atual sem script em um painel de parceiros de editores.

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

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

Felizmente, as métricas de negócios, como a taxa de cliques do anúncio e a receita por 1.000 impressões (RPM), não foram afetadas negativamente quando o TRECS e o Performance Fader foram ativados no painel de teste. 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 no mesmo cliente destacada anteriormente demonstra uma melhoria significativa no tempo de bloqueio da linha de execução principal pela Taboola ao usar o novo mecanismo.

Captura de tela de uma auditoria do Lighthouse para o tempo de linha de execução principal bloqueada depois que os novos mecanismos de 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 da Taboola ajudou scripts como RELEASE.js a reduzir o TBT em 485 ms (-70%).

Isso demonstra que o uso do LoAF para identificar as causas de INP e a implantação das técnicas de rendimento subsequentes com o Performance Fader permitem que os parceiros da Taboola alcancem o máximo sucesso na performance de anúncios e páginas.

Conclusão

Otimizar o INP é um processo complexo, principalmente quando scripts de terceiros são usados em sites de parceiros. Antes do início da otimização, a atribuição de INP a scripts específicos elimina qualquer suposição 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 que eles identifiquem oportunidades específicas de melhoria do SDK, eliminando a interferência de outras tecnologias presentes na página.

Quando usado em conjunto com uma boa estratégia de rendimento, como o uso de scheduler.postTask(), o LoAF pode ajudar 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.

Agradecemos especialmente a Gilberto Cocchi, Noam Rosenthal e Rick Viscomi, do Google, e Dedi Hakak, Anat Dagan e Omri Ariav, da equipe de engenharia e produto da Taboola, pela contribuição a este trabalho.