surfnperf 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2ebf230cbfd8dc288c35183b576965432d010f93
4
- data.tar.gz: 5ea5493fe01a15c3e89e310a85619c5a10f737c7
3
+ metadata.gz: 6e345d399d2630f3f58b9c21268597cf1d68beb9
4
+ data.tar.gz: 32baf5b753846d060524f9e195d87010251b5f2e
5
5
  SHA512:
6
- metadata.gz: a7d39899a860a238186e9228f1b404ffee2a09cd79ef43f2e415153a10f685730d41eba4af6f66b6ad2e51b413b8bace3e567a5c831f47d1c5dfc7555dfb7874
7
- data.tar.gz: 57d0f1897109c30d5f1e3a3084e8277ad826916b0b6e767947053d0c5c390e429f490f7fc1e0dd18d2b504c6bab63734b01de2e939919e81808e10d7e31bcdd4
6
+ metadata.gz: e53a18f7868588de15cb06dfc0b6dbcf9c89bca28ea6694047bbd68fb2fb4e6b26eb950cafb24c0aa39689535e7ced3bde9f378380168a3982d49fbf1e57fb9f
7
+ data.tar.gz: 0a711e5ab7c218d6274c94d2886e51814e15407cff9648dd08d8e337092ef7feea7775aaf0e0568c728bbb441309cb5d0db03f8dffc33463c701588315cefb87
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
- Surf-N-Perf
1
+ Surf-N-Perf
2
2
  ==============
3
3
 
4
- Micro-library for gathering frontend web page performance data.
4
+ Micro-library for gathering frontend web page performance data.
5
5
 
6
6
  Surf-N-Perf provides a simple to use API to gather [User Timing](http://www.w3.org/TR/user-timing/) and other important performance data in any browser.
7
7
 
@@ -41,6 +41,42 @@ There are 2 pieces of code that need to be included in your webpage:
41
41
  }
42
42
  }
43
43
 
