Watching for 'scroll' event may end LCP before a valid browser entry is created
See original GitHub issueTLDR; I believe web-vitals
marks isFinal
on all types of scroll events when only some scroll events stop largest-contentful-paint
browser entries.
Background
Thanks for open sourcing this!
When we started trying to use getLCP
in our code at page start, the reporter would never fire. We noticed that our component library’s positioning changes caused a scroll event before any meaningful render, that the web-vitals’ input handler would catch. The page hadn’t rendered anything, so there weren’t any LCP entries for web-vitals to report to our callback. All well and fine, we were causing a scroll event, and the docs describe marking isFinal
on scroll.
However, in our case, the Web Chrome Vitals Extension later displayed an LCP value. The extension would call getLCP
on tab-complete, well after the scroll that stopped our web-vitals instance and read LCP entries just fine.
Let me know if you want a repro. The code is still internal, so it may take some time to get a fiddle up.
I get the impression this library watches for scroll because it reads entries created by the browser, and the browser stops recording on scroll. Through my use case, though, I think I’ve found that this library stops on any scroll event when the browser only stops creating the largest-contentful-paint
entries on some scroll events.
LCP logic in Chromium
Searching for LCP and scroll logic in Chromium, I think I might have found the corresponding files.
Many types of scrolls I think all create `Event.type = ‘scroll’: https://github.com/chromium/chromium/blob/a4f27fdc4913d800752bd1cb9533d31357163d65/third_party/blink/renderer/core/scroll/scroll_types.h#L58
But LCP only stops recording on two types of scroll events: https://github.com/chromium/chromium/blob/55f44515cd0b9e7739b434d1c62f4b7e321cd530/third_party/blink/renderer/core/paint/paint_timing_detector.cc#L188
Remediation?
I admittedly don’t understand what kCompositorScroll
is, but the library could listen to key up, key down, and wheel device events instead of scroll
as a proxy for ‘kUserScroll’.
If this is a valid bug and has a straightforward fix, let me know, I’m happy to open contribute.
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (2 by maintainers)
Awesome, thanks for your work @philipwalton!
There is currently no reliable way to detect user-initiated scrolls. This is because the scroll event itself is an observation of the scroll position having change rather than a direct event causing it.
You could however try to observe all possible user initiated scroll sources (mousewheel, pointerdown / pointermove, down arrow / page down / space bar?) in combination with a scrollable page.
Could you explain more the rationale around no longer observing LCP after the user scrolls? This doesn’t seem like it would be guaranteed IMO.