| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- import { round } from 'lodash'
- import grammarlyExtensionPresent from '../../shared/utils/grammarly'
- import getMeta from '../../utils/meta'
- const TIMER_DOM_UPDATE_NAME = 'Ace-DomUpdate'
- const TIMER_MEASURE_NAME = 'Ace-Keypress-Measure'
- const sessionStart = Date.now()
- let performanceOptionsSupport = false
- // Check that performance.mark and performance.measure accept an options object
- try {
- const testMarkName = 'featureTestMark'
- performance.mark(testMarkName, {
- startTime: performance.now(),
- detail: { test: 1 },
- })
- performance.clearMarks(testMarkName)
- const testMeasureName = 'featureTestMeasure'
- performance.measure(testMeasureName, {
- start: performance.now(),
- detail: { test: 1 },
- })
- performance.clearMeasures(testMeasureName)
- performanceOptionsSupport = 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) {}
- let keypressesSinceDomUpdateCount = 0
- const unpaintedKeypressStartTimes: number[] = []
- let animationFrameRequest: number | null = null
- function timeInputToRender() {
- if (!performanceOptionsSupport) return
- ++keypressesSinceDomUpdateCount
- unpaintedKeypressStartTimes.push(performance.now())
- if (!animationFrameRequest) {
- animationFrameRequest = window.requestAnimationFrame(() => {
- animationFrameRequest = null
- performance.mark(TIMER_DOM_UPDATE_NAME, {
- detail: { keypressesSinceDomUpdateCount },
- })
- keypressesSinceDomUpdateCount = 0
- const keypressEnd = performance.now()
- for (const keypressStart of unpaintedKeypressStartTimes) {
- performance.measure(TIMER_MEASURE_NAME, {
- start: keypressStart,
- end: keypressEnd,
- })
- }
- unpaintedKeypressStartTimes.length = 0
- })
- }
- }
- export function initAcePerfListener(textareaEl: HTMLTextAreaElement) {
- textareaEl?.addEventListener('beforeinput', timeInputToRender)
- }
- export function tearDownAcePerfListener(textareaEl: HTMLTextAreaElement) {
- textareaEl?.removeEventListener('beforeinput', timeInputToRender)
- }
- function calculateMean(durations: number[]) {
- if (durations.length === 0) return 0
- const sum = durations.reduce((acc, entry) => acc + entry, 0)
- return sum / durations.length
- }
- export function reportAcePerf() {
- const durations = performance
- .getEntriesByName(TIMER_MEASURE_NAME, 'measure')
- .map(({ duration }) => duration)
- performance.clearMeasures(TIMER_MEASURE_NAME)
- const meanKeypressPaint = round(calculateMean(durations), 2)
- const grammarly = grammarlyExtensionPresent()
- const sessionLength = Math.floor((Date.now() - sessionStart) / 1000) // In seconds
- const memory = performanceMemorySupport ? measureMemoryUsage() : null
- // Get entries for keypress counts between DOM updates
- const domUpdateEntries = performance.getEntriesByName(
- TIMER_DOM_UPDATE_NAME,
- 'mark'
- ) as PerformanceMark[]
- performance.clearMarks(TIMER_DOM_UPDATE_NAME)
- let lags = 0
- let nonLags = 0
- let longestLag = 0
- let totalKeypressCount = 0
- for (const entry of domUpdateEntries) {
- const keypressCount = entry.detail.keypressesSinceDomUpdateCount
- if (keypressCount === 1) {
- ++nonLags
- } else if (keypressCount > 1) {
- ++lags
- }
- if (keypressCount > longestLag) {
- longestLag = keypressCount
- }
- totalKeypressCount += keypressCount
- }
- const meanLagsPerMeasure = round(lags / (lags + nonLags), 4)
- const meanKeypressesPerMeasure = round(
- totalKeypressCount / (lags + nonLags),
- 4
- )
- const release = getMeta('ol-ExposedSettings')?.sentryRelease || null
- return {
- numberOfEntries: durations.length,
- meanKeypressPaint,
- grammarly,
- sessionLength,
- memory,
- lags,
- nonLags,
- longestLag,
- meanLagsPerMeasure,
- meanKeypressesPerMeasure,
- release,
- }
- }
- window._reportAcePerf = () => {
- console.log(reportAcePerf())
- }
|