WICG / element-timing

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

PerformanceObserver api return result not what i need #60

Closed nextdoorUncleLiu closed 2 years ago

nextdoorUncleLiu commented 3 years ago

I think this api is imperfect, Although i can get the rendering time of test or img, what i want to get is the total rendering time of the entire div(parent), rather than an element with content: https://bugs.chromium.org/p/chromium/issues/detail?id=1214719#c6

so i cannot know exactly how long the current element including all the content within the element has been rendered, whether it can be a tree data return, and each object(PerformanceElementTiming) is the current the detailed information of the element, contains a children field, u can view the rendering time of the cildren element:

{ // contains the original PerformanceElementTiming
  element: body,
  children: [
    {
      element: #app,
      children: [
        {
          element: #header,
          children: [
            // ...
          ],
          renderTime: timestamp,
          startTime: timestamp,
          loadTime: timestamp
          ...
        },
        {
          element: #content,
          children: [
            // ...
          ],
          renderTime: timestamp,
          startTime: timestamp,
          loadTime: timestamp
          ...
        }
      ],
      renderTime: timestamp,
      startTime: timestamp,
      loadTime: timestamp
      ...
    }
  ]
  renderTime: timestamp,
  startTime: timestamp,
  loadTime: timestamp
  ...
}
npm1 commented 3 years ago

Timing everything in the page would be expensive and not something we'd want to allow by having something like <body elementtiming=...>. It would be a perf footgun IMO. You could already annotate all the elements in the tree you're interested in, and take the max timestamp. Why does that not work for you?

nextdoorUncleLiu commented 3 years ago

You may not understand what i mean too much.some website content is rendered through module configuration. in this application scenario, they may have a common layer:

<div class="content-container">
   // here is the content of the module configuration
</div>

The api support is to a certain element that has a img or text. when our structure is like this, it cannot be obtained:

// Because the content below is dynamic, what i want to is the content of "content-container"
<div class="content-container" elementtiming="content-container">
  <div class="content-head">
    this is head
  </div>
</div>
// or
<div class="content-container" elementtiming="content-container">
  <div class="content-body">
    <img src="imgurl" />
  </div>
</div>
// or
<div class="content-container" elementtiming="content-container">
  <div class="content-head">
    this is head
  </div>
  <div class="content-body">
    <img src="imgurl" />
  </div>
</div>

Since elementtiming can only get the performanceTiming object in the elements that currently exist in text or img, elementtiming in this scenario cannot be satisfied

Because what i care about is not just the rendering time of content-head or content-body, because they are rendered at the same time, if i only get the rendering time of both, then i cannot accurately measure the overall rendering time of the page, so i am more concerned about it is the rendering time of content-container, so that it can accurately let me know how much this part of the current page affects the rendering time of the page

npm1 commented 3 years ago

It doesn't matter that the content is dynamic... As long as you annotate the divs added (whether it's content-head, content-body, or both) before appending them to the content-container and as long as the content is in the div when it is added to the body, the timings should be accurate. In the case of img I believe you'd need to annotate the img instead of the div. In any case, it's not clear to me why you can't obtain what you want with the existing API.

nextdoorUncleLiu commented 3 years ago
<html>
  <head></head>
  <body>
    <div class="content-container" elementtiming="content-container"><!--this is dynamic container render position-->
      <div class="dynamic-container"> <!--this is dynamic container-->
        <div class="content-head" elementtiming="content-head">
          this is head
        </div>
        <img class="content-img" src="https://gravatar.com/avatar/5cf3a51bef6a18cdc69ce381e6f5cce3?d=https%3A%2F%2Fassets.codepen.io%2Finternal%2Favatars%2Fusers%2Fdefault.png&fit=crop&format=auto&height=80&version=0&width=80" alt="">
      </div>
    </div>
    <script>
      var observer = new PerformanceObserver((list) => {
        console.log(list.getEntries())
      });
      observer.observe({ entryTypes: ["element"] });
    </script>
  </body>
</html>

Sorry, maybe my expression is not clear enough, the above case, it is impossible for me to get the content of content-head only. what i want to get is the rendering time of "dynamic-container", which does not contain rendering test inside, and some are nodes that render text, or the rendering time of "content-container", content-container the rendering time may be affected by the request,network,etc.,resulting in changes in the rendering time, so the "elementtimg" i currently understand can be added to the "content-head" or "content-img" to get the current time, but this time is for the rendering of the entire page and the user the experience is not very convenient, i hope it can be similar to chrome devtools-> performance -> main, so that i can kndow the rendering time of an entire module, and can also view the corresponding rendering time sub-modules, which may be more convenient for the module performance optimization, thanks

npm1 commented 3 years ago

Ok, so is this an ergonomics feature request? In your example you'd annotate both the text and the image (or whatever other content), and then you'd compute the maxTime as the time in which you consider the dynamic-container to be rendered:

<html>
  <head></head>
  <body>
    <div class="content-container"><!--this is dynamic container render position-->
      <div class="dynamic-container"> <!--this is dynamic container-->
        <div class="content-head" elementtiming="content-head">
          this is head
        </div>
        <img class="content-img" ... elementtiming="content-img">
      </div>
    </div>
    <script>
      let maxTime = 0;
      var observer = new PerformanceObserver((list) => {
         list.getEntries().forEach(entry => {
             maxTime = max(maxTime, entry.startTime);
         });
      });
      observer.observe({ entryTypes: ["element"] });
    </script>
  </body>
</html>

I do understand the comment that it would be nicer if you could just see the tree with all the rendering times of all nodes but because this needs to be implemented efficiently for real user devices I don't think we would implement the suggested feature and instead we encourage people to annotate only the key elements of the site.

npm1 commented 2 years ago

Closing for now but feel free to reply if we missed something here.