Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Polyfills #173

Merged
merged 7 commits into from
Apr 12, 2017
Merged

Polyfills #173

merged 7 commits into from
Apr 12, 2017

Conversation

constgen
Copy link
Contributor

The problem is that 'babel-preset-env' doesn't consider defined platforms to filter only necessary polyfills. This change fixes this. Also polyfills are extracted to the 'vendor' chank.
Before
before
After
after
From 247KB down to 89KB

Copy link
Member

@eliperelman eliperelman left a comment

Choose a reason for hiding this comment

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

This is awesome! Just a few tweaks, and we should be able to ship this.

@@ -85,8 +84,10 @@ module.exports = (neutrino) => {
.when(process.env.NODE_ENV !== 'test', () => neutrino.use(chunk))
.target('web')
.context(neutrino.options.root)
.entry('vendor')
Copy link
Member

Choose a reason for hiding this comment

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

Dedent this line so it lines up with .context().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, will do

@@ -0,0 +1 @@
import 'babel-polyfill';
Copy link
Member

Choose a reason for hiding this comment

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

Add a blank line to the end of this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My bad. Usually VSCode helps me with this automatically.

@@ -67,14 +67,13 @@ module.exports = (neutrino) => {
neutrino.use(htmlTemplate, neutrino.options.html);
neutrino.use(namedModules);
neutrino.use(compileLoader, {
include: [neutrino.options.source, neutrino.options.tests],
include: [neutrino.options.source, neutrino.options.tests, require.resolve('./polyfills.js')],
Copy link
Member

Choose a reason for hiding this comment

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

Do we have to add this file to the compilation? Does it work if we switch the polyfills file to use require?

require('babel-polyfill');

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you mean to avoid './polyfills.js' it will not work. babel-preset-env just want to see some where the importing of 'babel-polyfill'. And it doesn't see it if this file is an entry point itself.

Copy link
Member

@eliperelman eliperelman Apr 11, 2017

Choose a reason for hiding this comment

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

I mean, if they want to not have polyfills in their project at all. They should have the ability to remove it if they wish.

Copy link
Contributor Author

@constgen constgen Apr 11, 2017

Choose a reason for hiding this comment

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

To be honest didn't think about this "include". I see that it will not affect the build until somebody will import exactly this file ./polyfills.js.

@@ -85,8 +84,10 @@ module.exports = (neutrino) => {
.when(process.env.NODE_ENV !== 'test', () => neutrino.use(chunk))
.target('web')
.context(neutrino.options.root)
.entry('vendor')
.add(require.resolve('./polyfills.js'))
Copy link
Member

Choose a reason for hiding this comment

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

Removing the polyfills file different, since we can't just remove based on the location of babel-polyfill. I'm not saying this is a bad thing, just different. We should probably add this to the docs, about how to remove the polyfills.

neutrino.config
  .entry('vendor')
    .delete(require.resolve('neutrino-preset-web/polyfills'))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Originally this refactoring had a separate entry point .entry('polyfills') which produced one more file chunk. In this case polyfills could be disabled easy by name. But I decided to make changes more soft and joined vendor with polyfills togehter. Now splitting vendor and polyfills seems not a bad idea from the configuration perspective.

@eliperelman
Copy link
Member

@jaridmargolin any thoughts?

@jaridmargolin
Copy link
Contributor

jaridmargolin commented Apr 11, 2017

@eliperelman @constgen - The idea of creating a separate file that imports is definitely a creative solution that solves the problem.

I am curious if automatically including it in the vendor is correct. If I begin utilizing new es features in my index entry, I wouldn't want my vendor bundle cache to be busted (or if my supported browser set changes). Overall curious if vendors & pollyfills should be tightly coupled.

Originally this refactoring had a separate entry point .entry('polyfills') which produced one more file chunk. In this case polyfills could be disabled easy by name. But I decided to make changes more soft and joined vendor with polyfills togehter. Now splitting vendor and polyfills seems not a bad idea from the configuration perspective.

I think the the separate polyfills entry might be a better solution.

EDIT: I had previously watched a talk that spoke about the effects of single file vs multiple bundles which load in parallel. I want to dig a little deeper in how these decisions apply to first paint (on first visit vs revisit vs cache bust).

@eliperelman
Copy link
Member

I'm leaning towards the separate polyfills entrypoint as well.

@codecov
Copy link

codecov bot commented Apr 11, 2017

Codecov Report

Merging #173 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #173   +/-   ##
=======================================
  Coverage   90.69%   90.69%           
=======================================
  Files          36       36           
  Lines         419      419           
=======================================
  Hits          380      380           
  Misses         39       39
Impacted Files Coverage Δ
packages/neutrino-preset-web/index.js 80.95% <ø> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f2c1dfb...9582366. Read the comment docs.

@constgen
Copy link
Contributor Author

constgen commented Apr 11, 2017

Made necessary changes. Now in my example I also added the 'lodash' library to entries and imported it in the index.js just to see how everything works together. The output is:
after-after

We still have an open question: "What if somebody will reconfigure a 'compile' rule 'include' section and erase require.resolve('./polyfills.js')?" Babel will no longer consider this file and the chunk size will rise again.

@jaridmargolin
Copy link
Contributor

^ above I was referring to some findings here: https://youtu.be/6m_E-mC0y3Y?list=PLNYkxOF6rcICc687SxHQRuo9TVNOJelSZ&t=248

Its not an exact science but the overall takeaway is, in certain cases, making multiple requests in parallel can be comparable or even faster than requesting a single bundle. I think we could benefit from spending a tiny bit of time profiling performance before making a decision here.

* There are definitely additional resources on this topic but I had a difficult time finding them.

@constgen
Copy link
Contributor Author

Additionally when we are in a dev mode (npm start) the rebuild will be faster because only index chunk is processed.

@eliperelman
Copy link
Member

Tested this out locally, everything worked great!

@eliperelman eliperelman merged commit f6bcb7b into neutrinojs:master Apr 12, 2017
@eliperelman
Copy link
Member

Sooo, do we need to add polyfills to the chunks? Right now the only defaulted chunks from the chunk middleware are vendor and manifest. Thoughts?

@constgen
Copy link
Contributor Author

Only if somebody is going to import/require polyfills to his code base. I believe it's not going to happen. But my opinion may be wrong.

@eliperelman
Copy link
Member

I must've missed something, because when running this while using async, I received a message about regeneratorRuntime being missing. Modifying the web middleware to also include polyfill in the chunk seems to have fixed it.

@constgen
Copy link
Contributor Author

constgen commented Apr 12, 2017

Interesting. This is definitely related to one of commits in this branch where I removed the 'transform-regenerator' from the babel preset because it is included in the polyfills on demand.

@constgen constgen deleted the polyfills branch April 12, 2017 20:43
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants