This repository has been archived by the owner. It is now read-only.
Permalink
Newer
100644
2 lines (2 sloc)
9.32 KB
1
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.ttiPolyfill=e.ttiPolyfill||{})}(this,function(e){"use strict";function t(e,t){var i=XMLHttpRequest.prototype.send,n=h.next();XMLHttpRequest.prototype.send=function(){var r=this;return e(n),this.addEventListener("readystatechange",function(e){4===r.readyState&&t(n)}),i.apply(this,arguments)}}function i(e,t){var i=fetch;fetch=function(){var n=this,r=arguments;return new Promise(function(s,a){var o=h.next();e(o),i.apply(n,r).then(function(e){t(o),s(e)},function(e){t(e),a(e)})})}}function n(e,t){var i=!0,r=!1,s=void 0;try{for(var a,o=t[Symbol.iterator]();!(i=(a=o.next()).done);i=!0){var u=a.value;if(e.includes(u.nodeName.toLowerCase()))return!0;if(u.children&&n(e,u.children))return!0}}catch(e){r=!0,s=e}finally{try{!i&&o.return&&o.return()}finally{if(r)throw s}}return!1}function r(e){var t=new MutationObserver(function(t){var i=!0,r=!1,s=void 0;try{for(var a,o=t[Symbol.iterator]();!(i=(a=o.next()).done);i=!0){var u=a.value;switch(u.type){case"childList":n(d,u.addedNodes)&&e(u);break;case"attributes":d.includes(u.target.tagName.toLowerCase())&&e(u)}}}catch(e){r=!0,s=e}finally{try{!i&&o.return&&o.return()}finally{if(r)throw s}}}),i={attributes:!0,childList:!0,subtree:!0,attributeFilter:["href","src"]};return t.observe(document,i),t}function s(e,t,i,n,r){if(n-i<5e3)return null;var s=0===r.length?e:r[r.length-1].end;return n-s<5e3?null:Math.max(s,t)}function a(e,t,i){if(e.length>2)return i;var n=[],r=!0,s=!1,a=void 0;try{for(var o,u=t[Symbol.iterator]();!(r=(o=u.next()).done);r=!0){var l=o.value;n.push({timestamp:l.start,type:"requestStart"}),n.push({timestamp:l.end,type:"requestEnd"})}}catch(e){s=!0,a=e}finally{try{!r&&u.return&&u.return()}finally{if(s)throw a}}var c=!0,h=!1,d=void 0;try{for(var m,f=e[Symbol.iterator]();!(c=(m=f.next()).done);c=!0){var g=m.value;n.push({timestamp:g,type:"requestStart"})}}catch(e){h=!0,d=e}finally{try{!c&&f.return&&f.return()}finally{if(h)throw d}}n.sort(function(e,t){return e.timestamp-t.timestamp});for(var v=e.length,_=n.length-1;_>=0;_--){var b=n[_];switch(b.type){case"requestStart":v--;break;case"requestEnd":if(++v>2)return b.timestamp;break;default:throw Error("Internal Error: This should never happen")}}return 0}var o=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},u=function(){function e(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,i,n){return i&&e(t.prototype,i),n&&e(t,n),t}}(),l=function(e){if(Array.isArray(e)){for(var t=0,i=Array(e.length);t<e.length;t++)i[t]=e[t];return i}return Array.from(e)},c=function(){function e(){o(this,e),this._count=0}return u(e,[{key:"next",value:function(){return++this._count}}]),e}(),h=new c,d=["img","script","iframe","link","audio","video","source"],m=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};o(this,e),this._debugMode=void 0!==t.debugMode&&t.debugMode,this._useMutationObserver=void 0===t.useMutationObserver||t.useMutationObserver;var i=window.__tti&&window.__tti.e,n=window.__tti&&window.__tti.o;i?(this._debugLog("Consuming the long task entries already recorded."),this._longTasks=i.map(function(e){return{start:e.startTime,end:e.startTime+e.duration}})):this._longTasks=[],n&&n.disconnect(),this._networkRequests=[],this._incompleteJSInitiatedRequestStartTimes=new Map,this._timerId=null,this._timerActivationTime=-1/0,this._scheduleTimerTasks=!1,this._minValue=t.minValue||null,this._registerListeners()}return u(e,[{key:"getFirstConsistentlyInteractive",value:function(){var e=this;return new Promise(function(t,i){e._firstConsistentlyInteractiveResolver=t,"complete"==document.readyState?e.startSchedulingTimerTasks():window.addEventListener("load",function(){e.startSchedulingTimerTasks()})})}},{key:"startSchedulingTimerTasks",value:function(){this._debugLog("Enabling FirstConsistentlyInteractiveDetector"),this._scheduleTimerTasks=!0;var e=this._longTasks.length>0?this._longTasks[this._longTasks.length-1].end:0,t=a(this._incompleteRequestStarts,this._networkRequests);this.rescheduleTimer(Math.max(t+5e3,e))}},{key:"setMinValue",value:function(e){this._minValue=e}},{key:"rescheduleTimer",value:function(e){var t=this;return this._scheduleTimerTasks?(this._debugLog("Attempting to reschedule FirstConsistentlyInteractive check to ",e),this._debugLog("Previous timer activation time: ",this._timerActivationTime),this._timerActivationTime>e?void this._debugLog("Current activation time is greater than attempted reschedule time. No need to postpone."):(clearTimeout(this._timerId),this._timerId=setTimeout(function(){return t._checkTTI()},e-performance.now()),this._timerActivationTime=e,void this._debugLog("Rescheduled firstConsistentlyInteractive check at ",e))):void this._debugLog("startSchedulingTimerTasks must be called before calling rescheduleTimer")}},{key:"disable",value:function(){this._debugLog("Disabling FirstConsistentlyInteractiveDetector"),clearTimeout(this._timerId),this._scheduleTimerTasks=!1,this._unregisterListeners()}},{key:"_debugLog",value:function(){if(this._debugMode){var e;(e=console).log.apply(e,arguments)}}},{key:"_registerPerformanceObserver",value:function(){var e=this;this._performanceObserver=new PerformanceObserver(function(t){var i=t.getEntries(),n=!0,r=!1,s=void 0;try{for(var a,o=i[Symbol.iterator]();!(n=(a=o.next()).done);n=!0){var u=a.value;"resource"===u.entryType&&e._networkRequestFinishedCallback(u),"longtask"===u.entryType&&e._longTaskFinishedCallback(u)}}catch(e){r=!0,s=e}finally{try{!n&&o.return&&o.return()}finally{if(r)throw s}}}),this._performanceObserver.observe({entryTypes:["longtask","resource"]})}},{key:"_registerMutationObserver",value:function(){this._mutationObserver=r(this._mutationObserverCallback.bind(this))}},{key:"_registerListeners",value:function(){t(this._beforeJSInitiatedRequestCallback.bind(this),this._afterJSInitiatedRequestCallback.bind(this)),i(this._beforeJSInitiatedRequestCallback.bind(this),this._afterJSInitiatedRequestCallback.bind(this)),this._registerPerformanceObserver(),this._useMutationObserver&&this._registerMutationObserver()}},{key:"_unregisterListeners",value:function(){this._performanceObserver&&this._performanceObserver.disconnect(),this._mutationObserver&&this._mutationObserver.disconnect()}},{key:"_beforeJSInitiatedRequestCallback",value:function(e){this._debugLog("Starting JS initiated request. Request ID: ",e),this._incompleteJSInitiatedRequestStartTimes.set(e,performance.now()),this._debugLog("Active XHRs: ",this._incompleteJSInitiatedRequestStartTimes.size)}},{key:"_afterJSInitiatedRequestCallback",value:function(e){this._debugLog("Completed JS initiated request with request ID: ",e),this._incompleteJSInitiatedRequestStartTimes.delete(e),this._debugLog("Active XHRs: ",this._incompleteJSInitiatedRequestStartTimes.size)}},{key:"_networkRequestFinishedCallback",value:function(e){this._debugLog("Network request finished: ",e),this._networkRequests.push({start:e.fetchStart,end:e.responseEnd}),this.rescheduleTimer(a(this._incompleteRequestStarts,this._networkRequests)+5e3)}},{key:"_longTaskFinishedCallback",value:function(e){this._debugLog("Long task finished: ",e);var t=e.startTime+e.duration;this._longTasks.push({start:e.startTime,end:t}),this.rescheduleTimer(t+5e3)}},{key:"_mutationObserverCallback",value:function(e){this._debugLog("Potentially network resource fetching mutation detected: ",e),this._debugLog("Pushing back FirstConsistentlyInteractive check by 5 seconds."),this.rescheduleTimer(performance.now()+5e3)}},{key:"_getMinValue",value:function(){return this._minValue?this._minValue:performance.timing.domContentLoadedEventEnd?performance.timing.domContentLoadedEventEnd-performance.timing.navigationStart:null}},{key:"_checkTTI",value:function(){this._debugLog("Checking if First Consistently Interactive was reached...");var e=performance.timing.navigationStart,t=a(this._incompleteRequestStarts,this._networkRequests),i=window.chrome&&window.chrome.loadTimes?1e3*window.chrome.loadTimes().firstPaintTime-e:0,n=i||performance.timing.domContentLoadedEventEnd-e,r=this._getMinValue(),o=performance.now();null===r&&(this._debugLog("No usable minimum value yet. Postponing check."),this.rescheduleTimer(Math.max(t+5e3,performance.now()+1e3))),this._debugLog("Parameter values: "),this._debugLog("NavigationStart: ",e),this._debugLog("lastKnownNetwork2Busy: ",t),this._debugLog("Search Start: ",n),this._debugLog("Min Value: ",r),this._debugLog("Last busy: ",t),this._debugLog("Current time: ",o),this._debugLog("Long tasks: ",this._longTasks),this._debugLog("Incomplete JS Request Start Times: ",this._incompleteRequestStarts),this._debugLog("Network requests: ",this._networkRequests);var u=s(n,r,t,o,this._longTasks);u&&(this._firstConsistentlyInteractiveResolver(u),this.disable()),this._debugLog("Could not detect First Consistently Interactive. Retrying in 1 second."),this.rescheduleTimer(performance.now()+1e3)}},{key:"_incompleteRequestStarts",get:function(){return[].concat(l(this._incompleteJSInitiatedRequestStartTimes.values()))}}]),e}(),f=function(e){if(window.PerformanceLongTaskTiming){return new m(e).getFirstConsistentlyInteractive()}return Promise.resolve(null)};e.getFirstConsistentlyInteractive=f,Object.defineProperty(e,"__esModule",{value:!0})});