javascripts/pushr/dispatchers/rum.js

  1. /**
  2. * @namespace javascripts.pushr.dispatchers.rum
  3. * @description Handles the pushr events for Real User Metrics
  4. */
  5. let allowedRumMetrics = ["ttfb", "networkInfo", "fcp", "fid", "lcp", "cls"]
  6. let rumMetricsCollected = []
  7. let rumObjects = []
  8. /**
  9. * If it is a rum event then push the rum data onto a new array for rum data. If the metric type isn't
  10. * one that is allow then we exit. If we have already collected it then we exit.
  11. *
  12. * @function pushrDispatcher
  13. * @memberof javascripts.pushr.dispatchers.rum
  14. */
  15. export const pushrDispatcher = (pushrObject) => {
  16. if (pushrObject.event !== "rum") return
  17. if (!allowedRumMetrics.some(metric => metric === pushrObject.data.metric)) return
  18. if (rumMetricsCollected.some(metric => metric === pushrObject.data.metric)) return
  19. rumMetricsCollected.push(pushrObject.data.metric)
  20. rumObjects.push(pushrObject.data)
  21. }
  22. /**
  23. * Dispatch any logs in rumObjects when the page is backgrounded or unloaded
  24. *
  25. * @function leavePageDispatcher
  26. * @memberof javascripts.pushr.dispatchers.rum
  27. */
  28. export const leavePageDispatcher = () => {
  29. const path = "/.netlify/functions/rum_logger-background/"
  30. const body = JSON.stringify(rumObjects)
  31. if (rumObjects.length) batchPostRumData(path, body)
  32. rumObjects = []
  33. }
  34. /**
  35. * When the rum data is sent, empty the rumObjects array to ensure the data is not sent again. Use
  36. * `navigator.sendBeacon()` if available, falling back to `fetch()`.
  37. *
  38. * @function batchPostRumData
  39. * @memberof javascripts.pushr.dispatchers.rum
  40. */
  41. const batchPostRumData = (path, body) => {
  42. (navigator.sendBeacon && navigator.sendBeacon(path, body)) ||
  43. fetch(path, { body, method: "POST", keepalive: true })
  44. }