WICG / element-timing

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

Base intersectionRect on initial viewport #42

Open valiantvu opened 4 years ago

valiantvu commented 4 years ago

If an element is scrolled out of view before it has finished loading, its intersectionRect will be 0. It would be useful to have the intersectionRect be based on the initial viewport (when the element was added to the DOM) instead of the current viewport at render time. This would enable collecting timings for elements that were in the initial viewport based on its intersectionRect. The comparison can still be done after the element has rendered, but the element would be compared against a representation of the initial viewport.

npm1 commented 4 years ago

Hi, thanks for the issue! Basing it on the 'initial viewport' might have the problem of us not knowing the real image size at the time (not sure about this). But I can see how it could be useful to base it on the first rect. Which comparison are we talking about here?

Does your website add all images to the DOM at the beginning of page load? If it doesn't then I think this additional intersectionRect might not always provide the information you want. It seems possible for an image to be added to the DOM when the user has scrolled into its coordinates, and the 'first intersectionRect' would be nonempty but it was not part of the initial viewport.

While I give this some more thought, I'll note that an alternative is to use IntersectionObserver to track the elements that are most likely within the initial viewport (I think it can be used to determine if they are indeed in the initial viewport or not).

valiantvu commented 4 years ago

I was thinking the intersectionRect could still be calculated once the image has rendered, at which point we know its size and position. However, instead of comparing against the current viewport we could compare against a representation of the initial viewport. This is essentially what we do at Pinterest - we create a bounding box representing the viewport on initial page load. After this bounding box has been filled, we check to see which images were inside the bounding box so we can record their resource timings (these are part of the custom perf metric we monitor). We server side render the page so all images are added to the DOM at the beginning of page load, but we do check that the viewport is filled before collecting timings in case the user has a large screen that requires client side rendering to completely fill the viewport with images. We have additional metrics for timing elements during subsequent scrolls.

Speaking more generally, it seems like sites would often want to track performance for the initial page load, specifically timings for elements in the initial viewport. It seems like intersectionRect could help with this use case, but if there is a stronger use case for basing intersectionRect on the viewport at time of render I wonder if there might be a way to optionally pass in an element for comparison (e.g. bounding box representing the initial viewport)?

npm1 commented 4 years ago

I think generally it's hard to determine the 'initial viewport'. Chrome tries to paint quickly at the beginning of the page load, which means we might not even have fully constructed and parsed the DOM by the first paint. Also, imagine there's some JS code which is loaded asynchronously and adds a bunch of DOM nodes: do these count for the 'initial viewport' or not? Another problem is that user input could change the DOM elements being displayed, so we'd need to be careful about this when deciding when to compute the 'initial viewport'. In general, it seems hard for the browser to determine whether a DOM element belongs to the initial viewport or not after some user input occurs. Maybe one solution here would be to provide some signal about whether user input has occurred?

Overall I think this is a useful problem to try to tackle: which elements should be considered part of the 'initial viewport'? Optimizing the load times of those with respect to navigation start seems like an important metric. Other elements would need to be optimized with respect to user inputs causing them to become visible in the screen.