44
+ SURF_N_PERF.visibility = {
45
+ initialState: document.visibilityState,
46
+ stateUpdates: [],
47
+ hiddenProperty: null,
48
+ stateProperty: null,
49
+ eventName: null,
50
+ markChange: function() {
51
+ var markName = 'visibility' + SURF_N_PERF.visibility.stateUpdates.length;
52
+
53
+ if (window.performance) {
54
+ if (window.performance.mark) {
55
+ window.performance.mark(markName);
56
+ }
57
+
58
+ if (window.performance.now) {
59
+ SURF_N_PERF.highResMarks[markName] = window.performance.now();
60
+ }
61
+ }
62
+
63
+ SURF_N_PERF.marks[markName] = new Date().getTime();
64
+
65
+ SURF_N_PERF.visibility.stateUpdates.push(document[SURF_N_PERF.visibility.stateProperty]);
66
+ },
67
+ };
68
+
69
+ if('hidden' in document) {
70
+ SURF_N_PERF.visibility.hiddenProperty = 'hidden';
71
+ SURF_N_PERF.visibility.stateProperty = 'visibilityState';
72
+ SURF_N_PERF.visibility.eventName = 'visibilitychange';
73
+ } else if('webkitHidden' in document) {
74
+ SURF_N_PERF.visibility.hiddenProperty = 'webkitHidden';
75
+ SURF_N_PERF.visibility.stateProperty = 'webkitVisibilityState';
76
+ SURF_N_PERF.visibility.eventName = 'webkitvisibilitychange';
77
+ SURF_N_PERF.visibility.initialState = document[SURF_N_PERF.visibility.stateProperty];
78
+ }
79
+
44
80
  SURF_N_PERF.setPageLoad = function() {
45
81
  SURF_N_PERF.marks.loadEventEnd = (new Date()).getTime();
46
82
 
@@ -54,7 +90,7 @@ There are 2 pieces of code that need to be included in your webpage:
54
90
 
55
91
  if(window.performance && window.performance.now) {
56
92
  SURF_N_PERF.highResMarks.firstPaintFrame = window.performance.now();
57
-
93
+
58
94
  if(window.performance.mark) {
59
95
  window.performance.mark('firstPaintFrame');
60
96
  }
@@ -62,6 +98,9 @@ There are 2 pieces of code that need to be included in your webpage:
62
98
  };
63
99
 
64
100
  if(window.addEventListener) {
101
+ if (SURF_N_PERF.visibility.stateProperty) {
102
+ document.addEventListener(SURF_N_PERF.visibility.eventName, SURF_N_PERF.visibility.markChange, false);
103
+ }
65
104
  window.addEventListener('load', SURF_N_PERF.setPageLoad, false);
66
105
  } else {
67
106
  window.attachEvent('onload', SURF_N_PERF.setPageLoad);
@@ -73,11 +112,13 @@ There are 2 pieces of code that need to be included in your webpage:
73
112
  ```
74
113
 
75
114
  That provides support for the following:
76
- - A "pageStart" mark for browsers that do not support [Navigation Timing](http://www.w3.org/TR/navigation-timing/) which can be used to compute durations from when the page first started loading (specifically, this mark falls between the [domLoading](http://www.w3.org/TR/navigation-timing/#dom-performancetiming-domloading) and [domInteractive](http://www.w3.org/TR/navigation-timing/#dom-performancetiming-dominteractive) attributes of Navigation Timing)
77
- - "pageStart" marks for browsers that support [High Resolution Time](http://www.w3.org/TR/hr-time/) and/or [User Timing](http://www.w3.org/TR/user-timing/) so that "pageStart" can be used as a consistent starting point for duration calculations across all browsers regardless of their supported features
78
- - A "loadEventEnd" mark for browsers that do not support [Navigation Timing](http://www.w3.org/TR/navigation-timing/) which can be used to compute durations from when the load event of the document is completed ([loadEventEnd](http://www.w3.org/TR/navigation-timing/#dom-performancetiming-loadend))
79
- - A "loadEventEnd" [DOMHighResTimeStamp](http://www.w3.org/TR/hr-time/#sec-DOMHighResTimeStamp) mark for calculating high resolution durations between a Navigation Timing mark and a user mark in browsers that support [High Resolution Time](http://www.w3.org/TR/hr-time/) but don't support [User Timing](http://www.w3.org/TR/user-timing/)
80
- - A "firstPaintFrame" mark (available in the best possible format for the browser, either a [User Timing Mark](http://www.w3.org/TR/user-timing/#performancemark), [DOMHighResTimeStamp](http://www.w3.org/TR/hr-time/#sec-DOMHighResTimeStamp), or [DOMTimeStamp](https://developer.mozilla.org/en-US/docs/Web/API/DOMTimeStamp)) that approximates the Time To First Paint in browsers that [support `window.requestAnimationFrame`](http://caniuse.com/#feat=requestanimationframe).
115
+
116
+ - A `"pageStart"` mark for browsers that do not support [Navigation Timing](http://www.w3.org/TR/navigation-timing/) which can be used to compute durations from when the page first started loading (specifically, this mark falls between the [`domLoading`](http://www.w3.org/TR/navigation-timing/#dom-performancetiming-domloading) and [`domInteractive`](http://www.w3.org/TR/navigation-timing/#dom-performancetiming-dominteractive) attributes of Navigation Timing)
117
+ - `"pageStart"` marks for browsers that support [High Resolution Time](http://www.w3.org/TR/hr-time/) and/or [User Timing](http://www.w3.org/TR/user-timing/) so that `"pageStart"` can be used as a consistent starting point for duration calculations across all browsers regardless of their supported features
118
+ - A `"loadEventEnd"` mark for browsers that do not support [Navigation Timing](http://www.w3.org/TR/navigation-timing/) which can be used to compute durations from when the load event of the document is completed ([`loadEventEnd`](http://www.w3.org/TR/navigation-timing/#dom-performancetiming-loadend))
119
+ - A `"loadEventEnd"` [DOMHighResTimeStamp](http://www.w3.org/TR/hr-time/#sec-DOMHighResTimeStamp) mark for calculating high resolution durations between a Navigation Timing mark and a user mark in browsers that support [High Resolution Time](http://www.w3.org/TR/hr-time/) but don't support [User Timing](http://www.w3.org/TR/user-timing/)
120
+ - A `"firstPaintFrame"` mark (available in the best possible format for the browser, either a [User Timing Mark](http://www.w3.org/TR/user-timing/#performancemark), [DOMHighResTimeStamp](http://www.w3.org/TR/hr-time/#sec-DOMHighResTimeStamp), or [DOMTimeStamp](https://developer.mozilla.org/en-US/docs/Web/API/DOMTimeStamp)) that approximates the Time To First Paint in browsers that [support `window.requestAnimationFrame`](http://caniuse.com/#feat=requestanimationframe).
121
+ - The initial `visibilityState` as well as listeners for the `"visibilitychange"` event, enabling the ability to calculate how much time the page was hidden when you call `surfnperf.getHiddenTime()`. This is of particular importance as [Chrome as of version 57](https://developers.google.com/web/updates/2017/03/background_tabs) and [Firefox as of version 57](https://blog.mozilla.org/blog/2017/09/26/firefox-quantum-beta-developer-edition/) limit the resources assigned to background (hidden) tabs.
81
122
 
82
123
  **2.** Then just drop the [surfnperf.min.js](https://github.com/Comcast/Surf-N-Perf/blob/master/surfnperf.min.js) in your codebase and reference that JavaScript file in your HTML document. If you're using [RequireJS](http://requirejs.org/) or [Browserify](http://browserify.org/), it registers itself as 'surfnperf'.
83
124
 
@@ -15,6 +15,42 @@
15
15
  }
16
16
  }
17
17
 
18
+ SURF_N_PERF.visibility = {
19
+ initialState: document.visibilityState,
20
+ stateUpdates: [],
21
+ hiddenProperty: null,
22
+ stateProperty: null,
23
+ eventName: null,
24
+ markChange: function() {
25
+ var markName = 'visibility' + SURF_N_PERF.visibility.stateUpdates.length;
26
+
27
+ if (window.performance) {
28
+ if (window.performance.mark) {
29
+ window.performance.mark(markName);
30
+ }
31
+
32
+ if (window.performance.now) {
33
+ SURF_N_PERF.highResMarks[markName] = window.performance.now();
34
+ }
35
+ }
36
+
37
+ SURF_N_PERF.marks[markName] = new Date().getTime();
38
+
39
+ SURF_N_PERF.visibility.stateUpdates.push(document[SURF_N_PERF.visibility.stateProperty]);
40
+ },
41
+ };
42
+
43
+ if('hidden' in document) {
44
+ SURF_N_PERF.visibility.hiddenProperty = 'hidden';
45
+ SURF_N_PERF.visibility.stateProperty = 'visibilityState';
46
+ SURF_N_PERF.visibility.eventName = 'visibilitychange';
47
+ } else if('webkitHidden' in document) {
48
+ SURF_N_PERF.visibility.hiddenProperty = 'webkitHidden';
49
+ SURF_N_PERF.visibility.stateProperty = 'webkitVisibilityState';
50
+ SURF_N_PERF.visibility.eventName = 'webkitvisibilitychange';
51
+ SURF_N_PERF.visibility.initialState = document[SURF_N_PERF.visibility.stateProperty];
52
+ }
53
+
18
54
  SURF_N_PERF.setPageLoad = function() {
19
55
  SURF_N_PERF.marks.loadEventEnd = (new Date()).getTime();
20
56
 
@@ -28,7 +64,7 @@
28
64
 
29
65
  if(window.performance && window.performance.now) {
30
66
  SURF_N_PERF.highResMarks.firstPaintFrame = window.performance.now();
31
-
67
+
32
68
  if(window.performance.mark) {
33
69
  window.performance.mark('firstPaintFrame');
34
70
  }
@@ -36,13 +72,14 @@
36
72
  };
37
73
 
38
74
  if(window.addEventListener) {
75
+ if (SURF_N_PERF.visibility.stateProperty) {
76
+ document.addEventListener(SURF_N_PERF.visibility.eventName, SURF_N_PERF.visibility.markChange, false);
77
+ }
39
78
  window.addEventListener('load', SURF_N_PERF.setPageLoad, false);
40
79
  } else {
41
80
  window.attachEvent('onload', SURF_N_PERF.setPageLoad);
42
81
  }
43
-
44
82
  if (window.requestAnimationFrame) {
45
83
  window.requestAnimationFrame(SURF_N_PERF.setFirstPaint);
46
84
  }
47
-
48
85
  </script>
@@ -262,37 +262,59 @@
262
262
  return this._round(b - a, options);
263
263
  };
264
264
 
265
- SNPProto._measureName = function(a, b) {
266
- return '_SNP_' + a + '_TO_' + b;
265
+ SNPProto._measureName = function(startMark, endMark) {
266
+ return '_SNP_' + startMark + '_TO_' + endMark;
267
267
  };
268
268
 
269
- SNPProto._setMeasure = function(a, b) {
269
+ SNPProto._setMeasure = function(startMark, endMark) {
270
270
  try {
271
- this.userTiming().measure(this._measureName(a, b), a, b);
271
+ this.userTiming().measure(this._measureName(startMark, endMark), startMark, endMark);
272
272
  } catch(e) {
273
273
  if(window.console && window.console.error) {
274
274
  if(e && e.message) {
275
275
  console.error("Surf-N-Perf Exception:", e.message);
276
276
  } else {
277
- console.error("Surf-N-Perf Exception: at least one of these events/marks is not available yet", a, b);
277
+ console.error("Surf-N-Perf Exception: at least one of these events/marks is not available yet", startMark, endMark);
278
278
  }
279
279
  }
280
280
  }
281
281
  };
282
282
 
283
- SNPProto._getMeasureDuration = function(a, b) {
284
- var measure = this.userTiming().getEntriesByName(this._measureName(a, b))[0] || {};
283
+ SNPProto._getMeasureDuration = function(startMark, endMark) {
284
+ var measure = this.userTiming().getEntriesByName(this._measureName(startMark, endMark))[0] || {};
285
285
  return measure.duration;
286
286
  };
287
287
 
288
- SNPProto.duration = function(a, b, options) {
288
+ /**
289
+ * Marks the current time
290
+ *
291
+ * @returns {String} name generated for the mark
292
+ * @memberOf SurfNPerf
293
+ */
294
+ SNPProto.markNow = function() {
295
+ var eventKey = '_NOW_' + this.now('DOM');
296
+ this.mark(eventKey);
297
+ return eventKey;
298
+ };
299
+
300
+ /**
301
+ * Returns the duration between two marks
302
+ *
303
+ * @param {String} startMark name of the first mark
304
+ * @param {String} [endMark] optional name of the second mark
305
+ * @returns {Number} duration between the two specified marks. If the endMark is not specified, returns the duration between the startMark and the current time
306
+ * @memberOf SurfNPerf
307
+ */
308
+ SNPProto.duration = function(startMark, endMark, options) {
309
+ endMark = endMark || this.markNow();
310
+
289
311
  if(this._userTiming) {
290
- this._setMeasure(a, b);
291
- return this._round(this._getMeasureDuration(a, b), options);
292
- } else if(this._highResTime && a === 'navigationStart' && !this._isTimingMark(b)) {
293
- return this._round(this.getMark(b), options);
312
+ this._setMeasure(startMark, endMark);
313
+ return this._round(this._getMeasureDuration(startMark, endMark), options);
314
+ } else if(this._highResTime && startMark === 'navigationStart' && !this._isTimingMark(endMark)) {
315
+ return this._round(this.getMark(endMark), options);
294
316
  } else {
295
- return this._roundedDuration(this._getDurationMark(a), this._getDurationMark(b), options);
317
+ return this._roundedDuration(this._getDurationMark(startMark), this._getDurationMark(endMark), options);
296
318
  }
297
319
  };
298
320
 
@@ -446,6 +468,56 @@
446
468
  }
447
469
  };
448
470
 
471
+ /**
472
+ * Is the page hidden or not, as reported by the Page Visibility API
473
+ *
474
+ * @returns {boolean} true if the page is in a state considered to be hidden to the user, and false otherwise.
475
+ * @memberOf SurfNPerf
476
+ */
477
+ SNPProto.isHidden = function() {
478
+ if(SURF_N_PERF.visibility && SURF_N_PERF.visibility.hiddenProperty) {
479
+ return document[SURF_N_PERF.visibility.hiddenProperty];
480
+ } else {
481
+ return null;
482
+ }
483
+ };
484
+
485
+ /**
486
+ * Total time a page is not visible, as reported by the Page Visibility API
487
+ *
488
+ * @returns {integer} time in ms
489
+ * @memberOf SurfNPerf
490
+ */
491
+ SNPProto.getHiddenTime = function(options) {
492
+ var total = 0,
493
+ states = [],
494
+ i,
495
+ length,
496
+ getMarkName = function(index) {
497
+ return index === 0 ? 'navigationStart' : 'visibility' + (index - 1);
498
+ };
499
+
500
+ if(SURF_N_PERF.visibility && SURF_N_PERF.visibility.initialState && SURF_N_PERF.visibility.stateUpdates) {
501
+ states = states.concat(SURF_N_PERF.visibility.initialState, SURF_N_PERF.visibility.stateUpdates);
502
+ length = states.length;
503
+ for(i = 1; i < length; i++) {
504
+ if(states[i - 1] !== 'visible' && states[i] === 'visible') {
505
+ total += this.duration(getMarkName(i - 1), getMarkName(i), {
506
+ decimalPlaces: 10
507
+ });
508
+ }
509
+ }
510
+ if(states[length - 1] !== 'visible') {
511
+ total += this.duration(getMarkName(length - 1), null, {
512
+ decimalPlaces: 10
513
+ });
514
+ }
515
+ return this._round(total, options);
516
+ } else {
517
+ return null;
518
+ }
519
+ };
520
+
449
521
  return new SurfNPerf();
450
522
 
451
523
  }));
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: surfnperf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Riviello
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-06 00:00:00.000000000 Z
11
+ date: 2017-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -73,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
73
  version: '0'
74
74
  requirements: []
75
75
  rubyforge_project:
76
- rubygems_version: 2.6.10
76
+ rubygems_version: 2.6.13
77
77
  signing_key:
78
78
  specification_version: 4
79
79
  summary: Micro-library for gathering frontend web page performance data