-
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(legacy-javascript): reduce polyfills, fix core-js import in test #10937
Conversation
{signal: 'String.prototype.codePointAt'}, | ||
{signal: 'String.fromCodePoint'}, | ||
{signal: 'String.raw'}, | ||
{signal: 'String.prototype.repeat'}, |
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 have been a clue something was wrong. the legacy-javascript.js
fixture here is the core-js@3 esmodules: false
variant, which should have dozens of variants.
}, /** @type {string[]} */ ([])).join(', '); | ||
variants.push({name: dir, signals}); | ||
|
||
const signals = []; |
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.
#10867 should have failed this test in CI .... fixing here
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.
oh this is a thorny problem. we don't know when to run these tests because something they depend on changed :/
I don't have any great ideas to fix this though other than catching it the next time. you?
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.
but test-legacy-javascript.sh
checks for any file with legacy-javascript
in the path. It should have triggered on a change to the audit.
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.
well then that's even more alarming :)
my point is still a problem I don't know a good way to deal with, but perhaps less urgent than outright broken testing 😆
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.
it did fail but didn't exit with code 1
https://travis-ci.org/github/GoogleChrome/lighthouse/builds/696156441#L1224
need to add
main().catch(err => {
console.error(err);
process.exit(1);
})
1352 true/main.bundle.min.js | ||
188400 false/main.bundle.min.js | ||
64217 true/main.bundle.min.js | ||
63536 true-and-bugfixes/main.bundle.min.js |
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.
The small difference from bugfixes: true
is because it only reduces the number of transforms applied. And the main.js
file used is super small.
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.
oh, and adding bugfixes
variant is orthogonal to the rest of this PR, I just wanted to add this.
@@ -144,11 +144,12 @@ describe('LegacyJavaScript audit', () => { | |||
'String.prototype[\'repeat\'] = function() {}', | |||
'Object.defineProperty(String.prototype, "repeat", function() {})', | |||
'Object.defineProperty(String.prototype, \'repeat\', function() {})', | |||
'Object.defineProperty(window, \'WeakMap\', function() {})', | |||
// Currently are no polyfills that declare a class. May be in the future. |
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'm hopeful that we can somehow get preset-modules
to workaround the bugs that require Promises to be polyfilled. keeping this around + the code in legacy-javascript that detects this.
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'm struggling to interpret the output in babel/babel#11700 (comment) a bit. Could you help me out?
Does each row of the polyfill say which target requires that the polyfill be used?
For example for the typed arrays it looks like safari 10.1 forces it, even though Uint8Array
was in Safari 5. I'm guessing there is some bug that makes it not behave exactly the same way?
I wish we had a better way to track each of these bugs, what they are/why you need them and/or an even more modern delivery discriminant than esmodules. Some of these are really massive polyfills just for what I'm guessing is like one obscure bug fix of a 3 year old versioned browser.
}, /** @type {string[]} */ ([])).join(', '); | ||
variants.push({name: dir, signals}); | ||
|
||
const signals = []; |
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.
oh this is a thorny problem. we don't know when to run these tests because something they depend on changed :/
I don't have any great ideas to fix this though other than catching it the next time. you?
['String.prototype.startsWith', 'es6.string.starts-with'], | ||
['String.prototype.trim', 'es6.string.trim'], | ||
// These break the coreJs2/coreJs3 naming pattern so are set explicitly. | ||
{name: 'ArrayBuffer', coreJs2Module: 'es6.typed.array-buffer', coreJs3Module: 'es.array-buffer.constructor'}, |
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.
aren't these all the biggest ones? and they're really all included in every esmodules: true bundle? :(
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.
ye :(
['Number.parseInt', 'es6.number.parse-int'], | ||
['Object.assign', 'es6.object.assign'], |
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'm still incredulous that modern browsers need Object.assign
polyfilled... 😢
@@ -205,7 +200,6 @@ class LegacyJavascript extends Audit { | |||
['Object.preventExtensions', 'es6.object.prevent-extensions'], | |||
['Object.seal', 'es6.object.seal'], | |||
['Object.setPrototypeOf', 'es6.object.set-prototype-of'], | |||
['Promise', 'es6.promise'], |
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.
and promises!?
Yes.
and each polyfill or transform that matches one of these targets is printed out.
Honestly, I can't figure this out.
It seems that because safari is not listed, that it would get polyfilled for all versions of safari (ios too). If this is WAI I must assume there is some bug in all versions Safari that makes typed arrays inconsistent with other browsers. typed-array was added in core-js@2, can't find much discussion other than this: zloirock/core-js#90 @developit said that all methods that accept a regex parameter must be polyfilled in older browsers. I don't see a similar reason to polyfill the typed arrays. EDIT: seems it's only b/c of a bug in A really nice thing about the caniuse data is that is gives reasons/comments in the data for such things.
that's the dream ... @paulirish and I want to explore extending
https://github.com/zloirock/core-js/blob/master/packages/core-js-compat/src/data.js#L705
|
Also, I have some catching up to do on the babel polyfill space :) babel/babel#11700 (comment) It seems the logic for determining what polyfills are needed is being pulled up to a new plugin @hzoo I understand this stuff is experimental atm, just wondering if the plan is to later modify |
The plan is to keep the polyfills and the transforms separated, so eventually everyone will need to use one of the new polyfill providers. On the other hand, we are exploring the idea moving back preset-env into If you are 100% sure that the typed arrays bug doesn't affect your code, you can use the |
Interesting, thanks for the insight.
Thanks @nicolo-ribaudo . The goal of this audit ultimately is to recommend other developers to use We could go further and say "exclude typed polyfills" because the bug is seemingly so negligible yet the polyfill so large. We'd much rather explore the possibility of getting that to be the default behavior of |
Also note that currently |
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.
sad day but important 👍
['Array.prototype.fill', 'es6.array.fill'], | ||
['Array.prototype.filter', 'es6.array.filter'], | ||
['Array.prototype.find', 'es6.array.find'], | ||
['Array.prototype.findIndex', 'es6.array.find-index'], | ||
['Array.prototype.forEach', 'es6.array.for-each'], | ||
['Array.from', 'es6.array.from'], | ||
['Array.isArray', 'es6.array.is-array'], | ||
['Array.prototype.lastIndexOf', 'es6.array.last-index-of'], |
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.
instead of removing these can we flag them with an extra property or move them to another array somewhere? it'd be nice to keep track of what we should detect once we figure out how to solve the bugfixes problem and not lose all this research
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.
what we should detect is simply any polyfill that will never be in a bundle w/ esmodules: true, bugfixes: true
(using either core-js@2 or core-js@3). everything being removed fails that criteria. if we add any back, it'll be because something changed upstream (and we can just add back to this list) or we accompany it with documentation for how and why to exclude (what we may do for typed-array, promise).
so I'm ok w/ just deleting these items. git blame and these PRs are enough history for me if I need to refer back for some reason.
This list is derived from the diff of the debug output when you toggle esmodule: true/false
. It may be good to print out that output in legacy-javascript/run.js
(doing much more than that would be more work than I'd like)
sidenote on the line you commented on... last-index-of used to be set to an older version of safari but was bumped here: zloirock/core-js@e4cea55
no idea what bug this is preventing lol https://github.com/zloirock/core-js/blob/master/packages/core-js/internals/array-method-uses-to-length.js
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.
alright wfm
I'd think future me would be annoyed by having to hunt down an ancient PR and copy paste individual lines from a diff that no longer merges for this info but I'll defer to your future self since it's almost definitely going to be you anyway :)
}, /** @type {string[]} */ ([])).join(', '); | ||
variants.push({name: dir, signals}); | ||
|
||
const signals = []; |
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.
it did fail but didn't exit with code 1
https://travis-ci.org/github/GoogleChrome/lighthouse/builds/696156441#L1224
need to add
main().catch(err => {
console.error(err);
process.exit(1);
})
@@ -1,29 +1,11 @@ | |||
all-legacy-polyfills | |||
175764 all-legacy-polyfills-core-js-3/main.bundle.min.js | |||
125257 all-legacy-polyfills-core-js-2/main.bundle.min.js | |||
85169 all-legacy-polyfills-core-js-3/main.bundle.min.js |
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.
ouch, takin' a 50% hit to the ceiling of benefit :(
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.
:(
'WeakMap = function() {}', | ||
'window.WeakMap = function() {}', | ||
'function WeakMap() {}', | ||
// 'WeakMap = function() {}', |
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.
should we delete these or are these comments important?
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.
Did you see my comment a few lines up
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 did, I just didn't make the connection :)
maybe just group all 4 of them together with that comment?
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
'WeakMap = function() {}', | ||
'window.WeakMap = function() {}', | ||
'function WeakMap() {}', | ||
// 'WeakMap = function() {}', |
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 did, I just didn't make the connection :)
maybe just group all 4 of them together with that comment?
['Array.prototype.fill', 'es6.array.fill'], | ||
['Array.prototype.filter', 'es6.array.filter'], | ||
['Array.prototype.find', 'es6.array.find'], | ||
['Array.prototype.findIndex', 'es6.array.find-index'], | ||
['Array.prototype.forEach', 'es6.array.for-each'], | ||
['Array.from', 'es6.array.from'], | ||
['Array.isArray', 'es6.array.is-array'], | ||
['Array.prototype.lastIndexOf', 'es6.array.last-index-of'], |
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.
alright wfm
I'd think future me would be annoyed by having to hunt down an ancient PR and copy paste individual lines from a diff that no longer merges for this info but I'll defer to your future self since it's almost definitely going to be you anyway :)
I think we would be glad to chat or work with y'all on this! |
If next time you will have questions about what and why polyfilled, please, ask me or at least take a look at tests that generate |
The PR addresses two things:
require('core-js')
is vital forpreset-env
to import any polyfills. The esmodules variants were missing this, so the bundles only differed minimally (transforms). After adding this, I noticed thatObject.create
was included forcore-js@2
+esmodule: true
, so I removed that polyfill.core-js@3 esmodules: true
variant had many signals–the expectation is that there be none. I realized that many polyfills should not be used as discriminators for identifying an module/nomodule build. See preset-env core-js 3 includes extra polyfills babel/babel#11700 (comment) . This resulted in removing ~25 polyfills (see below).Related: #10852