first-input-delay
Advanced tools
Comparing version 0.1.1 to 0.1.2
# Changelog | ||
### 0.1.2 (2018-08-09) | ||
- Filter out more erroneous values (#8) | ||
### 0.1.1 (2018-06-09) | ||
- Fix erroneous values on certain browsers (#5) | ||
- Filter out erroneous values (#5) | ||
@@ -7,0 +11,0 @@ ### 0.1.0 (2018-05-08) |
@@ -16,3 +16,3 @@ /* | ||
(function(){function g(a,b){d||(d=!0,f=a,h=b,k.forEach(function(a){removeEventListener(a,l,e)}),m())}function m(){d&&0<c.length&&(c.forEach(function(a){a(f,h)}),c=[])}function n(a,b){function c(){g(a,b);f()}function d(){f()}function f(){removeEventListener("pointerup",c,e);removeEventListener("pointercancel",d,e)}addEventListener("pointerup",c,e);addEventListener("pointercancel",d,e)}function l(a){if(a.cancelable){var b=a.timeStamp;b=Math.max((1E12<b?+new Date:performance.now())-b,0);"pointerdown"== | ||
a.type?n(b,a):g(b,a)}}var e={passive:!0,capture:!0},k=["click","mousedown","keydown","touchstart","pointerdown"],d=!1,f,h,c=[];k.forEach(function(a){addEventListener(a,l,e)});window.perfMetrics=window.perfMetrics||{};window.perfMetrics.onFirstInputDelay=function(a){c.push(a);m()}})(); | ||
(function(){function g(a,b){d||(d=b,c=a,h=new Date,k(removeEventListener),l())}function l(){0<=c&&c<h-m&&(e.forEach(function(a){a(c,d)}),e=[])}function n(a,b){function c(){g(a,b);e()}function d(){e()}function e(){removeEventListener("pointerup",c,f);removeEventListener("pointercancel",d,f)}addEventListener("pointerup",c,f);addEventListener("pointercancel",d,f)}function p(a){if(a.cancelable){var b=(1E12<a.timeStamp?new Date:performance.now())-a.timeStamp;"pointerdown"==a.type?n(b,a):g(b,a)}}function k(a){["click", | ||
"mousedown","keydown","touchstart","pointerdown"].forEach(function(b){a(b,p,f)})}var d,c,h,e=[],f={passive:!0,capture:!0},m=new Date;k(addEventListener);self.perfMetrics=self.perfMetrics||{};self.perfMetrics.onFirstInputDelay=function(a){e.push(a);l()}})(); |
{ | ||
"name": "first-input-delay", | ||
"version": "0.1.1", | ||
"version": "0.1.2", | ||
"description": "A JavaScript library for measuring the First Input Delay metric. See https://goo.gl/1AKcj5.", | ||
@@ -5,0 +5,0 @@ "main": "src/first-input-delay.js", |
@@ -21,3 +21,3 @@ # First Input Delay | ||
Since it's less than 400 bytes, we recommended you inline it directly into your document `<head>` to avoid a blocking request. | ||
Since it's less than 400 bytes (gzipped), we recommended you inline it directly into your document `<head>` to avoid a blocking request. | ||
@@ -24,0 +24,0 @@ **2) Register a callback to run when FID is detected.** |
@@ -17,16 +17,10 @@ /* | ||
(function() { | ||
var firstInputEvent; | ||
var firstInputDelay; | ||
var firstInputTimeStamp; | ||
var callbacks = []; | ||
var listenerOpts = {passive: true, capture: true}; | ||
var eventTypes = [ | ||
'click', | ||
'mousedown', | ||
'keydown', | ||
'touchstart', | ||
'pointerdown', | ||
]; | ||
var startTimeStamp = new Date; | ||
var firstInputOccurred = false; | ||
var firstInputDelay; | ||
var firstInputEvent; | ||
var firstInputCallbacks = []; | ||
/** | ||
@@ -38,4 +32,4 @@ * Accepts a callback to be invoked once the first input delay and event | ||
function onFirstInputDelay(callback) { | ||
firstInputCallbacks.push(callback); | ||
reportDelayIfReady(); | ||
callbacks.push(callback); | ||
reportFirstInputDelayIfRecordedAndValid(); | ||
} | ||
@@ -49,13 +43,10 @@ | ||
*/ | ||
function recordDelay(delay, evt) { | ||
if (!firstInputOccurred) { | ||
firstInputOccurred = true; | ||
function recordFirstInputDelay(delay, evt) { | ||
if (!firstInputEvent) { | ||
firstInputEvent = evt; | ||
firstInputDelay = delay; | ||
firstInputEvent = evt; | ||
firstInputTimeStamp = new Date; | ||
eventTypes.forEach(function(eventType) { | ||
removeEventListener(eventType, onInput, listenerOpts); | ||
}); | ||
reportDelayIfReady(); | ||
eachEventType(removeEventListener); | ||
reportFirstInputDelayIfRecordedAndValid(); | ||
} | ||
@@ -65,11 +56,17 @@ } | ||
/** | ||
* Reports the first input delay and event (if set) by invoking the set of | ||
* callback function (if set). If any of these are not set, nothing happens. | ||
* Reports the first input delay and event (if they're recorded and valid) | ||
* by running the array of callback functions. | ||
*/ | ||
function reportDelayIfReady() { | ||
if (firstInputOccurred && firstInputCallbacks.length > 0) { | ||
firstInputCallbacks.forEach(function(callback) { | ||
function reportFirstInputDelayIfRecordedAndValid() { | ||
// In some cases the recorded delay is clearly wrong, e.g. it's negative | ||
// or it's larger than the time between now and when the page was loaded. | ||
// - https://github.com/GoogleChromeLabs/first-input-delay/issues/4 | ||
// - https://github.com/GoogleChromeLabs/first-input-delay/issues/6 | ||
// - https://github.com/GoogleChromeLabs/first-input-delay/issues/7 | ||
if (firstInputDelay >= 0 && | ||
firstInputDelay < firstInputTimeStamp - startTimeStamp) { | ||
callbacks.forEach(function(callback) { | ||
callback(firstInputDelay, firstInputEvent); | ||
}); | ||
firstInputCallbacks = []; | ||
callbacks = []; | ||
} | ||
@@ -95,4 +92,4 @@ } | ||
function onPointerUp() { | ||
recordDelay(delay, evt); | ||
removeListeners(); | ||
recordFirstInputDelay(delay, evt); | ||
removePointerEventListeners(); | ||
} | ||
@@ -106,3 +103,3 @@ | ||
function onPointerCancel() { | ||
removeListeners(); | ||
removePointerEventListeners(); | ||
} | ||
@@ -113,3 +110,3 @@ | ||
*/ | ||
function removeListeners() { | ||
function removePointerEventListeners() { | ||
removeEventListener('pointerup', onPointerUp, listenerOpts); | ||
@@ -133,16 +130,15 @@ removeEventListener('pointercancel', onPointerCancel, listenerOpts); | ||
if (evt.cancelable) { | ||
var eventTimeStamp = evt.timeStamp; | ||
// In some browsers `event.timeStamp` returns a `DOMTimeStamp` value | ||
// (epoch time) istead of the newer `DOMHighResTimeStamp` | ||
// (document-origin time). To check for that we assume any timestamp | ||
// greater than 1 trillion is a `DOMTimeStamp`, and compare it using | ||
// the `Date` object rather than `performance.now()`. | ||
// - https://github.com/GoogleChromeLabs/first-input-delay/issues/4 | ||
var isEpochTime = evt.timeStamp > 1e12; | ||
var now = isEpochTime ? new Date : performance.now(); | ||
// In some browsers event.timeStamp returns a DOMTimeStamp instead of | ||
// a DOMHighResTimeStamp, which means we need to compare it to | ||
// Date.now() instead of performance.now(). To check for that we assume | ||
// any timestamp greater than 1 trillion is a DOMTimeStamp. | ||
var now = eventTimeStamp > 1e12 ? +new Date : performance.now(); | ||
// Input delay is the delta between when the system received the event | ||
// (e.g. evt.timeStamp) and when it could run the callback (e.g. `now`). | ||
var delay = now - evt.timeStamp; | ||
// Some browsers report event timestamp values greater than what they | ||
// report for performance.now(). To avoid computing a negative | ||
// first input delay, we clamp it at >=0. | ||
// https://github.com/GoogleChromeLabs/first-input-delay/issues/4 | ||
var delay = Math.max(now - eventTimeStamp, 0); | ||
if (evt.type == 'pointerdown') { | ||
@@ -153,17 +149,31 @@ onPointerDown(delay, evt); | ||
recordDelay(delay, evt); | ||
recordFirstInputDelay(delay, evt); | ||
} | ||
} | ||
/** | ||
* Invokes the passed callback function for each event type with the | ||
* `onInput` function and `listenerOpts`. | ||
* @param {!Function} callback | ||
*/ | ||
function eachEventType(callback) { | ||
var eventTypes = [ | ||
'click', | ||
'mousedown', | ||
'keydown', | ||
'touchstart', | ||
'pointerdown', | ||
]; | ||
eventTypes.forEach(function(eventType) { | ||
callback(eventType, onInput, listenerOpts); | ||
}); | ||
} | ||
// TODO(tdresser): only register touchstart/pointerdown if other | ||
// listeners are present. | ||
eventTypes.forEach(function(eventType) { | ||
addEventListener(eventType, onInput, listenerOpts); | ||
}); | ||
eachEventType(addEventListener); | ||
// Don't override the perfMetrics namespace if it already exists. | ||
window['perfMetrics'] = window['perfMetrics'] || {}; | ||
// Expose `perfMetrics.onFirstInputDelay` as a promise that can be awaited. | ||
window['perfMetrics']['onFirstInputDelay'] = onFirstInputDelay; | ||
self['perfMetrics'] = self['perfMetrics'] || {}; | ||
self['perfMetrics']['onFirstInputDelay'] = onFirstInputDelay; | ||
})(); |
Sorry, the diff of this file is not supported yet
23006
166