WICG / element-timing

A proposal for an Element Timing specification.
https://wicg.github.io/element-timing/
Other
58 stars 15 forks source link

Element Timing: Explainer

The Element Timing API enables monitoring when developer-specified image elements or groups of text nodes are displayed on screen. The way text nodes are grouped is described below.

Objectives

  1. Inform developers when specific elements are first displayed on the screen. We support the following types of images: \<img>, \<image> inside \<svg>, and background-images. We also support observing certain groups of text nodes. Web developers can better understand which are the critical images and text of their sites, so after annotating them the browser can provide timing information about those. This image and text converage means that the majority of web content can be timed via this API.
  2. Enable analytics providers to measure display time of key images or text, without explicit opt in from web developers. In many cases it's not feasible for developers to modify their HTML just to get better performance insights, so it's important to provide basic information even for websites that cannot annotate their elements.

How do we register elements for observation?

An element can be registered for observation via the elementtiming HTML attribute. Having this attribute set will signal the browser to expose render timing information for this element (its source image, background image, and/or text). It should be noted that setting the elementtiming attribute does not work retroactively: once an element has loaded and is rendered, setting the attribute will have no effect. Thus, it is strongly encouraged to set the attribute before the element is added to the document (in HTML, or if set on Javascript, before adding it to the document). Having the attribute implies that:

Image considerations

We define the image rendering timestamp as the next paint that occurs after the image has become fully loaded. This is important to distinguish as progressively rendered images may have multiple initial renderings before the image has even been fully received by the user agent.

Allowing third-party origins to measure the time an arbitrary image resource takes to render could expose sensitive information such as whether a user is logged into a website. Therefore, for privacy and security reasons, the image rendering timestamp is only exposed in entries corresponding to resources that pass the timing allow check. However, to enable a more holistic picture, the rest of the information is exposed for arbitrary images.

Text considerations

We say that a text node belongs to the closest block-level Element ancestor of the node. This means that an element could have 0 or many associated text nodes with it.

We say that an element is text-painted if at least one text node belongs to and has been painted at least once. Thus, the text rendering timestamp of an element is the time when it becomes text-painted.

Let the text rect of a text node be the display rectangle of that node within the viewport. We define the text rect of an element as the smallest rectangle which contains the geometric union of the text rects of all text nodes which belong to the element.

What information is exposed?

A PerformanceElementTiming entry has the following attributes:

Note: for background images, the element is the one being affected by the background image style.

Sample code:

<img src="https://github.com/WICG/element-timing/raw/main/my_image.jpg" elementtiming="foobar">

const observer = new PerformanceObserver((list) => {
  let perfEntries = list.getEntries().forEach(function(entry) {
      // Send the information to analytics, or in this case just log it to console.
      if (entry.identifier === 'foobar') {
        if (entry.renderTime)
          console.log("My image took " + entry.renderTime + " to render!");
        else
          console.log("Rendering time not available. Image took " + entry.loadTime + " to load!");
      }
   });
});
observer.observe({entryTypes: ['element']});

Questions

What about Shadow DOM?

Unfortunately Shadow DOM elements are not currently supported.

What about invisible or occluded elements?

The entry creation might be affected by visibility: for instance, elements are not exposed if the style visibility is set to none, or the opacity is 0. However, occlusion will not affect entry creation: an entry is seen if the element is there, but hidden by a full-screen pop-up on the page.

What are some differences between text and image observation?