A API Long Animation Frames (LoAF, pronunciado como Lo-Af) é uma atualização da API Long Tasks para entender melhor as atualizações lentas da interface do usuário (IU). Isso pode ser útil para identificar frames de animação lentos que provavelmente afetam a métrica Core Web Vital Interaction to Next Paint (INP), que mede a capacidade de resposta, ou para identificar outros problemas de instabilidade da interface que afetam a fluidez.
Status da API
Após um teste de origem do Chrome 116 para o Chrome 122, a API LoAF foi lançada no Chrome 123.
Contexto: a API Long Tasks
A API Long Animation Frames é uma alternativa à Long Tasks API, que já está disponível no Chrome há algum tempo (desde o Chrome 58). Como o nome sugere, a API Long Task permite monitorar tarefas longas, que ocupam a linha de execução principal por 50 milissegundos ou mais. Tarefas longas podem ser monitoradas usando a interface PerformanceLongTaskTiming
, com um PeformanceObserver
:
const observer = new PerformanceObserver((list) => {
console.log(list.getEntries());
});
observer.observe({ type: 'longtask', buffered: true });
Tarefas longas provavelmente causarão problemas de capacidade de resposta. Se um usuário tentar interagir com uma página, por exemplo, clicar em um botão ou abrir um menu, mas a linha de execução principal já estiver lidando com uma tarefa demorada, a interação do usuário será adiada até que a tarefa seja concluída.
Para melhorar a capacidade de resposta, é recomendável dividir tarefas longas. Se cada tarefa longa for dividida em uma série de várias tarefas menores, isso pode permitir que tarefas mais importantes sejam executadas entre elas para evitar atrasos significativos na resposta às interações.
Portanto, ao tentar melhorar a capacidade de resposta, o primeiro esforço geralmente é executar um rastro de desempenho e analisar tarefas longas. Isso pode ser feito com uma ferramenta de auditoria baseada em laboratório, como o Lighthouse (que tem uma auditoria Evitar tarefas longas da linha de execução principal) ou analisando tarefas longas no Chrome DevTools.
Os testes baseados em laboratório geralmente não são um bom ponto de partida para identificar problemas de responsividade, porque essas ferramentas podem não incluir interações. Quando incluem, são um pequeno subconjunto de interações prováveis. O ideal é medir as causas das interações lentas no campo.
Desvantagens da API Long Tasks
Medir tarefas longas no campo usando um Performance Observer é apenas um pouco útil. Na realidade, ele não fornece muitas informações além do fato de que uma tarefa demorada aconteceu e quanto tempo ela levou.
As ferramentas de monitoramento de usuários reais (RUM) costumam usar isso para criar tendências no número ou na duração de tarefas longas ou identificar em quais páginas elas ocorrem. No entanto, sem os detalhes subjacentes do que causou a tarefa longa, isso é apenas de uso limitado. A API Long Tasks tem apenas um modelo de atribuição básico, que, na melhor das hipóteses, informa apenas o contêiner em que a tarefa demorada ocorreu (o documento de nível superior ou um <iframe>
), mas não o script ou a função que a chamou, conforme mostrado em uma entrada típica:
{
"name": "unknown",
"entryType": "longtask",
"startTime": 31.799999997019768,
"duration": 136,
"attribution": [
{
"name": "unknown",
"entryType": "taskattribution",
"startTime": 0,
"duration": 0,
"containerType": "window",
"containerSrc": "",
"containerId": "",
"containerName": ""
}
]
}
A API Long Tasks também é uma visualização incompleta, já que ela também pode excluir algumas tarefas importantes. Algumas atualizações, como a renderização, acontecem em tarefas separadas que, preferencialmente, devem ser incluídas com a execução anterior que fez com que essa atualização medisse com precisão o "trabalho total" dessa interação. Para saber mais sobre as limitações de confiar em tarefas, consulte a seção "Onde as tarefas longas são insuficientes" da explicação.
O último problema é que a medição de tarefas longas só informa sobre tarefas individuais que levam mais tempo do que o limite de 50 milissegundos. Um frame de animação pode ser composto de várias tarefas menores do que esse limite de 50 milissegundos, mas ainda assim bloquear a capacidade de renderização do navegador.
A API Long Animation Frames
A Long Animation Frames API (LoAF, na sigla em inglês) é uma nova API que busca resolver algumas das deficiências da Long Tasks API para permitir que os desenvolvedores recebam insights mais úteis para ajudar a resolver problemas de resposta e melhorar o INP, além de gerar insights sobre problemas de suavidade.
Uma boa capacidade de resposta significa que uma página responde rapidamente às interações feitas com ela. Isso envolve a capacidade de pintar todas as atualizações necessárias pelo usuário em tempo hábil e evitar o bloqueio dessas atualizações. Para o INP, é recomendável responder em até 200 milissegundos, mas para outras atualizações (por exemplo, animações), até 200 milissegundos podem ser muito longos.
A API Long Animation Frames é uma abordagem alternativa para medir o trabalho de bloqueio. Em vez de medir as tarefas individuais, a API Long Animation Frames, como o nome sugere, mede frames de animação longos. Um frame de animação longo é quando uma atualização de renderização é atrasada por mais de 50 milissegundos (o mesmo que o limite para a API Long Tasks).
Os frames de animação longos são medidos desde o início das tarefas que exigem uma renderização. Quando a primeira tarefa em um possível frame de animação longo não exigir uma renderização, o frame longo de animação será encerrado após a conclusão da tarefa que não é de renderização, e um novo frame de animação longo em potencial será iniciado com a próxima tarefa. Esse frame de animação longa sem renderização ainda é incluído na API Long Animation Frames quando é maior que 50 milissegundos (com um tempo de renderStart
de 0) para permitir a medição de trabalho potencialmente bloqueado.
Os frames de animação longos podem ser observados de maneira semelhante às tarefas longas com um PerformanceObserver
, mas observando o tipo long-animation-frame
:
const observer = new PerformanceObserver((list) => {
console.log(list.getEntries());
});
observer.observe({ type: 'long-animation-frame', buffered: true });
Os frames de animação longos anteriores também podem ser consultados na linha do tempo de performance da seguinte forma:
const loafs = performance.getEntriesByType('long-animation-frame');
No entanto, há um maxBufferSize
para entradas de performance, depois que as entradas mais recentes são descartadas. Portanto, a abordagem PerformanceObserver é a recomendada. O tamanho do buffer long-animation-frame
é definido como 200, o mesmo que para long-tasks
.
Vantagens de analisar frames em vez de tarefas
A principal vantagem de analisar isso de uma perspectiva de frame, e não de tarefas, é que uma animação longa pode ser composta por qualquer número de tarefas que resultaram cumulativamente em um frame de animação longo. Isso aborda o ponto final mencionado anteriormente, em que a soma de muitas tarefas menores de bloqueio de renderização antes de um frame de animação pode não ser exibida pela API Long Tasks.
Outra vantagem dessa visualização alternativa para tarefas longas é a capacidade de fornecer detalhamentos de tempo de todo o frame. Em vez de incluir apenas um startTime
e um duration
, como a API Long Tasks, o LoAF inclui um detalhamento muito mais detalhado das várias partes da duração do frame.
Carimbos de data/hora e durações dos frames
startTime
: o horário de início do frame longo da animação em relação ao horário de início da navegação.duration
: a duração do frame de animação longo (sem incluir o tempo de apresentação).renderStart
: o horário de início do ciclo de renderização, que inclui callbacksrequestAnimationFrame
, cálculo de estilo e layout, callbacks de observador de redimensionamento e de interseção.styleAndLayoutStart
: o início do período gasto em cálculos de estilo e layout.firstUIEventTimestamp
: o tempo do primeiro evento de interface (mouse/teclado e assim por diante) a ser processado durante o curso deste frame.blockingDuration
: a duração total em milissegundos em que o frame de animação bloqueia o processamento de entrada ou outras tarefas de alta prioridade.
Uma explicação de blockingDuration
Um frame de animação longo pode ser composto por várias tarefas. O blockingDuration
é a soma das durações de tarefas com mais de 50 milissegundos (incluindo a duração de renderização final na tarefa mais longa).
Por exemplo, se um frame de animação longo for composto por duas tarefas de 55 e 65 milissegundos, seguido de uma renderização de 20 milissegundos, o duration
será de aproximadamente 140 milissegundos com um blockingDuration
de (55 - 50) + (65 + 20 - 50) = 40 milissegundos. Durante 40 milissegundos desse frame de animação de 140 milissegundos, o frame foi considerado bloqueado para processar a entrada.
Se você quer analisar duration
ou blockingDuration
Para a tela comum de 60 hertz, um navegador tentará programar um frame pelo menos a cada 16,66 milissegundos (para garantir atualizações suaves) ou após uma tarefa de alta prioridade, como a manipulação de entrada (para garantir atualizações responsivas). No entanto, se não houver entrada, nem outras tarefas de alta prioridade, mas houver uma fila de outras tarefas, o navegador normalmente continuará o frame atual depois de 16,66 milésimos de segundo, independentemente de quão bem divididas as tarefas estejam dentro dele. Ou seja, o navegador sempre tenta priorizar as entradas, mas pode escolher resolver uma fila de tarefas em vez de atualizações de renderização. Isso ocorre porque a renderização é um processo caro. Portanto, o processamento de uma tarefa de renderização combinada para várias tarefas geralmente leva a uma redução geral do trabalho.
Portanto, frames de animação longos com um blockingDuration
baixo ou zero ainda precisam parecer responsivos à entrada. Portanto, reduzir ou eliminar blockingDuration
dividindo tarefas longas é essencial para melhorar a capacidade de resposta conforme medido pelo INP.
No entanto, muitos frames de animação longos, independentemente de blockingDuration
, indicam atualizações da interface atrasadas e, portanto, ainda podem afetar a fluidez e causar a sensação de uma interface de usuário lenta para rolagem ou animações, mesmo que essas sejam menos um problema para a capacidade de resposta, medida pelo INP. Para entender os problemas nessa área, consulte o duration
, mas isso pode ser mais complicado de otimizar, porque não é possível resolver isso dividindo o trabalho, mas precisa reduzir o trabalho.
Tempos de frame
Os carimbos de data/hora mencionados anteriormente permitem que o frame de animação longa seja dividido em tempos:
Tempo | Cálculo |
---|---|
Horário de início | startTime |
Horário de término | startTime + duration |
Duração do trabalho | renderStart ? renderStart - startTime : duration |
Duração da renderização | renderStart ? (startTime + duration) - renderStart: 0 |
Renderização: duração do pré-layout | styleAndLayoutStart ? styleAndLayoutStart - renderStart : 0 |
Renderização: duração do estilo e do layout | styleAndLayoutStart ? (startTime + duration) - styleAndLayoutStart : 0 |
Melhor atribuição de script
O tipo de entrada long-animation-frame
inclui dados de atribuição melhores de cada script que contribuiu para um frame de animação longo (para scripts com mais de 5 milissegundos).
Semelhante à API Long Tasks, ele será fornecido em uma matriz de entradas de atribuição, cada uma detalhada:
- Um
name
e umEntryType
vão retornarscript
. - Um
invoker
significativo, indicando como o script foi chamado (por exemplo,'IMG#id.onload'
,'Window.requestAnimationFrame'
ou'Response.json.then'
). - O
invokerType
do ponto de entrada do script:user-callback
: um callback conhecido registrado em uma API da plataforma da Web (por exemplo,setTimeout
,requestAnimationFrame
).event-listener
: um listener de um evento da plataforma (por exemplo,click
,load
,keyup
).resolve-promise
: manipulador de uma promessa de plataforma (por exemplo,fetch()
). No caso de promessas, todos os manipuladores das mesmas promessas são misturados como um "script".).
reject-promise
: conformeresolve-promise
, mas para a rejeição.classic-script
: avaliação do script (por exemplo,<script>
ouimport()
)module-script
: igual aclassic-script
, mas para scripts de módulo.
- Separe os dados de tempo para esse script:
startTime
: hora em que a função de entrada foi invocada.duration
: a duração entrestartTime
e o término do processamento da próxima fila de microtarefas.executionStart
: o tempo após a compilação.forcedStyleAndLayoutDuration
: o tempo total gasto processando o layout e o estilo forçados dentro dessa função (consulte sobrecarga).pauseDuration
: tempo total gasto "pausando" operações síncronas (alerta, XHR síncrono).
- Detalhes da origem do script:
sourceURL
: o nome do recurso do script, quando disponível (ou vazio se não encontrado).sourceFunctionName
: o nome da função do script, quando disponível (ou vazio se não encontrado).sourceCharPosition
: a posição do caractere do script, quando disponível (ou -1 se não encontrado).
windowAttribution
: o contêiner (o documento de nível superior ou um<iframe>
) em que o frame de animação longo ocorreu.window
: uma referência à janela de mesma origem.
Quando fornecidas, as entradas de origem permitem que os desenvolvedores saibam exatamente como cada script no frame de animação longa foi chamado, até a posição do caractere no script de chamada. Isso indica o local exato em um recurso JavaScript que resultou no frame de animação longo.
Exemplo de uma entrada de performance long-animation-frame
Um exemplo completo de entrada de desempenho de long-animation-frame
, contendo um único script, é:
{
"blockingDuration": 0,
"duration": 60,
"entryType": "long-animation-frame",
"firstUIEventTimestamp": 11801.099999999627,
"name": "long-animation-frame",
"renderStart": 11858.800000000745,
"scripts": [
{
"duration": 45,
"entryType": "script",
"executionStart": 11803.199999999255,
"forcedStyleAndLayoutDuration": 0,
"invoker": "DOMWindow.onclick",
"invokerType": "event-listener",
"name": "script",
"pauseDuration": 0,
"sourceURL": "https://web.dev/js/index-ffde4443.js",
"sourceFunctionName": "myClickHandler",
"sourceCharPosition": 17796,
"startTime": 11803.199999999255,
"window": [Window object],
"windowAttribution": "self"
}
],
"startTime": 11802.400000000373,
"styleAndLayoutStart": 11858.800000000745
}
Isso fornece uma quantidade sem precedentes de dados para que os sites possam entender a causa das atualizações de renderização lentas.
Usar a API Long Animation Frames no campo
Ferramentas como o Chrome DevTools e o Lighthouse são úteis para descobrir e reproduzir problemas, mas são ferramentas do laboratório que podem deixar passar aspectos importantes da experiência do usuário que apenas os dados de campo podem oferecer.
A API Long Animation Frames foi projetada para ser usada no campo para coletar dados contextuais importantes sobre interações do usuário que a API Long Tasks não conseguia. Isso pode ajudar a identificar e reproduzir problemas com interatividade que você não teria descoberto de outra forma.
Suporte para detecção de recursos à API de frames de animação longos
Use o código abaixo para testar se a API tem suporte:
if (PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')) {
// Monitor LoAFs
}
Link para a interação INP mais longa
O caso de uso mais óbvio da API Long Animation Frames é ajudar a diagnosticar e corrigir problemas de Interaction to Next Paint (INP), e esse foi um dos principais motivos pelos quais a equipe do Chrome desenvolveu essa API. Uma INP boa é quando todas as interações são respondidas em 200 milissegundos ou menos desde a interação até que o frame seja pintado. Como a API Long Animation Frames mede todos os frames que levam 50 ms ou mais, a maioria das INPs problemáticas precisa incluir dados de LoAF para ajudar a diagnosticar essas interações.
O "LoAF de entrada" é o que inclui a interação de entrada, conforme mostrado no diagrama a seguir:
Em alguns casos, é possível que um evento INP abranja dois LoAFs, normalmente se a interação ocorrer depois que o frame tiver iniciado a parte de renderização do frame anterior e, assim, o manipulador de eventos for processado no frame seguinte:
Também é possível que ele abranja mais de dois LoAFs em algumas circunstâncias raras.
Ao registrar os dados de LoAF associados à interação de INP, você consegue mais informações sobre a interação de INP para ajudar a diagnosticá-la. Isso é útil principalmente para entender o delay de entrada, porque você pode conferir quais outros scripts estavam em execução naquele frame.
Também pode ser útil entender a duração do processamento e o atraso da apresentação inexplicáveis se os manipuladores de eventos não reproduzirem os valores vistos para aqueles como outros scripts que estão em execução para seus usuários, o que pode não estar incluído no seu teste.
Não há nenhuma API direta para vincular uma entrada de INP à entrada ou entradas de LoAF relacionadas, mas é possível fazer isso no código comparando os horários de início e de término de cada uma (consulte o script de exemplo WhyNp). A biblioteca web-vitals
inclui todos os LoAFs interseccionados na propriedade longAnimationFramesEntries
da interface de atribuição INP da v4.
Depois de vincular a entrada ou entradas do LoAF, você pode incluir informações com a atribuição de INP. O objeto scripts
contém algumas das informações mais valiosas, já que pode mostrar o que mais estava em execução nesses frames. Assim, o envio desses dados de volta ao serviço de análise permite entender melhor por que as interações foram lentas.
Relatar LoAFs para a interação de INP é uma boa maneira de descobrir quais são os problemas de interatividade mais urgentes na sua página. Cada usuário pode interagir de maneira diferente com sua página, e com um volume suficiente de dados de atribuição de INP, vários problemas potenciais serão incluídos nos dados de atribuição de INP. Assim, você pode classificar os scripts por volume para saber quais estão correlacionados com a INP lenta.
Informar dados de animação mais longos de volta a um endpoint de análise
Uma desvantagem de analisar apenas os LoAFs da INP é que você pode perder outras áreas em potencial para melhorias que podem causar problemas futuros de INP. Isso pode levar a uma sensação de perseguição, em que você corrige um problema de INP esperando ver uma grande melhoria, mas descobre que a próxima interação mais lenta é apenas um pouco melhor do que isso. Por isso, seu INP não melhora muito.
Em vez de analisar apenas o LoAF do INP, considere todos os LoAFs durante a vida útil da página:
No entanto, cada entrada do LoAF contém dados consideráveis, então você provavelmente vai querer restringir sua análise a apenas alguns LoAFs. Além disso, como as entradas de frames de animação longa podem ser muito grandes, os desenvolvedores precisam decidir quais dados da entrada devem ser enviados para a análise. Por exemplo, os tempos de resumo da entrada e talvez os nomes dos scripts ou algum outro conjunto mínimo de outros dados contextuais que possam ser considerados necessários.
Alguns padrões sugeridos para reduzir a quantidade de dados longos de frames de animação incluem:
- Observar frames de animação longos com interações
- Observar frames de animação longos com durações de bloqueio altas
- Observar frames de animação longos durante atualizações críticas da interface para melhorar a fluidez
- Observe os piores frames de animação longa
- Identificar padrões comuns em frames de animação longos
Qual desses padrões funciona melhor para você depende de quão longe você está na jornada de otimização e de quão comuns são os frames de animação longos. Para um site que nunca foi otimizado para responsividade, pode haver muitos LoAFs. Você pode limitar a apenas LoAFs com interações, definir um limite alto ou analisar apenas os piores.
À medida que você resolve os problemas comuns de capacidade de resposta, é possível ampliar o alcance, não se limitando apenas a interações ou durações de bloqueio altas, ou reduzindo os limites.
Observar frames de animação longos com interações
Para ter insights além do frame de animação longa da INP, você pode analisar todos os LoAFs com interações (que podem ser detectadas pela presença de um valor firstUIEventTimestamp
) com um blockingDuration
alto.
Esse também pode ser um método mais fácil de monitorar as LoAFs de INP em vez de tentar correlacionar as duas, o que pode ser mais complexo. Na maioria dos casos, isso inclui o LoAF de INP para uma determinada visita. Em casos raros, quando isso não acontece, ainda são exibidas interações longas que são importantes para corrigir, já que podem ser a interação de INP para outros usuários.
O código a seguir registra todas as entradas de LoAF com um blockingDuration
maior que 100 milissegundos em que uma interação ocorreu durante o frame. O valor 100 foi escolhido aqui porque é menor que o limite de INP "bom" de 200 milissegundos. Você pode escolher um valor maior ou menor dependendo das suas necessidades.
const REPORTING_THRESHOLD_MS = 100;
const observer = new PerformanceObserver(list => {
for (const entry of list.getEntries()) {
if (entry.blockingDuration > REPORTING_THRESHOLD_MS &&
entry.firstUIEventTimestamp > 0
) {
// Example here logs to console, but could also report back to analytics
console.log(entry);
}
}
});
observer.observe({ type: 'long-animation-frame', buffered: true });
Observe frames de animação longos com durações de bloqueio altas
Para melhorar a análise de todos os frames de animação longos com interações, você pode analisar todos os frames de animação longos com durações de bloqueio altas. Isso indica possíveis problemas de INP se um usuário interagir durante esses frames de animação longos.
O código a seguir registra todas as entradas de LoAF com uma duração de bloqueio maior que 100 milissegundos em que uma interação ocorreu durante o frame. O valor 100 foi escolhido aqui porque é menor que o limite de INP "bom" de 200 milissegundos para ajudar a identificar possíveis frames problemáticos, mantendo a quantidade de frames de animação longa informados no mínimo. Você pode escolher um valor maior ou menor, dependendo das suas necessidades.
const REPORTING_THRESHOLD_MS = 100;
const observer = new PerformanceObserver(list => {
for (const entry of list.getEntries()) {
if (entry.blockingDuration > REPORTING_THRESHOLD_MS) {
// Example here logs to console, but could also report back to analytics
console.log(entry);
}
}
});
observer.observe({ type: 'long-animation-frame', buffered: true });
Observe frames de animação longos durante atualizações críticas da interface para melhorar a fluidez.
Como mencionado anteriormente, analisar frames de animação longos com duração de bloqueio alta pode ajudar a resolver a capacidade de resposta de entrada. No entanto, para suavidade, observe todos os frames de animação longos com um duration
longo.
Como isso pode gerar bastante ruído, é recomendável restringir as medições a pontos-chave com um padrão como este:
const REPORTING_THRESHOLD_MS = 100;
const observer = new PerformanceObserver(list => {
if (measureImportantUIupdate) {
for (const entry of list.getEntries()) {
if (entry.duration > REPORTING_THRESHOLD_MS) {
// Example here logs to console, but could also report back to analytics
console.log(entry);
}
}
}
});
observer.observe({ type: 'long-animation-frame', buffered: true });
async function doUIUpdatesWithMeasurements() {
measureImportantUIupdate = true;
await doUIUpdates();
measureImportantUIupdate = false;
}
Observar os piores frames de animação longos
Em vez de ter um limite definido, os sites podem querer coletar dados sobre o frame de animação mais longo (ou frames) para reduzir o volume de dados que precisam ser beaconizados. Portanto, não importa quantos frames de animação longos sejam exibidos na página, somente os dados para os piores momentos, cinco, dez ou quantos frames de animação longos absolutamente necessários são retornados.
MAX_LOAFS_TO_CONSIDER = 10;
let longestBlockingLoAFs = [];
const observer = new PerformanceObserver(list => {
longestBlockingLoAFs = longestBlockingLoAFs.concat(list.getEntries()).sort(
(a, b) => b.blockingDuration - a.blockingDuration
).slice(0, MAX_LOAFS_TO_CONSIDER);
});
observer.observe({ type: 'long-animation-frame', buffered: true });
Essas estratégias também podem ser combinadas. Analise apenas os 10 piores LoAFs, com interações mais longas que 100 milissegundos.
No momento apropriado (idealmente no evento visibilitychange
), o beacon volta ao Google Analytics. Para testes locais, use console.table
periodicamente:
console.table(longestBlockingLoAFs);
Identificar padrões comuns em frames de animação longos
Uma estratégia alternativa seria analisar os scripts comuns que aparecem com mais frequência nas entradas de frames de animação longa. Os dados podem ser informados no nível do script e da posição do personagem para identificar infratores reincidentes.
Isso pode funcionar muito bem para plataformas personalizáveis, em que temas ou plug-ins que causam problemas de desempenho podem ser identificados em vários sites.
O tempo de execução de scripts comuns (ou origens de terceiros) em frames de animação longos pode ser resumido e informado para identificar os colaboradores comuns de frames de animação longos em um site ou em uma coleção de sites. Por exemplo, para analisar URLs:
const observer = new PerformanceObserver(list => {
const allScripts = list.getEntries().flatMap(entry => entry.scripts);
const scriptSource = [...new Set(allScripts.map(script => script.sourceURL))];
const scriptsBySource= scriptSource.map(sourceURL => ([sourceURL,
allScripts.filter(script => script.sourceURL === sourceURL)
]));
const processedScripts = scriptsBySource.map(([sourceURL, scripts]) => ({
sourceURL,
count: scripts.length,
totalDuration: scripts.reduce((subtotal, script) => subtotal + script.duration, 0)
}));
processedScripts.sort((a, b) => b.totalDuration - a.totalDuration);
// Example here logs to console, but could also report back to analytics
console.table(processedScripts);
});
observer.observe({type: 'long-animation-frame', buffered: true});
Um exemplo dessa saída é:
(index) |
sourceURL |
count |
totalDuration |
---|---|---|---|
0 |
'https://example.consent.com/consent.js' |
1 |
840 |
1 |
'https://example.com/js/analytics.js' |
7 |
628 |
2 |
'https://example.chatapp.com/web-chat.js' |
1 |
5 |
Usar a API Long Animation Frames nas ferramentas
A API também permite ferramentas adicionais para depuração local. Embora algumas ferramentas, como o Lighthouse e o Chrome DevTools, tenham conseguido coletar muitos desses dados usando detalhes de rastreamento de nível inferior, ter essa API de nível mais alto pode permitir que outras ferramentas acessem esses dados.
Mostrar dados de frames de animação longos no DevTools
É possível mostrar frames de animação longos no DevTools usando a API performance.measure()
, que são mostrados na faixa de tempos do usuário do DevTools em rastros de desempenho para mostrar onde concentrar seus esforços para melhorias de desempenho. Usando a API de extensibilidade do DevTools, elas podem até ser mostradas na própria faixa:
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
performance.measure('LoAF', {
start: entry.startTime,
end: entry.startTime + entry.duration,
detail: {
devtools: {
dataType: "track-entry",
track: "Long animation frames",
trackGroup: "Performance Timeline",
color: "tertiary-dark",
tooltipText: 'LoAF'
}
}
});
}
});
observer.observe({ type: 'long-animation-frame', buffered: true });
A longo prazo, os frames de animação longos provavelmente serão incorporados ao próprio DevTools, mas o snippet de código anterior permite que eles sejam exibidos nesse momento.
A primeira entrada na figura anterior também demonstra onde o navegador processou várias tarefas juntas no mesmo frame de animação longo, em vez de renderizá-las entre elas. Como mencionado anteriormente, isso pode acontecer quando não há tarefas de entrada de alta prioridade, mas há uma fila de tarefas. A primeira tarefa longa tem algumas atualizações de renderização para concluir (caso contrário, o frame longo de animação atual seria redefinido depois dela e uma nova começaria com a próxima tarefa). No entanto, em vez de ativar essa renderização imediatamente, o navegador processou várias tarefas adicionais e só então acionou a tarefa longa de renderização e encerrou o longo frame de animação. Isso demonstra a utilidade de analisar frames de animação longos no DevTools, em vez de apenas tarefas longas, para ajudar a identificar renderizações atrasadas.
Usar dados longos de frames de animação em outras ferramentas para desenvolvedores
A extensão das Core Web Vitals mostrou o valor nas informações de depuração do resumo de geração de registros para diagnosticar problemas de performance.
Agora, ele também exibe dados longos de frames de animação para cada callback de INP e cada interação:
Usar dados de frames de animação longa em ferramentas de teste automatizado
Da mesma forma, as ferramentas de teste automatizado em pipelines de CI/CD podem mostrar detalhes sobre possíveis problemas de desempenho medindo frames de animação longos durante a execução de vários conjuntos de testes.
Perguntas frequentes
Algumas das perguntas frequentes sobre essa API incluem:
Por que não apenas estender ou iterar na API Long Tasks?
Essa é uma abordagem alternativa para informar uma medição semelhante, mas diferente, de possíveis problemas de responsividade. É importante garantir que os sites que dependem da API Long Tasks já existentes continuem funcionando para evitar a interrupção dos casos de uso atuais.
Embora a API Long Tasks possa se beneficiar de alguns dos recursos do LoAF (como um modelo de atribuição melhor), acreditamos que focar em frames em vez de tarefas oferece muitos benefícios que tornam essa API fundamentalmente diferente da API Long Tasks existente.
Por que não tenho entradas de script?
Isso pode indicar que o frame de animação longo não foi causado pelo JavaScript, mas sim por um grande trabalho de renderização.
Isso também pode acontecer quando o frame de animação longo é devido ao JavaScript, mas a atribuição do script não pode ser fornecida por vários motivos de privacidade, conforme observado anteriormente, principalmente porque o JavaScript não é de propriedade da página.
Por que tenho entradas de script, mas nenhuma ou poucas informações de origem?
Isso pode acontecer por vários motivos, incluindo não haver uma boa fonte para apontar.
As informações do script também serão limitadas para scripts no-cors cross-origin
, mas isso pode ser resolvido buscando esses scripts usando CORS, adicionando crossOrigin = "anonymous"
à chamada <script>
.
Por exemplo, o script padrão do Gerenciador de tags do Google a ser adicionado à página:
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
<!-- End Google Tag Manager -->
Pode ser aprimorado para adicionar j.crossOrigin = "anonymous"
e permitir que todos os detalhes de atribuição sejam fornecidos ao GTM.
Isso vai substituir a API Long Tasks?
Acreditamos que a API Long Animation Frames seja melhor e mais completa para medir tarefas longas, mas não há planos de descontinuar a API Long Tasks.
Feedback necessário
Você pode enviar feedback na lista de problemas do GitHub ou registrar bugs na implementação da API do Chrome no rastreador de problemas do Chrome.
Conclusão
A API Long Animation Frames é uma API nova e incrível com muitas vantagens em relação à API Long Tasks anterior.
Ele é uma ferramenta fundamental para resolver problemas de capacidade de resposta, conforme medido pela INP. A INP é uma métrica difícil de otimizar, e essa API é uma das maneiras que a equipe do Chrome busca facilitar a identificação e a resolução de problemas para os desenvolvedores.
O escopo da API Long Animation Frames vai além do INP e pode ajudar a identificar outras causas de atualizações lentas que podem afetar a fluidez geral da experiência do usuário em um site.