Получить навигацию синхронизации обратно / вперед совместимы - конвертировать из эпохи в часы HR - PullRequest
0 голосов
/ 17 июня 2019

Давайте введем примечание от www.w3.org , включая две важные ссылки для сравнения.

Интерфейс PerformanceTiming был определен в [ВРЕМЯ НАВИГАЦИИ] и сейчас считается устаревшим. Использование имен из Интерфейс PerformanceTiming поддерживается, чтобы оставаться в обратном направлении совместимы, но нет никаких планов по расширению этой функциональности до имена в интерфейсе PerformanceNavigationTiming, определенные в [NAVIGATION-TIMING-2] (или другие интерфейсы) в будущем.

Я сделал функцию для получения времени навигации, которое должно быть обратно и вперед совместимым, потому что мы находимся в средней эре преобразования на уровень 2. Так что эта функция получает время от имени события работает в Chrome, но не в Firefox:

function nav(eventName) {
  var lev1 = performance.timing; //deprecated unix epoch time in ms since 1970
  var lev2 = performance.getEntriesByType("navigation")[0]; //ms since page started to load. (since performance.timing.navigationStart)
  var nav = lev2 || lev1; //if lev2 is undefined then use lev1
  return nav[eventName]
}

Объяснение: Когда нет записи "навигация", это прибегает к устаревшему способу определения времени навигации, основанного на Время эпохи Unix Время в миллисекундах с 1970 года (Лев1), в то время как новый способ (lev2) равен время HR в миллисекундах с тех пор, как текущая навигация по документу начала загружать , это полезно вместе с User Timing, который всегда имел формат времени HR.

Как мы можем получить функцию, возвращающую время HR во всех случаях?

Когда я вижу число, состоящее более чем из 10 цифр, без точки, я знаю, что это время, полученное из устаревшего уровня 1 времени навигации. Все остальные тестовые примеры дают числа десятичных точек, означающие, что это время HR с большей точностью. Самая большая проблема заключается в том, что они имеют различное время происхождения .

Я прошел путаницу, пробные ошибки и разочарованный поиск (MDN не обновился до уровня 2), чтобы подтвердить и заявить, что:

  • Навигация Сроки Уровень 1 использовать Время эпохи Unix и остальные ...
  • Навигация Время использования 2 уровня Время HR
  • Пользователь Время использования 1 уровня Время HR
  • Пользователь Время использования 2 уровня Время HR
  • Также performance.now() имеет HR-время как в Chrome, так и в Firefox.

Как преобразовать Время эпохи Unix в Время HR ?


решено.:

Код исправлен с помощью Amadan.
См. Комментарии в принятом ответе.

function nav(eventName, fallback) {
  var lev1 = performance.timing; //deprecated unix epoch time in ms since 1970
  var lev2 = performance.getEntriesByType("navigation")[0]; //ms since page started to load
  var nav = lev2 || lev1; //if lev2 is undefined then use lev1
  if (!nav[eventName] && fallback) eventName = fallback

  // approximate t microseconds it takes to execute performance.now()
  var i = 10000, t = performance.now()
  while(--i) performance.now()
  t = (performance.now() - t)/10000 // < 10 microseconds

  var oldTime = new Date().getTime(), 
      newTime = performance.now(),
      timeOrigin = performance.timeOrigin? 
                   performance.timeOrigin: 
                   oldTime - newTime - t; // approximate

  return nav[eventName] - (lev2? 0: timeOrigin);
  // return nav[eventName] - (lev2? 0: lev1.navigationStart); //alternative?
}

performance.timeOrigin уменьшается в случае, если используется старое время lev1 .
Если браузер не имеет его, то приблизительное времяOrigin, уменьшив performance.now() время с timeOrigin , с (new Date (). GetTime ()) время с начала Unix до время до начала с Unix Epoch . Очевидно, это определение, хотя ссылка была немного расплывчатой. Я подтвердил тестирование и верю ответу. Надеемся, что w3c имеет лучшее определение timeOrigin, чем: метка времени с высоким разрешением времени начала измерения производительности .

Возвращаемое значение функции представляет время, прошедшее с момента возникновения.

Может быть незначительным в большинстве случаев, но измеренное время t, которое потребовалось для выполнения performance.now(), удаляется, чтобы приблизиться к одновременному выполнению.

Я измерял t почти до 10 микросекунд на моем Raspberry Pi, который был довольно стабильным с различными размерами петли. Но мой Lenovo не был настолько точным, чтобы округлять десятичные дроби и получать более короткое время на t при тестировании больших размеров петель.


Альтернативное решение закомментировано в последней строке кода .
Устаревшие performance.timing.navigationStart:

представляющий момент в миллисекундах со времени UNIX, верно после завершения запроса на выгрузку в предыдущем документе втот же контекст просмотра. Если нет предыдущего документа, это значение будет таким же, как PerformanceTiming.fetchStart

Итак, чтобы проверить текущий документ (игнорируя любой предыдущий), используйте устаревший performance.timing.fetchStart :

, представляющий момент в миллисекундах с начала эпохи UNIX, Браузер готов получить документ, используя HTTP-запрос. это перед проверкой кеша любого приложения.

Конечно, правильно использовать устаревшее свойство, если оно единственное, которое понимает браузер. Он используется, когда «навигация» не определена в getEntriesByType, иначе имеется хорошая поддержка браузера .


Быстрая проверка подтвердила друг друга этой строкой прямо перед return:

console.log(performance.timeOrigin + '\n' + lev1.navigationStart + '\n' + lev1.fetchStart)

С результатом, который выглядит так в моем Chrome

1560807558225,1611
1560807558225
1560807558241

1 Ответ

1 голос
/ 17 июня 2019

Это возможно только в том случае, если браузер поддерживает HR time 2:

let unixTime = hrTime + performance.timeOrigin;

let hrTime = unixTime - performance.timeOrigin;

Однако, performance обычно используется для временных различий, которым все равно, каково происхождение абсолютных временных отметок.

Для браузеров, которые не поддерживают HR time 2, или для тех, кто нерешительно его поддерживает, вы можете подделать его следующим образом:

const hrSyncPoint = performance.now();
const unixSyncPoint = new Date().getTime();
const timeOrigin = unixSyncPoint - hrSyncPoint;

Это не суперточно, но должнобыть достаточно хорошим для большинства целей (в моей системе performance.timeOrigin - timeOrigin меньше миллисекунды).

...