Selaa lähdekoodia

Merge pull request #10063 from overleaf/td-extra-editing-session-metrics

Add extra editing session metrics

GitOrigin-RevId: d382719364e9fe029cd664e77608faa50204e0e0
Tim Down 3 vuotta sitten
vanhempi
sitoutus
3dbcc03db2

+ 20 - 9
services/web/frontend/js/ide.js

@@ -269,15 +269,26 @@ If the project has been renamed please look in your project list for a new proje
 
           // Ignore if no typing has happened
           if (cm6PerfData.numberOfEntries > 0) {
-            segmentation.cm6PerfMax = cm6PerfData.max
-            segmentation.cm6PerfMean = cm6PerfData.mean
-            segmentation.cm6PerfMedian = cm6PerfData.median
-            segmentation.cm6PerfNinetyFifthPercentile =
-              cm6PerfData.ninetyFifthPercentile
-            segmentation.cm6PerfDocLength = cm6PerfData.docLength
-            segmentation.cm6PerfNumberOfEntries = cm6PerfData.numberOfEntries
-            segmentation.cm6PerfMaxUserEventsBetweenDomUpdates =
-              cm6PerfData.maxUserEventsBetweenDomUpdates
+            const perfProps = [
+              'Max',
+              'Mean',
+              'Median',
+              'NinetyFifthPercentile',
+              'DocLength',
+              'NumberOfEntries',
+              'MaxUserEventsBetweenDomUpdates',
+              'Grammarly',
+              'SessionLength',
+              'Memory',
+            ]
+
+            for (const prop of perfProps) {
+              const perfValue =
+                cm6PerfData[prop.charAt(0).toLowerCase() + prop.slice(1)]
+              if (perfValue !== null) {
+                segmentation['cm6Perf' + prop] = perfValue
+              }
+            }
           }
         }
 

+ 31 - 4
services/web/frontend/js/infrastructure/cm6-performance.ts

@@ -1,11 +1,14 @@
 import { Transaction } from '@codemirror/state'
 import { EditorView } from '@codemirror/view'
+import { round } from 'lodash'
+import grammarlyExtensionPresent from '../shared/utils/grammarly'
 
 const TIMER_START_NAME = 'CM6-BeforeUpdate'
 const TIMER_END_NAME = 'CM6-AfterUpdate'
 const TIMER_MEASURE_NAME = 'CM6-Update'
 
 let latestDocLength = 0
+const sessionStart = Date.now()
 
 let performanceMeasureOptionsSupport = false
 
@@ -17,6 +20,20 @@ try {
   performanceMeasureOptionsSupport = true
 } catch (e) {}
 
+let performanceMemorySupport = false
+
+function measureMemoryUsage() {
+  // @ts-ignore
+  return performance.memory.usedJSHeapSize
+}
+
+try {
+  if ('memory' in window.performance) {
+    measureMemoryUsage()
+    performanceMemorySupport = true
+  }
+} catch (e) {}
+
 function isInputOrDelete(userEventType: string | undefined) {
   return (
     !!userEventType && ['input', 'delete'].includes(userEventType.split('.')[0])
@@ -111,16 +128,23 @@ export function reportCM6Perf() {
     .map(({ duration }) => duration)
     .sort((a, b) => a - b)
 
-  const max = calculateMax(inputDurations)
-  const mean = calculateMean(inputDurations)
-  const median = calculateMedian(inputDurations)
-  const ninetyFifthPercentile = calculate95thPercentile(inputDurations)
+  const max = round(calculateMax(inputDurations), 2)
+  const mean = round(calculateMean(inputDurations), 2)
+  const median = round(calculateMedian(inputDurations), 2)
+  const ninetyFifthPercentile = round(
+    calculate95thPercentile(inputDurations),
+    2
+  )
   const maxUserEventsBetweenDomUpdates = calculateMax(
     inputEvents.map(e => e.detail.userEventsSinceDomUpdateCount)
   )
+  const grammarly = grammarlyExtensionPresent()
+  const sessionLength = Math.floor((Date.now() - sessionStart) / 1000) // In seconds
 
   performance.clearMeasures(TIMER_MEASURE_NAME)
 
+  const memory = performanceMemorySupport ? measureMemoryUsage() : null
+
   return {
     max,
     mean,
@@ -129,6 +153,9 @@ export function reportCM6Perf() {
     maxUserEventsBetweenDomUpdates,
     docLength: latestDocLength,
     numberOfEntries: inputDurations.length,
+    grammarly,
+    sessionLength,
+    memory,
   }
 }
 

+ 3 - 0
services/web/frontend/js/shared/utils/grammarly.js

@@ -0,0 +1,3 @@
+export default function grammarlyExtensionPresent() {
+  return !!document.querySelector('grammarly-desktop-integration')
+}