Participants
- Nic Jansma, Yoav Weiss, Adrian de la Rosa, Amiya Gupta, Carine Bournez, Franco Vieira de Souza, Guohui Deng, Luis Flores, Noam Helfman, Scott Haseley, José Dapena Paz, Robert Liu, Michal Mocny, Giacomo Zecchini, Bas Schouten, Ryosuke Niwa
Admin
- Next meeting: May 7th, 2026
Minutes
- Michal: LCP and a few other metrics (FP, FCP, Element Timing) use the startTime to represent a single time point - the time the paint happens.
- … duration is currently 0
- … Relative to the time origin of the page
- … We now have prerendering with activationTime and BFCache restoration
- … So the “visual time origin” is now not necessarily the time origin
- … Scripts are supposed to get those timings from the different sources (e.g. activation time) and compute their own values
- … Given that the duration is always 0, maybe we could just expose the duration in a way that we would have if we redid the API?
- … If no one is relying on the duration to be zero, we could expose it to be relative to the navigation “visual time origin”
- … It impacts SoftNavs as well, which define it differently. Also BG loaded navigation, pretenders, BFCache
- Nic: mPulse doesn’t look at duration for any of these. So you’re saying that duration would now be relative to the thing that matters?
- Michal: yes
- Nic: How would we know what the thing that matters is? E.g. Is it BFCache, prerender, etc?
- Michal: That’s the status quo today. You get a paint and it’s your responsibility to know what are the things that happened on the page. By default you have large values that don’t correlate with the user experience. This would give you durations
- Nic: startTime is a point in time, duration is a span that you need to figure out where it started
- Michal: startTime will not change. Would equal duration when it’s a “regular” navigation
- Amiya: did you consider adding a new field?
- Michal: It would be a good alternative and less risky. But patchy. So asking if we can leverage the existing attribute.
- Jose: duration scares me because in paint events it’s zero, but other entries have other semantics. Seems risky as tools may misrepresent it
- Michal: Agree it’s weird. Comes down to the fact that in LCP and other paint timing startTime doesn’t represent a meaningful thing
- Jose: Agree that startTime is confusing. A different set of names would allow better ergonomics in the future
- Bas: Violating the invariant of endTime-startTime=duration would be unfortunate. Let’s just V2 the whole thing. Over years we’d end up with something more intuitive and easier to use
- Michal: Hard to know when to pull the trigger on v2. Can do that through a new entry type or a parameter
- … Need to expose the activationStart somehow
- Simon: Is startTime specified?
- Michal: All of these values are specified but there may not be a single place to update. ActivationStart is probably the most pressing
- Simon: As an implementer I need it to be specified
- Bas: When we implemented it wasn’t intuitive for us. We did end up figuring it out
- Michal: For BFCache, we talked about BFCache restoration entry. There’s VisibilityState observer
- … But maybe we can consolidate that as they have similar motivations
- Bas: Could having something like this serve to have LCP relative to the UI event that triggered it, similar to soft navs?
- Michal: exposing the raw values more conveniently would TODO
- … I’ll update the issue with the discussion, but sounds like no one really loves the idea of changing duration, but tightening the spec would be welcome
- Simon: From our reading of the spec, we concluded that LCP should not fire for images in Shadow DOM
- … Ended up implementing it anyway, but then got pushback as shadow DOM shouldn’t be exposed
- Michal: No WPTs is a huge oversight. The Chromium impl does report paints inside Shadow DOM (open and closed). Events are also reporting on what’s happening inside shadow roots. But element references are returned as null, without a direct ref to the element itself.
- … The paint timing spec implies not to support shadow DOM, but LCP does imply it
- … Need to update the spec
- Bas: Did you happen to check what Firefox does?
- Simon: no
- Jose: From Element Timing seems like we should expose, but paint timing spec counters that. Would be interesting to expose a shadow DOM timeline that would enable the shadow DOM implementers to see their entries
- … Unclear what would be intuitive for developers
- … There is an algorithm in paint timing. Need to adapt it to deal with Shadow DOM
- Michal: Element Timing doesn’t get exposed for elements inside Shadow DOM atm. You’re asking about a specific element, so if you filter the element references, there’s nothing to report.
- … For LCP it’s still useful to know that something happened, even if you don’t get the element itself
- … RE visibility on shadow DOM, I don’t think they apply to all elements
- NoamH: Is that for closed only?
- Michal: No distinction at the moment. I think that open should be exposed. Ryosuke had different opinions
- … For closed shadow DOM there are still ways to understand if paint happens, so the encapsulation boundaries should not apply
- NoamH: What happens when the entire app is a web component?
- Michal: You’d get LCP data in Chromium with no attribution. In Safari you get nothing
- NoamH: This is a problem, as it’s somewhat of a pattern
- Michal: Does the distinction matter between open and closed?
- NoamH: Not really
- Michal: The advantage of using open shadow DOM are for style and layout benefits, but there’s no intention to hide the content inside that shadow DOM
- Ryosuke: Even in the open case you’re not supposed to see it unless intentional
- Bas: Could be a case where the element names conflict. The thing you added to your shadow DOM conflicts with TODO[a]
- … Firefox exposes LCP but no element ref
- Michal: That’s the speced behavior
- … We should clarify this wording in paint-timing
- … Once an image/text elements’ paint is passed to the LCP algorithm, it’s considered eligible for paint timing TODO[b]
- … However, The default getter for the LCP performance entry is not to expose element refs for elements inside shadow roots.
- Bas: Tend to agree with Ryosule that even open shadow DOM are not meant to expose things to the outside of the shadow DOM
- Michal: In your intuition, would you include only metadata to the fact that it painted?
- Bas: Maybe expose that the container painted? Would complicate the implementation
- Michal: That’s how Event Timing does it. Events bubble up and tell you “something in the shadow host clicked”
- Ryosuke: Makes sense to expose the host, and to Noam’s point that getBoundingClientRect exposes paints
- … If you start exposing things inside the shadow root, that’s weird
- Yoav: Update spec to actually align what Chromium and Firefox are currently doing which is to expose Shadow host by default. Doesn't expose, right now it's null, maybe change to expose host.
- … Don't want to expose things inside of Shadow Roots open/closed w/out their consent
- … Same time, entire apps are just custom elements all the way down
- … Developers have disadvantage for this way of building apps
- … Maybe we can figure out a way for Shadow / Custom Element to opt-in
- … Container Timing will solve this, depends if we're exposing from inside Shadow tree to global namespace. Some kind of opt-in for Custom Element to expose timings to global timeline.
- … Don't think we want per-Shadow-Root timeline
- … Effectively reporting that to global and allowing RUM providers to collect for Custom Elements that want this
- … Single point of collection for all of that information
- Michal: Was a proposal in the past for mutationObservers to include shadow DOM if you have an existing ref
- Yoav: RUM providers, same person built custom element may not be the same as observed it
- Michal: Something needs to bubble up, to RUM providers, principled right now – see the host and summaries of what the boundary is, "the host painted", "the host interacted with", but if you want deep insights into host only the component author would want access to that
- Yoav: Allow for opt-in?
- Michal: Component could with JS API surface to an observer
- … Value-add that comes down the line that we could discuss
- … Agree with all principles so far
- … Last question: For a component where you only see the host, for LCP, there could be many paints inside. Stream of paints.
- … FCP only one event, even in Safari, that fires in boundary
- … Is it OK to report any time a new larger content inside a host paints? That's what we need for LCP at page-level
- … No insights into what/where, but you get N paints inside host
- Bas: I think opt-in should be in host not component itself, as the host might make certain assumptions of what happens in timeline, component shouldn't be able to violate.
- … For Michal's point, type of element that would redraw multiple sizes that you could get multiple LCPs for
- Michal: Many requests to support that, depends on the node being persistent, if you remove and reattach, or rebuild DOM, folks have asked for this before
- ... One of the examples, is fonts loading, late-loading font-swap.
- … Don't re-fire, layout shift but not new LCP entry
- Yoav: Switching source on an image, similarly doesn't fire but should
- Michal: In Chromium it does, as src+node is a pair of keys, but it's an open-spec issue
- Scott: Great if we could apply the same principles we do now (per element) but not exposed, we wouldn't re-emit for every text paint if it's a redraw, but we would for new text
- … Unfortunate if we only reported once from Shadow host
- Ryosuke: Needs consistent with model of how Shadow DOM behaves
- … Media element events shouldn't be exposed to outside world
- … By default that behavior needs to exist
- … Component wants to opt-in to main timeframe, if we had a mechanism, we need all performance measurements including ResourceTiming/etc
- … Don't want a new flag for each type of PerformanceObserver
- Yoav: RT is currently exposed from Shadow DOM
- … Fetches are exposed in the global timeline
- … Haven't heard of this being a problem
- Ryosuke: Consistency
- Yoav: RT is exposed but doesn't have attribution that a specific element triggered a resource
- … Consistency would be on element attribution, would be fine to expose paints pointing to host, but not what's building the elements
- … Similar for resources, right now they don't have attribution to an element, would point to a host but not script in Shadow host.
- Michal: For Media elements, browser may implement its own UI in Shadow DOM
- … Is there some sort of internal + closed? We don't want to expose timings to this
- … Ideally we don't even record these
- … Open Shadow DOM, closed Shadow DOM, plus browser UI
- Jose: Was that the same web context in the end?
- Michal: For media controls, I would guess it's the same
- … Fruitful, sounds like it's acceptable to make sure not to report elements except for host, which we're not doing even right now for Chromium
- … Elements inside of Shadow DOM be considered
- … Reporting times that paints happen, even multiple, in Shadow Roots, as long as the elements aren't described themselves
- Ryosuke: I'm not sure. Media UI applies to other elements. Not sure everything is considered content by the user
- … Need to continue discussion on that point
- Yoav: For browser-owned closed components vs. developer-owned
- … Not because they're contentful or not, it's because developers don't have control those components compared to open/closed web components on their site that they can include or exclude
- … Browser components is a black box chosen by the user
- … Can extensions draw web components on top of the context? I'm not sure
- … Web extensions shouldn't be exposed (e.g. ResourceTiming, initiated by extensions are excluded)
- … Extensions w/ components, picked by user, site doesn't have any business knowing that
- Ryosuke: Depends, if you control component
- Yoav: Information about the host, not inside element
- Ryosuke: Whenever Shadow DOM is updated you don't necessarily want to know about it
- … Parts are relevant for user, parts that are not
- Yoav: For LCP, if part getting updated is largest paint in page (not just Shadow Root). Example I'm thinking of is banner or app is custom element, in those cases we want to know one thing or a larger thing was painted
- Ryosuke: Not sure you universally want that
- Yoav: Examples?
- Ryosuke: Page that is just a video, full white video
- … Play will render, is that LCP or not?
- Michal: A browser UI play button? Or custom component
- Ryosuke: Browser UI
- Michal: I don't think we need to describe browser painting
- … But for "custom clock" element it's real content
- … When I ask for video on screen, I'm not asking for play button. I want to know loading performance of component underneath.
- Yoav: And play buttons aren't necessarily going to be larger than other content being played.
- Michal: Will summarize discussion in issue
[a]+bschouten@mozilla.com