-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
Conversation
There was a problem hiding this 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.
{src: 'https://example.com/coursehero-bundle-2.js', content: bundleData2.content}, | ||
], | ||
}; | ||
const results = await BundleDuplicationAudit.audit_(artifacts, [], context); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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 :)
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah exactly 👍
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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) { | ||
// ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// ? | |
// 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)
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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 :)
static _shouldIgnoreSource(source) { | ||
// Ignore bundle overhead. | ||
if (source.includes('webpack/bootstrap')) return true; | ||
if (source.includes('(webpack)/buildin')) return true; |
There was a problem hiding this comment.
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
Co-Authored-By: Patrick Hulce <[email protected]>
There was a problem hiding this 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. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/** 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; |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@patrickhulce suggested some renames: computed artifact => ModuleDuplication |
One of a few features I'm extracting from the bundle-analysis (#10064) branch.
In draft b/c no tests.