PdfJsMetrics.js 2.4 KB

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