Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(devtools): Use Chrome DevTools Performance extension API #55805

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

and-oli
Copy link

@and-oli and-oli commented May 15, 2024

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.io application / infrastructure changes
  • Other... Please describe:

What is the new behaviour?

Hi Angular folks! 👋

This change is a proof of concept of how the new Chrome DevTools Performance extension API can be used to surface Angular runtime data directly in the Chrome DevTools Performance panel.

Specifically, it implements the following changes:

1. Use the profiling status notification API to toggle the Timing API:

The notification API is implemented under the chrome.devtools.performance extension namespace and consits of two events: ProfilingStarted and ProfilingStopped, dispatched when the Performance panel has started and stopped recording, respectively. This API is used to enable the Timings API in Angular when the recording has started in the Performance panel and disable it when recording has stopped. This enables change 2:

2. Use the User Timings detail field format specification of the Performance extension API to inject Angular runtime data into the Performance panel timeline.

The Angular profiler uses several hooks to measure framework tasks like change detection. With this change, these measurements are visible in the same context as the runtime data collected by the browser in the Performance Panel timeline.

You can see an example of how this data would look like in the following image:

image

Note: right now, to enable the user timings to be collected in the first place, one needs to open the Angular DevTools panel before recording with the Chrome Devtools Performance panel so that the related artifacts are loaded in the page. This shortcoming can be fixed in a follow up so that the extra step isn't necessary.

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Why?

We (the Chrome Page Quality team) think allowing developers to extend the Peformance Panel can significantly offer a better experience for developers looking to improve performance to the current solutions available (think of fragmented workflows due to context switching between tools).

We aim to collect feeback about the API and explore further potential use cases where the API (or an expansion of it) would offer value in the web ecosystem. Doing this in collaboration with the Angular team would be invaluable, so please let us know your thoughts!

This change is a proof of concept of how the new Chrome DevTools
Performance extension API (https://bit.ly/rpp-e11y) can be used to
surface Angular runtime data directly in the Chrome DevTools Performance
panel.

Specifically, it implements the following changes:

1. Use the profiling status notification API to toggle the Timing API:
The notification API is implemented under the
chrome.devtools.performance extension namespace and consits of two
events: ProfilingStarted and ProfilingStopped, dispatched when the
Performance panel has started and stopped recording, respectively. This
API is used to enable the Timings API when the recording has started in
the Performance panel and disable it when recording has stopped.

2. Use the User Timings `detail` field format specification of the
Performance extension API
(https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/User_timing)
to inject data collected by the Angular Profiler into the
Performance panel timeline. Angular Profiler uses several hooks to
measure framework tasks like change detection. With this change, this
measurements are visible in the same context as the runtime data
collected by the browser in the Performance Panel timeline.

Note: to enable the user timings to be collected in the first place, one
needs to open the Angular DevTools panel so that the related artifacts
are loaded in the page. This shortcoming can be fixed in a follow up so
that the extra step isn't necessary.
@pullapprove pullapprove bot requested a review from dgp1130 May 15, 2024 10:37
@angular-robot angular-robot bot added the detected: feature PR contains a feature commit label May 15, 2024
Copy link
Contributor

@dgp1130 dgp1130 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this together! This is super interesting and a very cool feature for Angular.

@AleksanderBodurri can you take a look at this? The PR seems fine to me, but the UX implications of this feature might be worth thinking more deeply about.

Also CC @AndrewKushnir who might be interested in this.

Some UX thoughts:

  • We already have a "Profiler" tab in Angular DevTools with our own UI to understand change detection. That gives much more information than we probably can in the Performance tab in Chrome, but I do think this is a useful feature just so we can put Angular side-by-side with everything else going on in the page. This way a user might notice a dropped frame in the Performance tab and be able to easily correlate it with a particular Angular change detection cycle.
  • It would be very cool if we could somehow link the change detection cycle displayed in this timings API to the "Profiler" tab in Angular DevTools as a way of linking the user to more details about that particular cycle. It doesn't seem like this is possible based on the doc you linked, but even then we don't capture these metrics unless the user clicks "Record" in the "Profiler" tab, so it would take some effort to do that automatically a link things up.
  • We could consider a performance.mark call for when the app is hydrated, I think that would be useful to see how hydration is contributing to your page's lifecycle.
  • For partial hydration, we could maybe mark for each @defer which gets hydrated, though that might be a little noisy for large apps.
  • What should the actual Angular track show and what could it point to? The obvious answer here is showing change detection cycles, but what would be good to show in details or provide as help text? Should we color long CD cycles yellow or red to flag?
  • We could also include hydration work in this timeline as well, but I don't think we're at the point yet where users really need to think about optimizing hydration.

Most of these are ideas we can follow up with in the future rather than hard blockers for this PR, I'm just trying to think through the full implications of this. I'll be OOO for a bit, but when I get back I'll install this build and try it out to see how the UX shakes out in practice and what we should be thinking about to improve it.

},
},
};
performance.measure(name, measureOptions);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Does this necessarily need to be done in Angular DevTools? Could we put these options in performance.measure calls directly in the Angular framework and support users who don't have it installed?

I'm not sure if that would be the worth the bundle size impact (we could gate this on ngDevMode so they're supported in development) but I want to make sure that's something we're considering at least.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great question! It can also happen at the framework level so that having the extension installed isn't necessary.
For the sake of demonstrating its usage, implementing the call in the Angular profiler is practical because that way calls are done in a single place. Also, we have access to the ProfilingStarted and ProfilingStopped extension events to enable/disable the calls (to save the potential overhead when not profiling).

If this is done at the framework level I can imagine the implementation could be more complex depending on the tasks that are profiled and how the gate is implemented (with ngDevMode or otherwise). However, it could be well worth it if developers don't need to install an extension to profile their Angular app and can use Chrome DevTools right off the bat

@ngbot ngbot bot added this to the Backlog milestone May 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: devtools detected: feature PR contains a feature commit
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants