-
Notifications
You must be signed in to change notification settings - Fork 4
/
timing.html
156 lines (126 loc) · 5.89 KB
/
timing.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<!doctype html>
<html>
<head>
<title>Image Custom Metric</title>
<script>
var bNav = window.performance;
var bRT = (window.performance && window.performance.getEntries);
var bMO = ( "undefined" != typeof(MutationObserver) );
var t_top = new Date().getTime();
var t_onload, t_img, t_script;
// Used by Mutation Observer.
function observerCallback(mutations) {
if ( !mutations || !mutations.length ) {
return;
}
mutations.forEach( function(mutation) {
if ( mutation.type === "attributes" ) {
// we can check if the changed attribute values are interesting to us
// mutation.target is the node that changed and mutation.attributeName
// is the attribute that changed
}
else if ( mutation.type === "childList" ) {
// mutation.addedNodes is not a real array, so convert it to one
[].slice.call(mutation.addedNodes).forEach(function(node) {
if ( node.nodeType === Node.ELEMENT_NODE && "undefined" !== typeof(ghKeyElements[node.id]) ) {
// offsetHeight and offsetWidth are set when something is rendered to screen
var delta = new Date().getTime() - t_top;
if ( node.naturalWidth ) {
ghKeyElements[node.id].push("" + delta + " ms");
}
else {
ghKeyElements[node.id].push("" + delta + " ms");
}
}
});
}
});
}
// Poll to see when images are rendered.
function imagePolling() {
var bPoll = false; // do NOT continue polling unless we have to
for ( var id in ghImagePolling ) {
if ( ghImagePolling.hasOwnProperty(id) ) {
var elem = document.getElementById(id);
if ( elem && "IMG" == elem.tagName && elem.offsetHeight ) {
ghImagePolling[id] = new Date().getTime();
}
else {
bPoll = true;
}
}
}
if ( bPoll ) {
setTimeout(imagePolling, 100);
}
}
// a hash of element IDs we want to observe where the value is an array of mutation times
var ghKeyElements = { heroimg: [], calltoaction: [] };
if ( bMO ) {
var observer = new MutationObserver(observerCallback);
observer.observe(document, { childList: true, attributes: true, subtree: true });
}
var ghImagePolling = { heroimg: 0 }; // a hash of image IDs and their offsetHeight time
imagePolling();
window.onload = function() {
t_onload = new Date().getTime();
var imageEntry, cssEntry;
if ( bRT ) {
var aEntries = performance.getEntries();
for ( var i = 0, len = aEntries.length; i < len; i++ ) {
var e = aEntries[i];
if ( -1 != e.name.indexOf("resource.cgi?type=gif") ) {
imageEntry = e;
}
else if ( -1 != e.name.indexOf("resource.cgi?type=css") ) {
cssEntry = e;
}
}
}
var t_onloadhandler = t_img - t_top;
var t_inlinescript = t_afterImage - t_top;
var t_custommetric = Math.max(t_onloadhandler, t_inlinescript);
document.getElementById("resourcetiming").innerHTML = ( imageEntry ? Math.round(imageEntry.fetchStart + imageEntry.duration) + " ms" : "not supported" );
document.getElementById("onloadhandler").innerHTML = t_onloadhandler + " ms";
document.getElementById("inlinescript").innerHTML = t_inlinescript + " ms";
document.getElementById("mutobserver").innerHTML = ( bMO ? ghKeyElements["heroimg"].join(", ") : "not supported" );
document.getElementById("polling").innerHTML = ( ghImagePolling["heroimg"] ? (ghImagePolling["heroimg"] - t_top) + " ms" : "not found" );
document.getElementById("custommetric").innerHTML = t_custommetric + " ms";
document.getElementById("bnavtiming").innerHTML = ( bNav ? "" : "Nav timing not supported." );
}
</script>
<script src="//stevesouders.com/bin/resource.cgi?type=js&sleep=3&t=1429640818" onload="t_script=new Date().getTime()"></script>
<link href="//stevesouders.com/bin/resource.cgi?type=css&sleep=5&t=1429640818" rel="stylesheet">
<style type="text/css">
@font-face {
font-family: "Yanone";
src: url('/bin/resource.cgi?type=font&sleep=7&t=1429640818');
src: local('Yanone'), url('/bin/resource.cgi?type=font&sleep=6&t=1429640818') format("truetype");
}
TD { padding: 10px 20px; }
.timing { font-size: 2em; text-align: right; }
.timeval { font-size: 3em; color: orange; font-weight: bold; text-align: right; }
</style>
</head>
<body style="width: 900px; font-family: helvetica, arial; background: #000; color: #FFF;">
<h1 style="margin-left: 3em; font-size: 3em;">Image Custom Metric</h1>
<!-- This is to see if fonts have an affect, but I know they do not so I hide the text to make the page cleaner. -->
<div style="font-family: Yanone; color: black">Image Custom Metric</div>
<div style="float: left; background: white; margin-bottom: 2em; margin-left: 3em; padding: 4px;">
<img id=heroimg src="//stevesouders.com/bin/resource.cgi?type=gif&sleep=1&t=1429640818" onload="t_img=new Date().getTime()" height=50>
</div>
<script>
var t_afterImage = new Date().getTime();
</script>
<table style="clear: both;">
<tr> <td class=timing>RESOURCE TIMING:</td> <td class="timeval" id=resourcetiming>...</td> </tr>
<tr> <td class=timing>IMAGE ONLOAD:</td> <td class="timeval" id=onloadhandler>...</td> </tr>
<tr> <td class=timing>INLINE SCRIPT:</td> <td class="timeval" id=inlinescript>...</td> </tr>
<tr> <td class=timing>MUTATION OBSERVER:</td> <td class="timeval" id=mutobserver>...</td> </tr>
<tr> <td class=timing>offsetHeight POLLING:</td> <td class="timeval" id=polling>...</td> </tr>
<tr> <td class=timing>CUSTOM METRIC:</td> <td class="timeval" id=custommetric>...</td> </tr>
</table>
<p id="bnavtiming">
</p>
</body>
</html>