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

core: convert computed artifact loading to regular require() #6204

Merged
merged 7 commits into from
Oct 12, 2018

Conversation

brendankenny
Copy link
Member

@brendankenny brendankenny commented Oct 10, 2018

follow up to #5907 and #6151 (and enabled by test changes in #6171, #6195, and #6196).

This PR completes the transition of computed artifacts magically appearing on artifacts (like artifacts.requestNetworkRecords()) and instead being pulled in with plain old require() statements. Our codebase becomes a whole lot easier to follow and reason about after this.

I'll follow up with a pretty minor (non-functional) cleanup PR (and @paulirish wanted to discuss renaming them or at least moving them out of gather/ at that point).

Apologies for the giant PR. Most of this is mechanical; the major architecture/conceptual changes occurred in those earlier PRs. Due to the dependencies between the computed artifacts and the fact that they have to pass a context to each other, once one of these files was updated it turns out they all had to be :) I'm not sure we could have unwound this stack if we had waited much longer to do this refactor.

I've split up the PR into commits grouped by types of change to make the reviewing a little easier on the brain.

  • 7522a60 - update the computed artifact files. Primarily makes all methods static async and have their calls to each other be explicit instead of through computedArtifacts.request*()
  • 82fc891 - update the computedArtifact tests. Mostly adding context to calls for the cache.
  • 0c9e393 - updates to runner, gather-runner, and some build stuff. Mostly deleting computedArtifacts initialization and custom-bundling code :)
  • 472bef3 - audit updates. Such minimal changes!
  • ed3c3c7 - updates to audit tests. Mostly adding context to calls.

Or just look at the whole thing :)

* Decorate computableArtifact with a caching `request()` method which will
* automatically call `computableArtifact.compute_()` under the hood.
* @template {{name: string, compute_(artifacts: unknown, context: LH.Audit.Context): Promise<unknown>}} C
* @param {C} computableArtifact
Copy link
Member Author

@brendankenny brendankenny Oct 10, 2018

Choose a reason for hiding this comment

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

it was a nice dream to encapsulate computed artifacts like they were before this PR, leaving only a

{name: string, request: (artifacts: Whatever, context: LH.Audit.Context): Promise<Yeah>}

but we access static methods on the computed artifact classes in a few different places and LanternFirstCPUIdle even extends LanternInteractive, so we really need this function to return a

InputComputedArtifact & {request: (artifacts: Whatever, context: LH.Audit.Context): Promise<Yeah>}

which this change does. There's some limitations with current tsc (3.1) and trying to do this in jsdoc (e.g. you can constrain templates in jsdoc but you can't provide default values), but being more explicit with some of these annotations (as the comment added below mentions) makes it work without being overly prescriptive or falling back to any.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I suppose we could dream 😄

later I'd be on board for returning these to nice clean objects and moving those metric helpers into helpers functions instead of OO spaghetti 👍

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

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

wowza

NICE. LEE. DONE.

🔧 🛠 💥 💯

now quick before a conflict! :D

@@ -9,7 +9,7 @@ const ArbitraryEqualityMap = require('../../lib/arbitrary-equality-map');

class ComputedArtifact {
/**
* @param {LH.ComputedArtifacts} allComputedArtifacts
* @param {*} allComputedArtifacts
Copy link
Collaborator

Choose a reason for hiding this comment

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

what's the longer term plan for new-computed-artifact and this file? or is new-computed-artifact meant to be like the verb constructor not the new file and I've misread it the whole time... 😮

Copy link
Member Author

Choose a reason for hiding this comment

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

what's the longer term plan for new-computed-artifact and this file?

that's the cleanup followup I mentioned. I'll delete that one, rename the new- file, then I wanted to add some tests and possibly do the file move.

@@ -7,6 +7,7 @@

const Audit = require('../audit');
const i18n = require('../../lib/i18n/i18n.js');
const ComputedSi = require('../../gather/computed/metrics/speed-index.js');
Copy link
Collaborator

Choose a reason for hiding this comment

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

Si 🤢

@@ -7,6 +7,7 @@

const Audit = require('../audit');
const i18n = require('../../lib/i18n/i18n.js');
const ComputedFci = require('../../gather/computed/metrics/first-cpu-idle.js');
Copy link
Collaborator

Choose a reason for hiding this comment

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

Fci 🤢

Copy link
Member Author

Choose a reason for hiding this comment

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

ComputedFci 🤢

I couldn't think of another name since SpeedIndex is already taken by the audit class itself and ComputedFirstCPUIdle seemed way too long. I spent exactly 0 time coming up with the name, though, so I'm happy to change :)

Copy link
Member Author

Choose a reason for hiding this comment

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

ComputedFci 🤢

Unless you mean the capitalization scheme, in which case I WILL DIE ON THIS HILL

Copy link
Collaborator

Choose a reason for hiding this comment

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

Unless you mean the capitalization scheme

Hahaha, that is exactly what I mean :)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Then shouldn't below be FirstCpuIdle? :)

Copy link
Member Author

Choose a reason for hiding this comment

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

ha, @paulirish caught the same thing :) My defense is that I was merely moving the existing line in the file, git diff just can't handle visualizing it :P

Copy link
Member Author

Choose a reason for hiding this comment

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

(also that--even though it totally is the way better way--we gave up on consistency on this particular issue a long time ago because no one manages to remember to enforce their favorite way every time. See also: XMLHttpRequest)

@@ -7,6 +7,7 @@

const Audit = require('../audit');
const i18n = require('../../lib/i18n/i18n.js');
const ComputedEil = require('../../gather/computed/metrics/estimated-input-latency.js');
Copy link
Collaborator

Choose a reason for hiding this comment

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

Eil 🤢

@@ -56,8 +52,19 @@ class LanternFirstCPUIdle extends LanternInteractive {
longTasks.push({start: timing.startTime, end: timing.endTime});
}

// Require here to resolve circular dependency.
const FirstCPUIdle = require('./first-cpu-idle');
Copy link
Collaborator

Choose a reason for hiding this comment

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

this scares me a little, why does that require this?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I found the new structure for computeSimulatedMetrics 👍

Copy link
Member Author

Choose a reason for hiding this comment

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

I found the new structure for computeSimulatedMetrics 👍

yeah, this seemed fine for now since it's just two places, but we can always refactor into helper functions for things like findQuietWindow

Copy link
Collaborator

Choose a reason for hiding this comment

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

yeah sg

* Decorate computableArtifact with a caching `request()` method which will
* automatically call `computableArtifact.compute_()` under the hood.
* @template {{name: string, compute_(artifacts: unknown, context: LH.Audit.Context): Promise<unknown>}} C
* @param {C} computableArtifact
Copy link
Collaborator

Choose a reason for hiding this comment

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

I suppose we could dream 😄

later I'd be on board for returning these to nice clean objects and moving those metric helpers into helpers functions instead of OO spaghetti 👍

@brendankenny
Copy link
Member Author

Breaking everybody, sry :)

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

Successfully merging this pull request may close these issues.

None yet

4 participants