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

report: add onViewTrace to renderer options #13528

Merged
merged 7 commits into from
Feb 11, 2022
Merged

Conversation

@@ -12,6 +12,9 @@ import {ReportUIFeatures} from '../renderer/report-ui-features.js';
import {CategoryRenderer} from './category-renderer.js';
import {DetailsRenderer} from './details-renderer.js';

/** @type {WeakMap<HTMLElement, ReportUIFeatures>} */
const rootElToReportUIFeatures = new WeakMap();
Copy link
Member

Choose a reason for hiding this comment

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

Could you add some tests for this?

Storing the renderer state in globals can lead to lingering instances between test cases. Probably won't be a problem here since you use a map, but should still keep that in mind.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

What sort of test? Every call to render will make a new element, and so a new key->value pair in this map.

ahhh this tile has zero tests eh? kinda makes since, they api surface and methods are pretty minimal, and each individual component is pretty well tested. Not quite certain what tests should be added that wouldn't just be duplicates of existing tests.

one test I thought of is just doing renderReport and then addButton then confirming the button is in the el. And doing a second report render and confirming the same.

Copy link
Member

Choose a reason for hiding this comment

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

I was thinking of tests that verify the association between a rootEl and an instance of ReportUIFeatures. The one you mentioned would work.

* @param {Parameters<ReportUIFeatures['addButton']>[0]} opts
*/
function addButton(rootEl, opts) {
const features = rootElToReportUIFeatures.get(rootEl);
Copy link
Member

Choose a reason for hiding this comment

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

We could get away with creating a new instance of ReportUIFeatures in this function since ReportUIFeatures.addButton only depends on the _dom member of ReportUIFeatures.

Copy link
Collaborator Author

@connorjclark connorjclark Jan 4, 2022

Choose a reason for hiding this comment

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

This does work, however you have to dig through multiple class constructors to confirm there aren't any side effects from creates a new ReportUIFeatures, which suggests that this could be a foot-gun if those constructors began doing something other than rebinding a bunch of methods ... makes me lean towards keeping the map around. Semantically it makes since that there should only ever be one instance. wdyt?

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

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

Worth discussing the API since this wasn't part of #12772? Something like

/** If defined, adds a View Trace button to the performance category. When clicked, will run this function. */
onViewTrace?: () => void;

fits well with the rest of the API and avoids any global state, keeping track of the rootEl, etc.

@adamraine
Copy link
Member

fits well with the rest of the API and avoids any global state, keeping track of the rootEl, etc.

I agree, this fits better with the rest of the API. Leaves UX implementation details up to the report renderer. SGTM.

@connorjclark
Copy link
Collaborator Author

hmmm, it would make sense to do onViewTrace?: (traceEvents: TraceEvent[]) => void; but the report doesn't have the trace events (it isn't in the LHR).... so we really would need to rely on the callback being a closure and already having access to the trace events/artifacts. Which makes the callback just a wrapper around use calling addButton({text: 'View Trace', onClick}).

@connorjclark
Copy link
Collaborator Author

what about adding this to Renderer.Options:

buttons?: Array<{text: string, icon?: string, onClick: () => void}>,

@brendankenny
Copy link
Member

so we really would need to rely on the callback being a closure and already having access to the trace events/artifacts. Which makes the callback just a wrapper around use calling addButton({text: 'View Trace', onClick}).

It already is a closure though, so that wouldn't be a change? But it would just need to close over the trace, not be a wrapper around addButton.

getStandaloneReportHTML has a similar requirement. Improving consistency with e.g. onPrintOverride/onSaveFileOverride could be good, but I'm not sure if there's an easy fix beyond a large expansion of reportRenderer responsibilities.

buttons?: Array<{text: string, icon?: string, onClick: () => void}>

If the pro/con is a single function that matches the rest of the API vs support for placing arbitrary buttons in the perf category, I'd definitely vote for putting off the buttons API until we need a second one.

@connorjclark
Copy link
Collaborator Author

Since both the text and the onClick would be provided from devtools (the text is translated, and the callback needs access to an artifact), the option ends up looking like this:

 if (this._opts._internalViewTraceButton) {
  this.addButton(this._opts._internalViewTraceButton);
}

This is what I meant by saying it would just be a wrapper around addButton... there's nothing related to the trace in its usage, except for its name. That's odd. Also, opts.onViewTrace doesn't work because we need more than just a callback, so it's gonna look like the parameters to the addButton method.

This might as well be _internalButton ... which might as well be _internalButtons.

Anyhow, I think marking this option as _internal knocks the importance of all this down a peg or two, so hopefully it's fine now.

Copy link
Member

@paulirish paulirish left a comment

Choose a reason for hiding this comment

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

wow. well that's a smaller diff!

sgtm!

@connorjclark connorjclark changed the title report: add addButton to api report: add _internalButtons to api Feb 10, 2022
@adamraine
Copy link
Member

In general I agree with @brendankenny that we don't need a generalized API for adding buttons, and we already have specialized options for adding specific buttons in the flow report.

getReportHtml?: (flowResult: FlowResult_) => string;
saveAsGist?: (flowResult: FlowResult_) => void;

There is also getStandaloneReportHTML on the normal report:

getStandaloneReportHTML?: () => string;

At least for consistency I would prefer an opts.onViewTrace callback.

Since both the text and the onClick would be provided from devtools (the text is translated, and the callback needs access to an artifact), the option ends up looking like this:

I think it's better to move this translated string and any UX details behind the report renderer anyway. That we we aren't copying the addButton api and only need to get the callback from the options.

Also, opts.onViewTrace doesn't work because we need more than just a callback, so it's gonna look like the parameters to the addButton method.

What more does it need? artifacts will be available in DevTools when onViewTrace is being defined:
https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/panels/lighthouse/LighthousePanel.ts;l=247?q=lighthousepanel&ss=chromium%2Fchromium%2Fsrc:third_party%2Fdevtools-frontend%2Fsrc%2F

@connorjclark connorjclark changed the title report: add _internalButtons to api report: add onViewTrace to api Feb 11, 2022
Copy link
Member

@adamraine adamraine left a comment

Choose a reason for hiding this comment

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

Very cool, thanks Connor!

@connorjclark connorjclark changed the title report: add onViewTrace to api report: add onViewTrace to renderer options Feb 11, 2022
@connorjclark connorjclark merged commit 25b8095 into master Feb 11, 2022
@connorjclark connorjclark deleted the report-api-addbutton branch February 11, 2022 18:47
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.

None yet

5 participants