O Chrome 64 vai suspender o uso da API chrome.loadTimes()

chrome.loadTimes() é uma API não padrão que expõe métricas de carregamento e informações de rede aos desenvolvedores para ajudá-los a entender melhor o desempenho do seu site no mundo real.

Desde que essa API foi implementada em 2009, todas as informações úteis que ela informa podem ser encontrados em APIs padronizadas, como:

Essas APIs padronizadas estão sendo implementadas por vários fornecedores de navegadores. Como resultado, o uso de chrome.loadTimes() será descontinuado no Chrome 64.

A API descontinuada

A função chrome.loadTimes() retorna um único objeto que contém todos os informações de rede e carregamento. Por exemplo, o objeto a seguir é o resultado de chamar chrome.loadTimes() em www.google.com:

{
  "requestTime": 1513186741.847,
  "startLoadTime": 1513186741.847,
  "commitLoadTime": 1513186742.637,
  "finishDocumentLoadTime": 1513186742.842,
  "finishLoadTime": 1513186743.582,
  "firstPaintTime": 1513186742.829,
  "firstPaintAfterLoadTime": 0,
  "navigationType": "Reload",
  "wasFetchedViaSpdy": true,
  "wasNpnNegotiated": true,
  "npnNegotiatedProtocol": "h2",
  "wasAlternateProtocolAvailable": false,
  "connectionInfo": "h2"
}

Substituições padronizadas

Agora é possível encontrar cada um dos valores acima usando APIs padronizadas. O seguinte corresponde cada valor à API padronizada, e as seções abaixo mostram exemplos de código sobre como usar cada valor na API antiga com equivalentes modernos.

chrome.loadTimes() recurso Substituição padronizada de API
requestTime Tempo de navegação 2
startLoadTime Tempo de navegação 2
commitLoadTime Tempo de navegação 2
finishDocumentLoadTime Tempo de navegação 2
finishLoadTime Tempo de navegação 2
firstPaintTime Tempo de pintura
firstPaintAfterLoadTime N/A
navigationType Tempo de navegação 2
wasFetchedViaSpdy Tempo de navegação 2
wasNpnNegotiated Tempo de navegação 2
npnNegotiatedProtocol Tempo de navegação 2
wasAlternateProtocolAvailable N/A
connectionInfo Tempo de navegação 2

Os exemplos de código abaixo retornam valores equivalentes aos retornados pelo chrome.loadTimes(): No entanto, para códigos novos, esses exemplos não são recomendado. O motivo é que chrome.loadTimes() fornece valores de horários no período de época em segundos, enquanto as novas APIs de desempenho normalmente informa valores em milissegundos em relação ao tempo de horário, que tende a mais úteis na análise de desempenho.

Vários dos exemplos também favorecem as APIs Performance Linha do tempo 2 (por exemplo, performance.getEntriesByType()), mas fornecem substitutos para os a API Navigation Timing 1, porque ela tem maior suporte a navegadores. A partir de agora, as APIs de linha do tempo de desempenho têm preferência e costumam ser informados com maior precisão.

requestTime

function requestTime() {
  // If the browser supports the Navigation Timing 2 and HR Time APIs, use
  // them, otherwise fall back to the Navigation Timing 1 API.
  if (window.PerformanceNavigationTiming && performance.timeOrigin) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return (ntEntry.startTime + performance.timeOrigin) / 1000;
  } else {
    return performance.timing.navigationStart / 1000;
  }
}

startLoadTime

function startLoadTime() {
  // If the browser supports the Navigation Timing 2 and HR Time APIs, use
  // them, otherwise fall back to the Navigation Timing 1 API.
  if (window.PerformanceNavigationTiming && performance.timeOrigin) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return (ntEntry.startTime + performance.timeOrigin) / 1000;
  } else {
    return performance.timing.navigationStart / 1000;
  }
}

commitLoadTime

function commitLoadTime() {
  // If the browser supports the Navigation Timing 2 and HR Time APIs, use
  // them, otherwise fall back to the Navigation Timing 1 API.
  if (window.PerformanceNavigationTiming && performance.timeOrigin) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return (ntEntry.responseStart + performance.timeOrigin) / 1000;
  } else {
    return performance.timing.responseStart / 1000;
  }
}

finishDocumentLoadTime

function finishDocumentLoadTime() {
  // If the browser supports the Navigation Timing 2 and HR Time APIs, use
  // them, otherwise fall back to the Navigation Timing 1 API.
  if (window.PerformanceNavigationTiming && performance.timeOrigin) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return (ntEntry.domContentLoadedEventEnd + performance.timeOrigin) / 1000;
  } else {
    return performance.timing.domContentLoadedEventEnd / 1000;
  }
}

finishLoadTime

function finishLoadTime() {
  // If the browser supports the Navigation Timing 2 and HR Time APIs, use
  // them, otherwise fall back to the Navigation Timing 1 API.
  if (window.PerformanceNavigationTiming && performance.timeOrigin) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return (ntEntry.loadEventEnd + performance.timeOrigin) / 1000;
  } else {
    return performance.timing.loadEventEnd / 1000;
  }
}

firstPaintTime

function firstPaintTime() {
  if (window.PerformancePaintTiming) {
    const fpEntry = performance.getEntriesByType('paint')[0];
    return (fpEntry.startTime + performance.timeOrigin) / 1000;
  }
}

firstPaintAfterLoadTime

function firstPaintTimeAfterLoad() {
  // This was never actually implemented and always returns 0.
  return 0;
}
function navigationType() {
  if (window.PerformanceNavigationTiming) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return ntEntry.type;
  }
}

wasFetchedViaSpdy

function wasFetchedViaSpdy() {
  // SPDY is deprecated in favor of HTTP/2, but this implementation returns
  // true for HTTP/2 or HTTP2+QUIC/39 as well.
  if (window.PerformanceNavigationTiming) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return ['h2', 'hq'].includes(ntEntry.nextHopProtocol);
  }
}

wasNpnNegotiated

function wasNpnNegotiated() {
  // NPN is deprecated in favor of ALPN, but this implementation returns true
  // for HTTP/2 or HTTP2+QUIC/39 requests negotiated via ALPN.
  if (window.PerformanceNavigationTiming) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return ['h2', 'hq'].includes(ntEntry.nextHopProtocol);
  }
}

npnNegotiatedProtocol

function npnNegotiatedProtocol() {
  // NPN is deprecated in favor of ALPN, but this implementation returns the
  // HTTP/2 or HTTP2+QUIC/39 requests negotiated via ALPN.
  if (window.PerformanceNavigationTiming) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return ['h2', 'hq'].includes(ntEntry.nextHopProtocol) ?
        ntEntry.nextHopProtocol : 'unknown';
  }
}

wasAlternateProtocolAvailable

function wasAlternateProtocolAvailable() {
  // The Alternate-Protocol header is deprecated in favor of Alt-Svc
  // (https://www.mnot.net/blog/2016/03/09/alt-svc), so technically this
  // should always return false.
  return false;
}

connectionInfo

function connectionInfo() {
  if (window.PerformanceNavigationTiming) {
    const ntEntry = performance.getEntriesByType('navigation')[0];
    return ntEntry.nextHopProtocol;
  }
}

Plano de remoção

A API chrome.loadTimes() será descontinuada no Chrome 64 e prevista para ser removida no final de 2018. Os desenvolvedores precisam migrar o código o mais rápido possível para evitar qualquer perda de dados.

Intenção de descontinuação | Rastreador Chromestatus | Bug do Chromium