diff --git a/services/web/frontend/js/ide.js b/services/web/frontend/js/ide.js index 0c2e3d8c95..33a237ac30 100644 --- a/services/web/frontend/js/ide.js +++ b/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 + } + } } } diff --git a/services/web/frontend/js/infrastructure/cm6-performance.ts b/services/web/frontend/js/infrastructure/cm6-performance.ts index a69cbfe427..597c7e7b56 100644 --- a/services/web/frontend/js/infrastructure/cm6-performance.ts +++ b/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, } } diff --git a/services/web/frontend/js/shared/utils/grammarly.js b/services/web/frontend/js/shared/utils/grammarly.js new file mode 100644 index 0000000000..0aaf57eaed --- /dev/null +++ b/services/web/frontend/js/shared/utils/grammarly.js @@ -0,0 +1,3 @@ +export default function grammarlyExtensionPresent() { + return !!document.querySelector('grammarly-desktop-integration') +}