-
Notifications
You must be signed in to change notification settings - Fork 148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🐛 [RUM-8606] Track First Hidden before init #3391
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #3391 +/- ##
=======================================
Coverage 92.75% 92.75%
=======================================
Files 299 299
Lines 7852 7855 +3
Branches 1792 1793 +1
=======================================
+ Hits 7283 7286 +3
Misses 569 569 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Bundles Sizes Evolution
🚀 CPU Performance
🧠 Memory Performance
|
e275848
to
e21ce2c
Compare
e21ce2c
to
a43463c
Compare
|
||
if (typeof performance !== 'undefined' && 'getEntriesByType' in performance && supportsVisibilityStateEntries()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💬 suggestion:
You can use supportPerformanceTimingEvent
from
export function supportPerformanceTimingEvent(entryType: RumPerformanceEntryType) { |
if (typeof performance !== 'undefined' && 'getEntriesByType' in performance && supportsVisibilityStateEntries()) { | |
if (supportPerformanceTimingEvent('visibility-state')) { |
No need to test for performance being defined, as all browsers we support support it.
const visibilityEntries = performance.getEntriesByType('visibility-state') | ||
if (visibilityEntries && visibilityEntries.length > 0) { | ||
for (const entry of visibilityEntries) { | ||
if (entry.name === 'hidden') { | ||
earliestHidden = Math.min(earliestHidden, entry.startTime) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💬 suggestion: entries are ordered in the buffer so you could just get the first one
performance.getEntriesByType('visibility-state').find(entry => entry.name === 'hidden')?.startTime
if (document.visibilityState === 'hidden') { | ||
timeStamp = 0 as RelativeTime | ||
} else if (earliestHidden < Infinity) { | ||
timeStamp = earliestHidden as RelativeTime | ||
} else { | ||
timeStamp = Infinity as RelativeTime |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💬 suggestion: maybe change the function design like the following to make it clearer:
function trackFirstHidden(configuration: RumConfiguration, eventTarget: Window = window): { timeStamp: TimeStamp, stop: () => void } {
if (document.visibilityState === 'hidden') {
return { timeStamp: 0, stop: noop }
}
if (supportPerformanceTimingEvent('visibility-state')) {
const firstHiddenEntry = performance.getEntriesByType('visibility-state').find(entry => entry.name === 'hidden')
if (firstHiddenEntry) {
return { timeStamp: firstHiddenEntry.startTime, stop: noop }
}
}
let timeStamp = Infinity
const { stop } = addEventListeners(...)
return { get timeStamp() { return timeStamp }, stop }
}
Motivation
When a page is in background, the browser can pause or slow down its execution to preserve resources. This is known to screw page-load related metrics (ex: vitals like FCP/FID and other like
@view.loading_time
): when the user opens a page in background (ex: middle click), those timings can be arbitrary long (as long as the tab stays in background). This is why we try to detect that a page was hidden/in background and discard those timings in this case.But we only do so once init is called: we don’t know whether a page was in background before init is called, or even before the SDK was loaded.
Changes
Chrome is providing Performance entries called visibility-state that are notified whenever a page gets hidden/visible: VisibilityStateEntry - Web APIs | MDN . It is possible to query past entries using performange.getEntriesByType('visibility-state'). When the browser support this, it could be used as initial state in trackFirstHidden .
Testing
I have gone over the contributing documentation.