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(duplicated-javascript): new audit #10314

Merged
merged 25 commits into from
Mar 6, 2020
Merged

core(duplicated-javascript): new audit #10314

merged 25 commits into from
Mar 6, 2020

Conversation

connorjclark
Copy link
Collaborator

One of a few features I'm extracting from the bundle-analysis (#10064) branch.

image

In draft b/c no tests.

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.

I am super excited to see this land in default :D awesome awesome stuff!

I've lost track between PRs but is there a set of scripts you have for pulling down the coursehero examples? would be awesome to one day get some smoketests with our own webpack build that we can test out newer versions of webpack, make sure we still handle them well, etc.

lighthouse-core/computed/javascript-duplication.js Outdated Show resolved Hide resolved
lighthouse-core/computed/javascript-duplication.js Outdated Show resolved Hide resolved
lighthouse-core/computed/javascript-duplication.js Outdated Show resolved Hide resolved
{src: 'https://example.com/coursehero-bundle-2.js', content: bundleData2.content},
],
};
const results = await BundleDuplicationAudit.audit_(artifacts, [], context);
Copy link
Collaborator

Choose a reason for hiding this comment

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

would love to get 1 test where we exercise the providedWastedBytesByUrl too, maybe create some fake bundles for our fixture trace?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

don't see how to do this ... computeWasteWithTTIGraph just spits out a number. does that method need to be decomposed?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I just mean test the results from audit() not just audit_() at least once

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

cool, done

"https://example.com/coursehero-bundle-1.js",
"https://example.com/coursehero-bundle-2.js",
],
"wastedBytes": 10519,
Copy link
Collaborator

Choose a reason for hiding this comment

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

example of the folder thing I'd love to see node_modules/@babel/runtime and node_modules/lodash-es split out as rows :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ah, here's the clarification i needed

you are suggesting aggregating all the modules matching node_modules/(@.*)?/(.*)/**/* into one row?

Copy link
Collaborator

Choose a reason for hiding this comment

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

yeah exactly 👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I have concerns about doing that - consider lodash. One bundle might need lodash/deep, another lodash/get. Pretend each is pretty big. We'd then be falsely reporting that there's duplication across those two bundles. Using different modules from the same package in different bundles should be allowed.

Also, I just think it's simpler to keep this in terms of modules.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe there's a misunderstanding then. We wouldn't be falsely reporting any duplicates with what I'm proposing. This is exclusively for UI presentation in how we aggregate the already identified duplicates modules.

In the scenario that both lodash/deep and lodash/get are duplicated in different bundles, it seems pretty reasonable to say that "lodash" is duplicated. It at least gives the correct actionable advice. But the one real world situation we're analyzing here is even way more clear cut. Right now we have the completely unactionable "Other" when we could at least pull out @babel/runtime and lodash-es

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Got it! I'm cool with this - even though it loses some amount specificity, knowing exactly which modules are duplicated should be possible with the treemap viz I have planned for duplicated modules. so let's do this.

const networkRecord = networkRecords.find(n => n.url === url);
const script = artifacts.ScriptElements.find(script => script.src === url);
if (!networkRecord || !script || script.content === null) {
// ?
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// ?
// this should never happen because we found the content from scripts that were bundles with source maps

could they have been inline scripts with a source map comment though? maybe we should fallback to the main resource for estimation which is what we did normally for estimateTransferSize (in unused css for example)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah that's exactly what we should do for inline bundles.

{key: 'wastedBytes', valueType: 'bytes', granularity: 0.05, label: str_(i18n.UIStrings.columnWastedBytes)},
];

// TODO: show warning somewhere if no source maps.
Copy link
Collaborator

Choose a reason for hiding this comment

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

ah if we gotta wire it let's just punt then, this has grown enough :)

lighthouse-core/computed/javascript-duplication.js Outdated Show resolved Hide resolved
static _shouldIgnoreSource(source) {
// Ignore bundle overhead.
if (source.includes('webpack/bootstrap')) return true;
if (source.includes('(webpack)/buildin')) return true;
Copy link
Collaborator

Choose a reason for hiding this comment

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

just curious did you take a look at any sites built with parcel for their overhead names?

https://lhci-canary.herokuapp.com/app/projects/d1e4b15c-e644-4552-b136-e975f486a2ce/dashboard should have sourcemaps and multiple bundles for future examples if you need one

@vercel vercel bot temporarily deployed to Preview March 5, 2020 22:58 Inactive
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.

LGTM

const UIStrings = {
/** Imperative title of a Lighthouse audit that tells the user to remove duplicate JavaScript from their code. This is displayed in a list of audit titles that Lighthouse generates. */
title: 'Remove duplicate modules in JavaScript bundles',
/** Description of a Lighthouse audit that tells the user *why* they should defer loading any content in CSS that isn’t needed at page load. This is displayed after a user expands the section to see more. No word length limits. 'Learn More' becomes link text to additional documentation. */
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
/** Description of a Lighthouse audit that tells the user *why* they should defer loading any content in CSS that isn’t needed at page load. This is displayed after a user expands the section to see more. No word length limits. 'Learn More' becomes link text to additional documentation. */
/** Description of a Lighthouse audit that tells the user *why* they should remote duplicate JavaScript from their scripts. This is displayed after a user expands the section to see more. No word length limits. 'Learn More' becomes link text to additional documentation. */

static _shouldIgnoreSource(source) {
// Ignore bundle overhead.
if (source.includes('webpack/bootstrap')) return true;
if (source.includes('(webpack)/buildin')) return true;
Copy link
Collaborator

Choose a reason for hiding this comment

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

interesting thanks for looking into ti! we can followup here if we end up seeing this in practice later

const context = {settings, computedCache: new Map()};
const results = await BundleDuplicationAudit.audit(artifacts, context);

// Without the `wastedBytesByUrl` this would be zero because the items don't define a url.
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍

@connorjclark
Copy link
Collaborator Author

@patrickhulce suggested some renames:

computed artifact => ModuleDuplication
audit => duplicated-javascript

@vercel vercel bot temporarily deployed to Preview March 6, 2020 23:03 Inactive
@connorjclark connorjclark changed the title core(bundle-duplication): new audit core(duplicated-javascript): new audit Mar 6, 2020
@devtools-bot devtools-bot merged commit ea9d226 into master Mar 6, 2020
@devtools-bot devtools-bot deleted the bundle-dupe branch March 6, 2020 23:28
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.

4 participants