Feedback do desenvolvedor necessário: API Frame Timing

Nos últimos anos, os navegadores fizeram grandes avanços no desempenho de renderização, especialmente em dispositivos móveis. Antes você não esperava conseguir um frame rate eficiente para um conteúdo remotamente complexo, mas hoje isso é possível com um pouco de cuidado.

No entanto, para a maioria de nós, há uma desconexão entre o que podemos testar razoavelmente em nossos próprios dispositivos e a experiência de nossos usuários. Se eles não conseguirem 60 fps, a experiência será prejudicada, e eles irão para outro lugar, e nós sofreremos. Além disso, o W3C está discutindo uma nova API que pode nos ajudar a ver o que os usuários veem: a API Frame Timing.

Jake Archibald e eu gravamos recentemente uma visão geral em vídeo da API. Se você preferir assistir em vez de ler, confira:

Usos da API Frame Timing

Sem dúvida, há várias coisas que podem ser feitas com a API Frame Timing e, principalmente, você mede o que é importante para você e para o seu projeto. Mesmo assim, aqui estão algumas ideias:

  • Acompanhar o QPS das animações JavaScript e CSS.
  • Acompanhar a suavidade das rolagens de sua página (ou talvez aquela lista infinita de rolagem que você já tem).
  • Redimensionando automaticamente seus efeitos do showbiz com base na carga atual do dispositivo.
  • Teste de regressão em métricas de desempenho no ambiente de execução.

O argumento rápido de venda

Veja como a API está na especificação: com ela, você pode extrair dados sobre o tempo da linha de execução do renderizador, onde o JavaScript, estilos e layout são executados. Você pode ter ouvido a linha de execução do renderizador chamada de thread principal. É a mesma coisa por outro nome.

var rendererEvents = window.performance.getEntriesByType("renderer");

Cada um dos registros de encadeamento do renderizador que você obtém é mais ou menos assim:

    {
      sourceFrameNumber: 120,
      startTime: 1342.549374253
      cpuTime: 6.454313323
    }

Cada registro é essencialmente um objeto que contém um número exclusivo de frame, um carimbo de data/hora de alta resolução para a inicialização do frame e outro para o tempo de CPU usado. Com uma matriz desses valores, é possível analisar cada um dos valores de startTime e descobrir se a linha de execução principal está a 60 fps. Essencialmente, a startTime de cada frame sobe em blocos de aproximadamente 16 ms?

Contudo, mais do que isso, você também tem o cpuTime. Assim, é possível saber se está dentro do limite de 16 ms ou se estava dentro do fio. Se a cpuTime estiver bem perto do limite de 16 ms, não vai haver muito espaço para itens como coleta de lixo e, com o uso da CPU alto, o consumo da bateria também será maior.

Além do encadeamento do renderizador, você também pode extrair dados sobre o tempo do encadeamento do compositor, onde a pintura e a composição acontecem:

var compositeThreadEvents = window.performance.getEntriesByType("composite");

Cada um também retorna com um número de frame de origem, que você pode usar para vincular aos eventos da linha de execução principal:

{
    sourceFrameNumber: 120,
    startTime: 1352.343235321
}

Devido à forma como a composição geralmente funciona nos navegadores, pode haver vários desses registros por registro de linha de execução do renderizador. Portanto, você pode usar o sourceFrameNumber para vinculá-los. Há também alguma discussão sobre a necessidade de tempo de CPU nesses registros também, então, se você quiser falar fortemente sobre os problemas do GitHub (link em inglês).

Mais informações

Essa API ainda não foi lançada, mas esperamos que seja em breve. Enquanto isso, confira a seguir o que você pode ler e fazer: