Высокоточные измерения времени
API производительности позволяет выполнять высокоточные измерения, основанные на времени с потенциальным разрешением в доли миллисекунд и стабильным монотонным таймером, не подверженным сдвигу системного времени или корректировкам. Высокоразрешающие таймеры необходимы для точного бенчмаркинга вместо менее точных и немонотонных Date отметок времени.
Эта страница предоставляет обзор того, как работает высокоточное время в API производительности и как оно сравнивается с Date отметками времени.
DOMHighResTimeStamp
Высокоточная точность достигается с помощью типа DOMHighResTimeStamp для значений времени. Единица измерения — миллисекунды, и точность должна составлять 5 мкс (микросекунд). Однако, если браузер не может предоставить значение времени с точностью до 5 микросекунд, браузер может представить значение как время в миллисекундах с точностью до миллисекунды. Это может произойти из-за аппаратных/программных ограничений или по соображениям безопасности и конфиденциальности. Более подробную информацию см. в разделе о снижении точности ниже.
Все отметки времени в API производительности используют тип DOMHighResTimeStamp. Ранее API производительности (и другие веб-API) использовали тип EpochTimeStamp (ранее известный как DOMTimeStamp). Эти типы теперь не рекомендуются.
Performance.now() vs. Date.now()
JavaScript определяет Date.now() как количество миллисекунд, прошедших с момента эпохи, которая определяется как полночь начала 1 января 1970 года по UTC. Метод performance.now() в свою очередь относится к свойству Performance.timeOrigin. Более подробную информацию см. в разделе происхождения времени ниже.
Значения времени JavaScript Date могут быть подвержены сдвигу системного времени или корректировкам. Это означает, что значение времени может не всегда монотонно возрастать. Основное назначение объектов Date — отображать информацию о времени и дате пользователю, поэтому многие операционные системы запускают демон, который регулярно синхронизирует время. Время может быть подкорректировано на несколько миллисекунд несколько раз в час.
Метод performance.now() (и все другие значения DOMHighResTimeStamp ) предоставляют монотонно возрастающие значения времени и не подвержены корректировкам времени. Это означает, что гарантируется, что DOMHighResTimeStamp значения будут по крайней мере равны, если не больше, чем в последний раз, когда вы к ним обращались.
Date.now(); // 1678889977578 performance.now(); // 233936
Для измерения производительности, расчета точных частот кадров (FPS), анимационных циклов и т. п. используйте монотонно возрастающее высокоточное время, доступное с помощью Performance.now(), а не JavaScript Date.now().
Резюмируя:
| - | Performance.now() | Date.now() |
|---|---|---|
| Разрешение | доли миллисекунд | миллисекунды |
| Происхождение | Performance.timeOrigin | Эпоха Unix (1 января 1970 года, по UTC) |
| Использовать корректировки времени | Нет | Да |
| Монотонно возрастающее | Да | Нет |
Происхождения времени
API производительности использует свойство Performance.timeOrigin для определения базовой точки для отметок времени, связанных с производительностью. Все DOMHighResTimeStamp времена относятся к свойству timeOrigin.
В контекстах окна это время начала навигации. В контекстах Worker и ServiceWorker это время запуска рабочего процесса.
В предыдущей версии спецификации (Уровень 1) метод performance.now() относился к свойству performance.timing.navigationStart из спецификации Навигационных измерений. Однако это изменилось в более поздней версии спецификации (Уровень 2), и performance.now() теперь относится к Performance.timeOrigin, что позволяет избежать рисков изменения времени при сравнении отметок времени между веб-страницами.
// Level 1 (clock change risks) currentTime = performance.timing.navigationStart + performance.now(); // Level 2 (no clock change risks) currentTime = performance.timeOrigin + performance.now();
Синхронизация источников времени между контекстами
Чтобы учесть различные источники времени в контекстах окна и рабочего процесса, необходимо переводить отметки времени, поступающие из скриптов рабочего процесса, с помощью свойства timeOrigin, чтобы синхронизировать временные характеристики для всего приложения. Примеры кода для синхронизации времени см. в разделе примеров на странице Performance.timeOrigin.
Снижение точности
Для защиты от атак на основе тайминга и отслеживания, типы DOMHighResTimeStamp грубятся в зависимости от статуса изоляции сайта.
- Разрешение в изолированных контекстах: 5 микросекунд
- Разрешение в неизолированных контекстах: 100 микросекунд
Для применения изоляции между доменами на вашем сайте используйте заголовки Cross-Origin-Opener-Policy (COOP) и Cross-Origin-Embedder-Policy (COEP):
Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp
Эти заголовки гарантируют, что документ верхнего уровня не разделяет группу контекстов просмотра с документами из других доменов. Cross-Origin-Opener-Policy изолирует ваш документ и потенциальные злоумышленники не смогут получить доступ к вашему глобальному объекту, если они откроют его в всплывающем окне, предотвращая ряд атак между доменами, известные как XS-Leaks.
См. также
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/High_precision_timing