Search code examples
javascriptreactjsfirebaseperformance-testingfirebase-performance

How to add the GoogleChromeLabs input-first-delay polyfill to a React app


I must be missing something simple, but can't seem to get the polyfill working for measuring the first input delay on my firebase project.

I have included the minified file as suggested here, and then in the body of my HTML I have run the code as suggested also.

So it looks like:

<head>
  <title>My website</title>

  <!--first-input-delay-->
  !function(n,e){var t,o,i,c=[],f={passive:!0,capture:!0},r=new Date,a="pointerup",u="pointercancel";function p(n,c){t||(t=c,o=n,i=new Date,w(e),s())}function s(){o>=0&&o<i-r&&(c.forEach(function(n){n(o,t)}),c=[])}function l(t){if(t.cancelable){var o=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,o){function i(){p(t,o),r()}function c(){r()}function r(){e(a,i,f),e(u,c,f)}n(a,i,f),n(u,c,f)}(o,t):p(o,t)}}function w(n){["click","mousedown","keydown","touchstart","pointerdown"].forEach(function(e){n(e,l,f)})}w(n),self.perfMetrics=self.perfMetrics||{},self.perfMetrics.onFirstInputDelay=function(n){c.push(n),s()}}(addEventListener,removeEventListener);
</head>

<body>

  <!-- my react app -->
  <div id="root"></div>

  <script>
    perfMetrics.onFirstInputDelay((delay, evt) => {
        console.log("First Input Delay", delay)
        console.log("Event details", evt)
      })
  </script>

</body>

When I include the console logs, the script runs as expected and console logs the data, but it never sends it to firebase. If I take out the console logs (perfMetrics.onFirstInputDelay()), the script fails with TypeError: n is not a function.

How should I be adding this to my app? Should I be sending the trace to Firebase somehow? I use performance tracing at the moment, but unsure how to send this specific event as it doesn't have a start and stop time.

Is the solution something like the below?

const performance = firebase.performance()
performance.trace(onFirstInputDelay)

Solution

  • So I was doing something silly. I only needed to include the polyfill and let the Firebase SDK handle the onFirstInputDelay event.

    So just having this works.

    <head>
      <title>My website</title>
    
      <!--first-input-delay-->
      !function(n,e){var t,o,i,c=[],f={passive:!0,capture:!0},r=new Date,a="pointerup",u="pointercancel";function p(n,c){t||(t=c,o=n,i=new Date,w(e),s())}function s(){o>=0&&o<i-r&&(c.forEach(function(n){n(o,t)}),c=[])}function l(t){if(t.cancelable){var o=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,o){function i(){p(t,o),r()}function c(){r()}function r(){e(a,i,f),e(u,c,f)}n(a,i,f),n(u,c,f)}(o,t):p(o,t)}}function w(n){["click","mousedown","keydown","touchstart","pointerdown"].forEach(function(e){n(e,l,f)})}w(n),self.perfMetrics=self.perfMetrics||{},self.perfMetrics.onFirstInputDelay=function(n){c.push(n),s()}}(addEventListener,removeEventListener);
    </head>
    
    <body>
      <!-- my react app -->
      <div id="root"></div>
    </body>