Fix perf mark race in commit list instrumentation
What does this MR do and why?
Fixes a race in the commit list performance instrumentation (added in !224782 (merged)) that throws in production:
SyntaxError: Failed to execute 'measure' on 'Performance': The mark 'commit-list-fetching-data' does not exist.
The start mark is deferred to requestAnimationFrame by performanceMarkAndMeasure, but the Apollo result() handler calls performance.measure() against it synchronously. When result() runs first, the measure throws. This happens in background tabs (browsers pause rAF, e.g. when the commits page is opened via middle-click) and on Apollo cache hits (result() fires in a microtask).
Changes in app/assets/javascripts/performance/utils.js:
performanceMarkAndMeasurenow skips any measure whose named start or end mark does not exist, instead of lettingperformance.measurethrow. Measures with an omitted start (measured from navigation start) still run.- New
sync: trueoption runs the mark and measures immediately instead of deferring to rAF.
The commit list component now calls the util with sync: true, so the fetch metric is preserved (and correctly timed) in the racy cases instead of lost. The guard also protects other callers of the util from the same class of error (e.g. the MR diffs measure in app/assets/javascripts/diffs/utils/performance.js).
Adds spec/frontend/performance/utils_spec.js and updates the commit list specs.
Closes https://gitlab.com/gitlab-org/gitlab/-/work_items/625058
References
| Sentry issue | Browser | Impact |
|---|---|---|
| GITLABCOM-CLIENTSIDE-2HDW2 | Chrome | 676 users / 800 events in 24h, ~900 events/day and rising over the last 7 days |
| GITLABCOM-CLIENTSIDE-2KH2T | Safari | ~16 users/day |
How to set up and validate locally
- Open a project commits page (
/-/commits/master) in a background tab (middle-click a link to it), wait a few seconds, then switch to it. - Before: the console shows the
SyntaxErrorabove. After: no error, and theCommit List: Data fetchmeasure appears inperformance.getEntriesByType('measure').
Screenshots or screen recordings
No visual changes.