├── icon.png
├── versions
└── 1-0.zip
├── chrome-webstore
├── icon-128.png
├── promo-440.png
├── promo-920.png
├── promo-1440.png
├── screenshot-01.png
└── screenshot-02.png
├── onload-execute.js
├── README.md
├── manifest.json
├── performance.js
├── popup.html
├── LICENSE
├── performance.css
└── popup.js
/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GregM/performance-timing-google-chrome-extension/HEAD/icon.png
--------------------------------------------------------------------------------
/versions/1-0.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GregM/performance-timing-google-chrome-extension/HEAD/versions/1-0.zip
--------------------------------------------------------------------------------
/chrome-webstore/icon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GregM/performance-timing-google-chrome-extension/HEAD/chrome-webstore/icon-128.png
--------------------------------------------------------------------------------
/chrome-webstore/promo-440.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GregM/performance-timing-google-chrome-extension/HEAD/chrome-webstore/promo-440.png
--------------------------------------------------------------------------------
/chrome-webstore/promo-920.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GregM/performance-timing-google-chrome-extension/HEAD/chrome-webstore/promo-920.png
--------------------------------------------------------------------------------
/chrome-webstore/promo-1440.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GregM/performance-timing-google-chrome-extension/HEAD/chrome-webstore/promo-1440.png
--------------------------------------------------------------------------------
/chrome-webstore/screenshot-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GregM/performance-timing-google-chrome-extension/HEAD/chrome-webstore/screenshot-01.png
--------------------------------------------------------------------------------
/chrome-webstore/screenshot-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GregM/performance-timing-google-chrome-extension/HEAD/chrome-webstore/screenshot-02.png
--------------------------------------------------------------------------------
/onload-execute.js:
--------------------------------------------------------------------------------
1 | window.addEventListener("load", function load(event){
2 | window.removeEventListener("load", load, false);
3 | //console.log("Web Performance Timing API data ready.")
4 | },false);
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | performance-timing-google-chrome-extension
2 | ==========================================
3 |
4 | Web Performance Timing API Google Chrome Extension
5 |
6 | Available here: https://chrome.google.com/webstore/detail/web-performance-timing-ap/nllipdabkglnhmanndddgcihbcmjpfej?hl=en-US&authuser=1
7 |
8 | 
9 |
10 | Available under MIT License
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest_version": 2,
3 |
4 | "name": "Web Performance Timing API",
5 | "description": "Graphs common performance timing data from your current website using the performance timing API.",
6 | "version": "1.0",
7 | "browser_action": {
8 | "default_icon": "icon.png",
9 | "default_popup": "popup.html"
10 | },
11 | "permissions": [
12 | "tabs", "http://*/*", "https://*/*"
13 | ]
14 | }
--------------------------------------------------------------------------------
/performance.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | var p = {};
3 |
4 | p.prerequestTime = performance.timing.requestStart - performance.timing.navigationStart;
5 | p.latencyTime = performance.timing.responseStart - performance.timing.requestStart;
6 | p.serverTime = performance.timing.responseEnd - performance.timing.responseStart;
7 | p.domLoadingTime = performance.timing.domInteractive - performance.timing.responseEnd;
8 | p.domCompleteTime = performance.timing.domComplete - performance.timing.domInteractive;
9 | p.loadTime = performance.timing.loadEventEnd - performance.timing.domComplete;
10 |
11 | // Test to make sure these two variables match.
12 | // p.onloadTime = performance.timing.loadEventEnd - performance.timing.navigationStart;
13 | p.totalTime = p.prerequestTime + p.latencyTime + p.serverTime + p.domLoadingTime + p.domCompleteTime + p.loadTime;
14 |
15 | return p;
16 | })();
--------------------------------------------------------------------------------
/popup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Web Performance API Timing
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Gregory Mazurek
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/performance.css:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: white;
3 | border: 1px solid #EFEFEF;
4 | margin: 10px;
5 | min-width: 475px;
6 | overflow-x: hidden;
7 | padding: 10px;
8 | }
9 |
10 | .header.label {
11 | font-size: 13px;
12 | font-weight: bold;
13 | width: 150px;
14 | }
15 |
16 | .header.performance-label, .header.performance-time {
17 | border: 0;
18 | margin: 10px 0 10px;
19 | text-decoration: underline;
20 | }
21 |
22 | .performance-label, .performance-time,
23 | .performance-graph,
24 | .performance-graph-pre, .performance-graph-key, .performance-graph-post,
25 | .performance-graph-total {
26 | display: block;
27 | float: left;
28 | height: 20px;
29 | line-height: 20px;
30 | }
31 |
32 | .performance-row:hover {
33 | background-color: #EFEFEF;
34 | }
35 |
36 | .performance-row.key-0 {
37 | border-bottom: 1px solid grey;
38 | padding-bottom: 10px;
39 | }
40 |
41 | .performance-label {
42 | border-right: 1px solid grey;
43 | width: 100px;
44 | }
45 |
46 | .performance-time {
47 | padding: 0 0 0 20px;
48 | text-align: right;
49 | width: 60px;
50 | }
51 |
52 | .performance-graph, .performance-graph-total {
53 | height: 20px;
54 | padding: 0 20px;
55 | width: 250px;
56 | }
57 |
58 | .performance-graph-key.key-0 {
59 | background-color: #511906;
60 | }
61 | .performance-graph-key.key-1 {
62 | background-color: #946250;
63 | }
64 | .performance-graph-key.key-2 {
65 | background-color: #4D9371;
66 | }
67 | .performance-graph-key.key-3 {
68 | background-color: #06436B;
69 | }
70 | .performance-graph-key.key-4 {
71 | background-color: #F2A74C;
72 | }
73 | .performance-graph-key.key-5 {
74 | background-color: #3D85B3;
75 | }
76 | .performance-graph-key.key-6 {
77 | background-color: #3B7559;
78 | }
79 |
80 | .clearfix:before,
81 | .clearfix:after {
82 | content: " ";
83 | display: table;
84 | }
85 |
86 | .clearfix:after {
87 | clear: both;
88 | }
89 |
90 | .footer, .explanation {
91 | margin-top: 10px;
92 | }
--------------------------------------------------------------------------------
/popup.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | /* Key for total loading time of page */
4 | var PAGE_LOAD_KEY = "totalTime";
5 |
6 | /* Global mutable variables used throughout */
7 | var precedingTime = pageLoadTotalTime = counter = 0;
8 |
9 | /* The data that will be displayed to the end user */
10 | /* At some point, share orderOfEvents and eval() on orderOfEvents.calculation */
11 | var orderOfEvents = [{
12 | 'key': 'prerequestTime',
13 | 'label': 'Pre-request',
14 | 'calculation': 'performance.timing.requestStart - performance.timing.navigationStart'
15 | }, {
16 | 'key': 'latencyTime',
17 | 'label': 'Latency',
18 | 'calculation': 'performance.timing.responseStart - performance.timing.requestStart'
19 | }, {
20 | 'key': 'serverTime',
21 | 'label': 'Server',
22 | 'calculation': 'performance.timing.responseEnd - performance.timing.responseStart'
23 | }, {
24 | 'key': 'domLoadingTime',
25 | 'label': 'DOM Loading',
26 | 'calculation': 'performance.timing.domInteractive - performance.timing.responseEnd'
27 | }, {
28 | 'key': 'domCompleteTime',
29 | 'label': 'DOM Complete',
30 | 'calculation': 'performance.timing.domComplete - performance.timing.domInteractive'
31 | }, {
32 | 'key': 'loadTime',
33 | 'label': 'Load',
34 | 'calculation': 'performance.timing.loadEventEnd - performance.timing.domComplete'
35 | }];
36 |
37 |
38 | chromeExtension = {
39 |
40 | /**
41 | * Generate everything.
42 | *
43 | * @private
44 | */
45 | generate: function () {
46 |
47 | chrome.tabs.executeScript(
48 | {
49 | file: 'performance.js'
50 | },
51 | function(result, isException) {
52 | if (isException) {
53 | //console.log("There was an error with counting elements on this page.");
54 | } else {
55 | pageLoadTotalTime = result[0][PAGE_LOAD_KEY];
56 | var dataParent = document.getElementsByClassName('data')[0];
57 |
58 | var node = chromeExtension.createRow(PAGE_LOAD_KEY, pageLoadTotalTime, 0, pageLoadTotalTime);
59 | dataParent.appendChild(node);
60 |
61 | chromeExtension.incrementCounter();
62 |
63 | for (var i in orderOfEvents) {
64 | var key = orderOfEvents[i].key;
65 | var time = result[0][key];
66 | var displayName = orderOfEvents[i].label;
67 | var dataRow = chromeExtension.createRow(displayName, time);
68 |
69 | dataParent.appendChild(dataRow);
70 |
71 | precedingTime = precedingTime + time;
72 | chromeExtension.incrementCounter();
73 | }
74 | chromeExtension.createRowMouseOverEvent();
75 | }
76 | }
77 | );
78 | },
79 |
80 | /**
81 | * Increments global counter
82 | *
83 | * @private
84 | */
85 | incrementCounter: function() {
86 | counter = counter + 1;
87 | },
88 |
89 | /**
90 | * Create a new row with the data passed through
91 | *
92 | * @param {String} key for performance api metric
93 | * @param {Number} value for performance api metric
94 | * @private
95 | */
96 | createRow: function (key, value) {
97 | var bar, clearfix, barCopy;
98 |
99 | var d = document.createElement('div');
100 | d.className = 'performance-row performance-row-' + counter + ' key-' + counter;
101 |
102 | var label = document.createElement('span');
103 | label.className = 'performance-label';
104 | label.textContent = key;
105 |
106 | var time = document.createElement('span');
107 | time.className = 'performance-time';
108 | time.textContent = value + " ms";
109 |
110 | bar = (key === PAGE_LOAD_KEY) ? this.createGraphTotal() : this.createGraph(key, value, counter);
111 | if (document.getElementsByClassName('performance-graph-total')[0]) {
112 | barCopy = this.createChartData(value, counter);
113 | document.getElementsByClassName('performance-graph-total')[0].appendChild(barCopy);
114 | }
115 |
116 | d.appendChild(label);
117 | d.appendChild(bar);
118 | d.appendChild(time);
119 |
120 | clearfix = this.createClearfixDOMElement();
121 | d.appendChild(clearfix);
122 | return d;
123 | },
124 |
125 | /**
126 | * Create a new graph wrapper so that the totals can be passed through
127 | *
128 | * @private
129 | */
130 | createGraphTotal: function() {
131 | var g = document.createElement('div');
132 | g.className = 'performance-graph-total';
133 | return g;
134 | },
135 |
136 | /**
137 | * Create a new graph with the data passed through
138 | *
139 | * @param {String} DOM element name
140 | * @param {Number} current tally of milliseconds passed
141 | * @private
142 | */
143 | createGraph: function(key, value) {
144 | var g = document.createElement('span');
145 | g.className = 'performance-graph ' + key;
146 |
147 | var preTime = this.createPreChartSpacing(counter);
148 | var thisKeyTime = this.createChartData(value, counter);
149 | var clearfix = this.createClearfixDOMElement();
150 |
151 | g.appendChild(preTime);
152 | g.appendChild(thisKeyTime);
153 | g.appendChild(clearfix);
154 |
155 | return g;
156 | },
157 |
158 | /**
159 | * Create an the bar which is a percentage of its parent.
160 | *
161 | * @param {Number} value of the data point
162 | *
163 | * @private
164 | */
165 | createChartData: function(value) {
166 | var d = document.createElement('span');
167 | d.className = 'performance-graph-key key-' + counter;
168 | d.style.width = (value / pageLoadTotalTime * 100) + '%';
169 | return d;
170 | },
171 |
172 | /**
173 | * Create a pre DOM element and assign it to be a percentage
174 | * equal to everything that has been allocated so far.
175 | *
176 | * @private
177 | */
178 | createPreChartSpacing: function() {
179 | var d = document.createElement('span');
180 | d.className = 'performance-graph-pre key-' + counter;
181 | d.style.width = (precedingTime / pageLoadTotalTime * 100) + '%';
182 | return d;
183 | },
184 |
185 | /**
186 | * Create a clearfix DOM element
187 | *
188 | * @private
189 | */
190 | createClearfixDOMElement: function() {
191 | var c = document.createElement('span');
192 | c.className = 'clearfix';
193 | return c;
194 | },
195 |
196 | /**
197 | * Create an onmouseover event on each row
198 | *
199 | * @private
200 | */
201 | createRowMouseOverEvent: function() {
202 | var explanation = document.getElementsByClassName('explanation')[0];
203 | var preText = "Calc: ";
204 | for (var i = 1; i < (orderOfEvents.length + 1); i++) {
205 | document.getElementsByClassName('performance-row-' + i)[0].onmouseout= function() {
206 | explanation.innerHTML = ' ';
207 | };
208 | }
209 | document.getElementsByClassName('performance-row-1')[0].onmouseover = function() {
210 | explanation.innerHTML = preText + orderOfEvents[0].calculation;
211 | };
212 | document.getElementsByClassName('performance-row-2')[0].onmouseover = function() {
213 | explanation.innerHTML = preText + orderOfEvents[1].calculation;
214 | };
215 | document.getElementsByClassName('performance-row-3')[0].onmouseover = function() {
216 | explanation.innerHTML = preText + orderOfEvents[2].calculation;
217 | };
218 | document.getElementsByClassName('performance-row-4')[0].onmouseover = function() {
219 | explanation.innerHTML = preText + orderOfEvents[3].calculation;
220 | };
221 | document.getElementsByClassName('performance-row-5')[0].onmouseover = function() {
222 | explanation.innerHTML = preText + orderOfEvents[4].calculation;
223 | };
224 | document.getElementsByClassName('performance-row-6')[0].onmouseover = function() {
225 | explanation.innerHTML = preText + orderOfEvents[5].calculation;
226 | };
227 | },
228 |
229 | /**
230 | * Execute
231 | *
232 | */
233 | init: function () {
234 | chrome.tabs.executeScript(
235 | {
236 | file: 'onload-execute.js'
237 | },
238 | function(result, isException) {
239 | if (result) {
240 | chromeExtension.generate();
241 | } else {
242 | //console.log("There was an error retrieving Web Performing API Timing information");
243 | }
244 | });
245 | }
246 |
247 | }
248 |
249 | window.addEventListener("load", function load(event){
250 | window.removeEventListener("load", load, false);
251 | chromeExtension.init();
252 | },false);
253 |
254 | })();
--------------------------------------------------------------------------------