PdfJsMetrics.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. let {
  57. latencyFetch,
  58. latencyRender,
  59. compileTimeClientE2E,
  60. stats,
  61. timings,
  62. } = metrics
  63. stats = stats || {}
  64. timings = timings || {}
  65. const leanMetrics = {
  66. version: VERSION,
  67. latencyFetch,
  68. latencyRender,
  69. pdfSize: stats['pdf-size'],
  70. compileTimeClientE2E,
  71. compileTimeServerE2E: timings.compileE2E,
  72. }
  73. sl_console.log('/event/compile-metrics', JSON.stringify(metrics))
  74. sendMB('compile-metrics-v3', leanMetrics, SAMPLING_RATE)
  75. }
  76. function submitPDFBandwidth(metrics) {
  77. const metricsFlat = {}
  78. Object.entries(metrics).forEach(([section, items]) => {
  79. if (!items) return
  80. Object.entries(items).forEach(([key, value]) => {
  81. metricsFlat[section + '_' + key] = value
  82. })
  83. })
  84. sl_console.log('/event/pdf-bandwidth', JSON.stringify(metrics))
  85. sendMB('pdf-bandwidth-v3', metricsFlat, SAMPLING_RATE)
  86. }