sitespeedio / sitespeed.io

sitespeed.io is an open-source tool for comprehensive web performance analysis, enabling you to test, monitor, and optimize your website’s speed using real browsers in various environments.
https://www.sitespeed.io/
MIT License
4.75k stars 603 forks source link

Measure multiple element timing and page visual complete for a page with shadow DOM #4136

Open ovenger-snow opened 7 months ago

ovenger-snow commented 7 months ago

Your question

I am looking for some suggestions on how properly this can be done.

Goal: Execute tests against the application with shadow DOM and measure multiple elements/components timing + visual complete. So we would be able to get all the timings both when multiple elements are available and full page visual complete.

As of now, I can see several solutions to each but I assume there are even more.

  1. Element timings(Element Timing API) I am mostly talking about --scriptInput.visualElements. The limitation of it is that it doesn't work for shadow DOM as you can get it by single document.body.querySelector. I understand that you may annotate elements but that will require additional work from dev teams.
  2. Using performance marks. In general, just mark before the page starts loading and add an additional mark once an element is visible/clickable/etc. Currently, I have an issue with that where the mark is not found. I assume it is because it requires the page to be in context, which is not available if you mark it before the navigation.
  3. Using stopWatch. For now, that's the only solution I was able to achieve some results but only for a single element. I am awaiting a specific element to appear, but I haven't yet figured out how to do it for multiple elements.

Including a sample of how I am doing it with stopWatch

await commands.measure.start('Test');
const stopWatchBefore = commands.stopWatch.get('ElementStopWatch');
commands.navigate('https://example.com/');
await commands.wait.byId('someElementId', 5000);
const time = stopWatch.stop();
await commands.wait.byPageToComplete();
await commands.measure.stop();
await commands.measure.add(stopWatch.getName(), time);
soulgalore commented 7 months ago

Hi @ovenger-snow can you provide an example page/URL, then I could try to add a fallback for the visual elements to get it from the shadow DOM?

ovenger-snow commented 7 months ago

First example found - https://www.htmlelements.com/demos/menu/shadow-dom/index.htm

P.S. After some research, found out that Element Timing API doesn't support shadow DOM. So seems like option 1 is not viable.

soulgalore commented 7 months ago

What do you want to measure on that page? :) If you can share your real URL and exact what you want to measure it will be easier.

For element timings: The Chrome API does not support I think as long as it's attached to the DOM and you can get the position, you can get it for the visual elements? It works like this: it finds the element, gets the position and then uses that position in the video recording and calculates when it was painted.

Marks and stop watch can measure things but will not now when things is painted on the screen.

ovenger-snow commented 7 months ago

I can't share the current app I am working on. I was able to find another example - https://www.alodokter.com/aloshop So for example on this page, we can measure when categories are available, when some product is available and in the end the whole page loading time. image

I didn't dive deep into how element timing works. Happy to hear your thoughts on how you would do it. Currently, just evaluating different options. With stop watch was thinking about using some selenium commands inside the stopwatch.