Skip to content

feat: Add element timing support #124

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

Merged
merged 10 commits into from
Jun 1, 2020

Conversation

rupesh1
Copy link
Contributor

@rupesh1 rupesh1 commented May 31, 2020

I would like to add support for the Element Timing API, the use case is similar to the 'Component First Paint' feature currently available but its controlled through markup.

Some more details:

I made a few of changes (patching, docs, single build script (for simple running locally)) outside the direct scope of the feature feel free to edit/revert them.

@Zizzamia
Copy link
Owner

Wow, shocked!!! A lot of good stuff here, thank you so much for this contribution.
The pieces around improving the build, the types, and security we can merge it right away. If you want we can merge it in a separate PR.

The feature you are proposing is perfect for Perfume.js, let me just suggest a few documentation changes I would like to make.

README.md Outdated
@@ -131,6 +132,9 @@ const perfume = new Perfume({
case 'tbtFinal':
myAnalyticsTool.track('totalBlockingTimeFinal', { duration: data });
break;
case 'page-title':
Copy link
Owner

Choose a reason for hiding this comment

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

Because this is part of an Element Timing metric, let's try to make it more simple for any newcomer to understand what this metric is for. We could say elPageTitle then in the tracking elementTimingPageTitle. In the end, people will choose the name they prefer in their app, but here in the quickstart, we need to find names that are self-explanatory.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

README.md Outdated
@@ -277,6 +281,22 @@ perfume.endPaint('togglePopover');

![Performance](https://github.com/Zizzamia/perfume.js/blob/master/docs/src/assets/performance-cfp.png)

Or you can try the [emerging](https://chromestatus.com/features#elementtiming) [Element Timing API](https://wicg.github.io/element-timing/) specification by simply adding the `elementtiming` attribute to HTML elements you would like to measure:
Copy link
Owner

Choose a reason for hiding this comment

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

We should probably have his own section like

### Element Timing
brief description

how to use it

demo result

Copy link
Contributor Author

Choose a reason for hiding this comment

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

performanceEntries: IPerformanceEntry[],
) => {
performanceEntries.forEach(performanceEntry => {
if (performanceEntry.identifier) {
Copy link
Owner

Choose a reason for hiding this comment

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

To keep Perfume.js super tiny I have Terser at max modification, so to make sure this code working as minified as well, we need to add the word identifier into this list https://github.com/Zizzamia/perfume.js/blob/master/rollup.config.ts#L80.

Otherwise, we will get identifier minified to a different single letter. 😅

Copy link
Contributor Author

@rupesh1 rupesh1 May 31, 2020

Choose a reason for hiding this comment

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

It's weird I can see the .identifer in the minified output before the change

Screenshot_053120_114742_AM

Based on what you said and the terser doc's I'd expect that to be mangled, no worries I've added it anyway: https://github.com/Zizzamia/perfume.js/pull/124/commits/f10f58642ba63af04e7a34990c3bd4533f68f98b

Copy link
Owner

Choose a reason for hiding this comment

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

Good research! For the next release, it just safer have it. But in a future separate PR we should probably trim out all the ones that are not really necessary anymore. Thank you.

@@ -47,6 +47,7 @@ export type IPerformanceObserverType =
| 'measure'
| 'navigation'
| 'paint'
| 'element'
Copy link
Owner

Choose a reason for hiding this comment

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

Niiiice!

@@ -22,6 +22,7 @@ export const initPerformanceObserver = () => {
po('resource', initResourceTiming);
}
perfObservers[3] = po('layout-shift', initLayoutShift);
po('element', initElementTiming);
Copy link
Owner

@Zizzamia Zizzamia May 31, 2020

Choose a reason for hiding this comment

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

Have you tested this in Firefox, Safari, and Edge? I guess this code works only on Chrome right?
The reason I ask about other browsers, just in case they crash when used this API. I had bad experiences a few years back with new Performance Observer types.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point:

  • Firefox does warn
    firefox

  • legacy Edge doesn't seem to care
    legacy edge

  • Chrome and new Edge work as expected:
    Chrome

new edge

I'll test Safari tomorrow

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When testing Safari I was getting consistent TypeError even on the live site but it seems that was by design in the V1 spec: w3c/performance-timeline#87

iOS 13.3
iOS13

iOS 12.4
iOS12

Safari 13
safari 13

Safari 12
safari 12

Live Safari 12
live safari 12

Copy link
Owner

Choose a reason for hiding this comment

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

Interesting, I wonder if we should safeguard this for Safari.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The best I could find was https://github.com/GoogleChrome/web-vitals/blob/master/src/lib/observe.ts#L34 which seems quite reasonable

Copy link
Owner

Choose a reason for hiding this comment

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

Because this is an experimental API, we should probably introduce a configuration on/off options as we do for Resource Timing.

const perfume = new Perfume({
  elementTiming: true,
  analyticsTracker: ({ metricName, data }) => {
    myAnalyticsTool.track(metricName, data);
  })
});

Btw side note, we might want to remove the diff view in https://github.com/Zizzamia/perfume.js#element-timing, and just keep what the final version should look like.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in #127

@@ -148,6 +152,14 @@ export class AppComponent implements AfterViewInit {
this.isLowEndExperience = result;
this.ref.detectChanges();
});
heroLogoTiming.subscribe(result => {
Copy link
Owner

Choose a reason for hiding this comment

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

Dope, thank you for changing this code as well!

@Zizzamia Zizzamia added this to the v5.1.0 milestone May 31, 2020
@Zizzamia
Copy link
Owner

Zizzamia commented Jun 1, 2020

Amazing work! I'm going to approve this PR for now, and release the new version in the next two days.

Thank you @rupesh1 for the help, and looking forward to seeing more collaboration in the future.

@Zizzamia Zizzamia merged commit 5e0cd24 into Zizzamia:master Jun 1, 2020
@rupesh1 rupesh1 deleted the add-element-timing-support branch June 1, 2020 16:30
@latel
Copy link

latel commented Aug 16, 2021

not working on ios 14?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants