高标准精度时间(High Resolution Time)规范定义了
Performance
接口,支持应用程序(applications)内的客户端延迟测量。
Date 对象表示自 1970-01-01 起的毫秒精度时间。在实践中,会受制于时钟偏移(clock skew)和系统时钟调整(adjustment of the system clock),所以时间值可能不能保证一直是在增加的,例如:
var mark_start = Date.now();
doTask(); // Some task
var duration = Date.now() - mark_start;
duration 可能 >0,<0,=0。
对一些需要计算网页加载时间、脚本执行时间、动画时间或是需要更高精确度等情况就不太够了。
为了保证单调增长(monotonically increasing)且更高精确度的时间值,Performace 接口定义了 DOMHighResTimeStamp
类型,performance.now
方法,performance.timeOrigin
属性。
DOMHighResTimeStamp
单位是毫秒,精确到 5 微秒(0.005 ms),如果因为硬件或软件的限制,User Agent 不能精确到微秒,则会显示精确到 1ms。
typedef double DOMHighResTimeStamp;
Time Origin
计算时间的起始点,
The time origin is the time value from which time is measured:
If the global object is a
Window
object, the time origin MUST be equal to:
- the time when the browsing context(浏览上下文) is first created if there is no previous document;(注:在一个 Web 浏览器内,一个标签页或窗口常包含一个浏览上下文,如一个 iframe 或一个 frameset 内的若干 frame。)
- otherwise, the time of the user confirming the navigation during the previous document’s prompt to unload algorithm, if a previous document exists and if the confirmation dialog was displayed;
- otherwise, the time of starting the navigation responsible for loading the Window object’s newest Document object.
- If the global object is a
WorkerGlobalScope
object, the time origin MUST be equal to the official moment of creation of the worker.- Otherwise, the time origin is undefined.
在 Chrome DevTools 控制台打印 performance
:
{navigation: {type: 0, redirectCount: 0}
timeOrigin: 1555386564177.783
timing: {
connectEnd: 1555386564181
connectStart: 1555386564181
domComplete: 1555386564345
domContentLoadedEventEnd: 1555386564322
domContentLoadedEventStart: 1555386564318
domInteractive: 1555386564317
domLoading: 1555386564286
domainLookupEnd: 1555386564181
domainLookupStart: 1555386564181
fetchStart: 1555386564181
loadEventEnd: 1555386564345
loadEventStart: 1555386564345
navigationStart: 1555386564177
redirectEnd: 0
redirectStart: 0
requestStart: 1555386564181
responseEnd: 1555386564291
responseStart: 1555386564181
secureConnectionStart: 0
unloadEventEnd: 0
unloadEventStart: 0
}
}
Performance 接口
[Exposed=(Window,Worker)]
interface Performance : EventTarget {clearMarks: ƒ clearMarks()
clearMeasures: ƒ clearMeasures()
void clearResourceTimings();
PerformanceEntryList getEntries();
PerformanceEntryList getEntriesByType(DOMString type);
PerformanceEntryList getEntriesByName(DOMString name, optional DOMString type);
mark: ƒ mark()
measure: ƒ measure()
memory: (...)
readonly attribute PerformanceNavigation navigation;
DOMHighResTimeStamp now();
attribute EventHandler onresourcetimingbufferfull;
void setResourceTimingBufferSize(unsigned long maxSize);
readonly attribute DOMHighResTimeStamp timeOrigin;
readonly attribute PerformanceTiming timing;
[Default] object toJSON();};
performance 属性
partial interface WindowOrWorkerGlobalScope {[Replaceable]
readonly attribute Performance performance;
};
例如 window.performance
,
interface Performance {
readonly attribute PerformanceTiming timing;
readonly attribute PerformanceNavigation navigation;
};
partial interface Window {[Replaceable] readonly attribute Performance performance;
};
PerformanceTiming 接口
interface PerformanceTiming {
readonly attribute unsigned long long navigationStart;
readonly attribute unsigned long long unloadEventStart;
readonly attribute unsigned long long unloadEventEnd;
readonly attribute unsigned long long redirectStart;
readonly attribute unsigned long long redirectEnd;
readonly attribute unsigned long long fetchStart;
readonly attribute unsigned long long domainLookupStart;
readonly attribute unsigned long long domainLookupEnd;
readonly attribute unsigned long long connectStart;
readonly attribute unsigned long long connectEnd;
readonly attribute unsigned long long secureConnectionStart;
readonly attribute unsigned long long requestStart;
readonly attribute unsigned long long responseStart;
readonly attribute unsigned long long responseEnd;
readonly attribute unsigned long long domLoading;
readonly attribute unsigned long long domInteractive;
readonly attribute unsigned long long domContentLoadedEventStart;
readonly attribute unsigned long long domContentLoadedEventEnd;
readonly attribute unsigned long long domComplete;
readonly attribute unsigned long long loadEventStart;
readonly attribute unsigned long long loadEventEnd;
};
- DNS 解析:timing.domainLookupEnd – timing.domainLookupStart
- 建立连接:timing.connectEnd – timing.connectStart
- 发送请求:timing.responseStart – timing.requestStart
- 接收请求:timing.responseEnd – timing.responseStart
- 解析 DOM 树:timing.domInteractive – timing.domLoading
- 页面加载完成:timing.domContentLoadedEventStart – timing.domInteractive
- DOMContentLoaded 事件耗时:
timing.domContentLoadedEventEnd – timing.domContentLoadedEventStart
- DOM 加载完成:timing.domComplete – timing.domContentLoadedEventEnd
- DOMLoad 事件耗时:timing.loadEventEnd – timing.loadEventStart
PerformanceNavigation 接口
interface PerformanceNavigation {
const unsigned short TYPE_NAVIGATE = 0;
const unsigned short TYPE_RELOAD = 1;
const unsigned short TYPE_BACK_FORWARD = 2;
const unsigned short TYPE_RESERVED = 255;
readonly attribute unsigned short type;
readonly attribute unsigned short redirectCount;
};
-
TYPE_NAVIGATE (0)
通过点击链接、书签、表单提交、脚本、浏览器地址栏输入地址访问
The page was accessed by following a link, a bookmark, a form submission, or a script, or by typing the URL in the address bar. -
TYPE_RELOAD (1)
通过点击刷新按钮或是Location.reload()
访问
The page was accessed by clicking the Reload button or via the Location.reload() method. -
TYPE_BACK_FORWARD (2)
通过页面前进后退访问
The page was accessed by navigating into the history. -
TYPE_RESERVED (255)
其他方式
Any other way.
PerformanceEntry 接口
PerformanceEntry 对象封装了作为性能时间线(performance timeline)一部分的单个性能指标。
[Exposed=(Window,Worker)]
interface PerformanceEntry {
readonly attribute DOMString name;
readonly attribute DOMString entryType;
readonly attribute DOMHighResTimeStamp startTime;
readonly attribute DOMHighResTimeStamp duration;
[Default] object toJSON();};
partial interface Performance {PerformanceEntryList getEntries ();
PerformanceEntryList getEntriesByType (DOMString type);
PerformanceEntryList getEntriesByName (DOMString name, optional DOMString type);
};
typedef sequence<PerformanceEntry> PerformanceEntryList;
- name:PerformanceEntry 对象标识符,不需要唯一(unique)。
- entryType:该 PerformanceEntry 对象表示的接口的类型。
- startTime:该性能度量的第一个记录时间戳的时间值。
- duration:记录时间,即记录开始到结束的时间。
PerformanceEntry 实例会是下列接口实例之一:
- PerformanceMark
- PerformanceMeasure
- PerformanceFrameTiming
- PerformanceNavigationTiming
- PerformanceResourceTiming
- PerformancePaintTiming
例如在 Chrome DevTools 的控制台打印 performance.getEntries()
,
PerformanceNavigationTiming
[Exposed=Window]
interface PerformanceNavigationTiming : PerformanceResourceTiming {
readonly attribute DOMHighResTimeStamp unloadEventStart;
readonly attribute DOMHighResTimeStamp unloadEventEnd;
readonly attribute DOMHighResTimeStamp domInteractive;
readonly attribute DOMHighResTimeStamp domContentLoadedEventStart;
readonly attribute DOMHighResTimeStamp domContentLoadedEventEnd;
readonly attribute DOMHighResTimeStamp domComplete;
readonly attribute DOMHighResTimeStamp loadEventStart;
readonly attribute DOMHighResTimeStamp loadEventEnd;
readonly attribute NavigationType type;
readonly attribute unsigned short redirectCount;
[Default] object toJSON();};
{
connectEnd: 3.8349999995261896
connectStart: 3.8349999995261896
decodedBodySize: 74229
domComplete: 336.69000000008964
domContentLoadedEventEnd: 130.1899999998568
domContentLoadedEventStart: 129.47499999791034
domInteractive: 129.42000000111875
domainLookupEnd: 3.8349999995261896
domainLookupStart: 3.8349999995261896
duration: 339.76500000062515
encodedBodySize: 18430
entryType: "navigation"
fetchStart: 3.8349999995261896
initiatorType: "navigation"
loadEventEnd: 339.76500000062515
loadEventStart: 336.72999999907915
name: "https://developer.mozilla.org/en-US/docs/Web/API/Performance_API"
nextHopProtocol: "h2"
redirectCount: 0
redirectEnd: 0
redirectStart: 0
requestStart: 5.089999998745043
responseEnd: 15.745000000606524
responseStart: 5.395000000135042
secureConnectionStart: 0
serverTiming: []
startTime: 0
transferSize: 0
type: "back_forward"
unloadEventEnd: 16.714999997930136
unloadEventStart: 16.709999999875436
workerStart: 0
}
PerformanceResourceTiming
检索和分析网络加载应用资源(例如 link/script/iframe 标签、css 中 url()
等)的详细网络计时数据。
[Exposed=(Window)]
interface PerformanceResourceTiming : PerformanceEntry {
readonly attribute DOMString initiatorType;
readonly attribute DOMHighResTimeStamp redirectStart;
readonly attribute DOMHighResTimeStamp redirectEnd;
readonly attribute DOMHighResTimeStamp fetchStart;
readonly attribute DOMHighResTimeStamp domainLookupStart;
readonly attribute DOMHighResTimeStamp domainLookupEnd;
readonly attribute DOMHighResTimeStamp connectStart;
readonly attribute DOMHighResTimeStamp connectEnd;
readonly attribute DOMHighResTimeStamp secureConnectionStart;
readonly attribute DOMHighResTimeStamp requestStart;
readonly attribute DOMHighResTimeStamp responseStart;
readonly attribute DOMHighResTimeStamp responseEnd;
serializer = {inherit, attribute};
};
{
connectEnd: 403.1199999990349
connectStart: 403.1199999990349
decodedBodySize: 33808
domainLookupEnd: 403.1199999990349
domainLookupStart: 403.1199999990349
duration: 1.6250000007858034
encodedBodySize: 33808
entryType: "resource"
fetchStart: 403.1199999990349
initiatorType: "link"
name: "https://developer.mozilla.org/static/fonts/locales/ZillaSlab-Regular.subset.bbc33fb47cf6.woff2"
nextHopProtocol: "h2"
redirectEnd: 0
redirectStart: 0
requestStart: 404.0950000016892
responseEnd: 404.7449999998207
responseStart: 404.3100000017148
secureConnectionStart: 0
serverTiming: []
startTime: 403.1199999990349
transferSize: 0
workerStart: 0
}
PerformancePaintTiming
网页构建期间有关“绘制(paint)”(也称为“渲染(render)”)操作的计时信息。“绘制(paint)”是指将渲染树转换为屏幕上的像素。
interface PerformancePaintTiming : PerformanceEntry {};
{
duration: 0
entryType: "paint"
name: "first-paint"
startTime: 667.9050000020652
}
参考资料:
- High Resolution Time Level 2
- MDN – Performance API
- Navigation Timing
- Performance Timeline Level 2