PdfJsMetrics.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import { v4 as uuid } from 'uuid'
  2. import { sendMB } from '../../../infrastructure/event-tracking'
  3. // VERSION should get incremented when making changes to caching behavior or
  4. // adjusting metrics collection.
  5. // Keep in sync with the service worker.
  6. const VERSION = 2
  7. const pdfJsMetrics = {
  8. version: VERSION,
  9. id: uuid(),
  10. epoch: Date.now(),
  11. totalBandwidth: 0,
  12. }
  13. const SAMPLING_RATE = 0.01
  14. export function trackPdfDownload(response, compileTimeClientE2E) {
  15. const { serviceWorkerMetrics, stats, timings } = response
  16. const t0 = performance.now()
  17. let bandwidth = 0
  18. function firstRenderDone({ timePDFFetched, timePDFRendered }) {
  19. const latencyFetch = timePDFFetched - t0
  20. // The renderer does not yield in case the browser tab is hidden.
  21. // It will yield when the browser tab is visible again.
  22. // This will skew our performance metrics for rendering!
  23. // We are omitting the render time in case we detect this state.
  24. let latencyRender
  25. if (timePDFRendered) {
  26. latencyRender = timePDFRendered - timePDFFetched
  27. }
  28. done({ latencyFetch, latencyRender })
  29. }
  30. function updateConsumedBandwidth(bytes) {
  31. pdfJsMetrics.totalBandwidth += bytes - bandwidth
  32. bandwidth = bytes
  33. }
  34. let done
  35. const onFirstRenderDone = new Promise(resolve => {
  36. done = resolve
  37. })
  38. // Submit latency along with compile context.
  39. onFirstRenderDone.then(({ latencyFetch, latencyRender }) => {
  40. submitCompileMetrics({
  41. latencyFetch,
  42. latencyRender,
  43. compileTimeClientE2E,
  44. stats,
  45. timings,
  46. })
  47. })
  48. // Submit bandwidth counter separate from compile context.
  49. submitPDFBandwidth({ pdfJsMetrics, serviceWorkerMetrics })
  50. return {
  51. firstRenderDone,
  52. updateConsumedBandwidth,
  53. }
  54. }
  55. function submitCompileMetrics(metrics) {
  56. const { latencyFetch, latencyRender, compileTimeClientE2E } = metrics
  57. const leanMetrics = {
  58. version: VERSION,
  59. latencyFetch,
  60. latencyRender,
  61. compileTimeClientE2E,
  62. }
  63. sl_console.log('/event/compile-metrics', JSON.stringify(metrics))
  64. sendMB('compile-metrics-v5', leanMetrics, SAMPLING_RATE)
  65. }
  66. function submitPDFBandwidth(metrics) {
  67. const metricsFlat = {}
  68. Object.entries(metrics).forEach(([section, items]) => {
  69. if (!items) return
  70. Object.entries(items).forEach(([key, value]) => {
  71. metricsFlat[section + '_' + key] = value
  72. })
  73. })
  74. const leanMetrics = {}
  75. Object.entries(metricsFlat).forEach(([metric, value]) => {
  76. if (
  77. [
  78. 'serviceWorkerMetrics_id',
  79. 'serviceWorkerMetrics_cachedBytes',
  80. 'serviceWorkerMetrics_fetchedBytes',
  81. 'serviceWorkerMetrics_requestedBytes',
  82. 'serviceWorkerMetrics_version',
  83. 'serviceWorkerMetrics_epoch',
  84. ].includes(metric)
  85. ) {
  86. leanMetrics[metric] = value
  87. }
  88. })
  89. if (Object.entries(leanMetrics).length === 0) {
  90. return
  91. }
  92. sl_console.log('/event/pdf-bandwidth', JSON.stringify(metrics))
  93. sendMB('pdf-bandwidth-v5', leanMetrics, SAMPLING_RATE)
  94. }