Closed dholbert closed 2 years ago
I wonder why they are not using IntersectionObserver instead? It is not an intended use-case. Another problem I see from using this API for that is that the PerformanceObserver delivery of entries could be delayed, and this use-case would require quick delivery of the entries.
Hi! I'm the author of that long post, so I can give some additional background. As a quick note, I've updated it to no longer "recommend" using LayoutShift, and rather to point out that it may seem like a relevant choice, but that this discussion is also open about the intended use.
IntersectionObserver
is an interesting thought! At first my mind assumed that it wouldn't be useful, because we aren't looking to track when an element enters or leaves the viewport, but rather just when it changes positions within the viewport, where it most likely won't be intersecting anything or changing its intersection value at any point. We already have a more convenient solution to address scrolling and occlusion issues as described in that post by scoping where the ring gets rendered.
But, now that I think about it more, I think you are recommending that we could do something where the ring itself uses an IntersectionObserver
between its own current bounding box and the target element to see if the element has moved at all? That, I must admit, is not a possibility I had considered, but I'm very interested in trying this approach now.
Coming back to LayoutShift, this use case would indeed require timely delivery of entries (ideally within the same frame window with additional time to be able to update before the frame renders), and would ideally be able to track shifts at any granularity, even down to 1px or lower. As I mention at the end of that post, what this ring system really wants is a "subscribe to animation frame" API, rather than requesting one. LayoutShift (from initially skimming the spec), seemed like a potential match to provide that kind of subscription, but with this new information it is clearly not a great fit. I think clarifying the intended limitations would be useful to prevent that kind of misunderstanding as this API becomes more widely available.
One more reason to explicitly recommend against (and perhaps design against) the "layout changed, let's run some JS to update all our CSS and reposition these elements" use-case: we don't want to end up in a future where some fraction of websites depend on browsers supporting this feature in order to render properly.
Layout-shift is meant as a developer-facing feature for monitoring performance/user-experience; so I think we should make it clear that it's only meant to be used in a way where its implementation status is effectively undetectable to users. (This will ensure that we can safely deprecate & drop support for this API in the future, without breaking sites, once we've got a hypothetical better metric available and/or when this metric hypothetically becomes impractical for next-gen web engines to implement.)
It may be tempting for web developers to use the Layout Instability API as a way of tracking when elements move (for any reason), as a way to receive callbacks when they need to recompute the positions of other related elements (e.g. overlays, focus rings).
There's a blog post here that recommends doing exactly that -- it describes a number of other things too, so you can do find-in-page for "layout shift" to jump to the relevant details: https://www.notion.so/Focus-Rings-4459faa9d1f643728ca8dde145a89900
(see also: a tweet about this in https://twitter.com/aweary/status/1313266406641864706?s=20 )
So this blog post is describing a way to use the Layout Shift API as a callback that fires when layout changes (specifically when it changes in a way that moves elements around); and it uses this as a hook for the web-developer's JS to run and make some resulting positioning adjustments to overlays and such.
Is this an intended-to-be-useful use case for this API? The problem that comes to mind first is the magic "3px" threshold that's currently hardcoded in spec (which means: an element that slowly moves < 3px per animation frame won't trigger a layout shift report, even if it continues moving a long distance at that rate; see first example in https://github.com/WICG/layout-instability/issues/53#issuecomment-691298116 . So this blog post's approach wouldn't ever receive a callback if they happened to only have slowly/subtly moving content.)
If in fact this "layout observer" sort of thing is not a use-case that this API intends to robustly support, then it might make sense to make that clear in the spec...