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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃檵 Tree Shaking #392

Closed
devongovett opened this Issue Dec 23, 2017 · 29 comments

Comments

Projects
None yet
@devongovett
Copy link
Member

devongovett commented Dec 23, 2017

We should add tree shaking to Parcel in production mode so we have smaller bundle sizes. Because this requires cross-file optimizations, it will be harder to do with Parcel's parallel architecture. This basically means that tree-shaking must be done in a Packager.

There are a few approaches we could take:

  • Use Rollup. I tried creating a RollupPackager to replace the current JSPackager in production mode, which just runs everything through Rollup. This worked and was relatively simple to implement, but was extremely slow. e.g. a 3s build went to 15s. It also only really works well with ES6 modules, not CommonJS which is much more common (haha) still especially in Node modules.
  • Use something like common-shake, which is a library for doing tree-shaking on CommonJS modules. I haven't tried it, but it looks neat and is a library rather than a full bundler.
  • Implement something ourselves. Sounds like a lot of work, but we may be able to tune it specifically for Parcel's architecture, e.g. doing some work in the Asset workers, and some in the Packager.

Goals we should aim for:

  • Support ES6 modules
  • Support CommonJS modules
  • Eliminate the module wrappers/runtime that JSPackager uses as much as possible by e.g. concatenating modules like Rollup does (scope hoisting)
  • Be relatively fast still
  • Support something like webpack 4's sideEffects: false option in package.json to enable us to not parse or include all code that is imported but not used.

Would love to hear some feedback on this, and if you have ideas on how we should implement this or features we should support please comment below! 馃槏

@lukeed

This comment has been minimized.

Copy link

lukeed commented Dec 24, 2017

I'm sorry to say, but since you're already constructing your own Asset & Bundle trees, it makes most sense (to me) that you create your own tree shaker. You have (nearly) all the info that you need to know, so why pass it off to another tool which is going to reconstruct another/similar tree, just to acquire the same info you already have. 馃檭

@steveblue

This comment has been minimized.

Copy link

steveblue commented Dec 24, 2017

+1 custom. If Parcel can treeshake with multiple cores, it would be a huge advantage over the competition. There are fairly huge limitations with the tools you mentioned @devongovett. The only way to overcome those limitations would be a custom implementation. The ability to treeshake multiple module patterns in one app is a huge problem that needs to be resolved by someone.

@xywai1993

This comment has been minimized.

Copy link

xywai1993 commented Dec 27, 2017

source map 馃槃

@xuqiang521

This comment has been minimized.

Copy link

xuqiang521 commented Dec 28, 2017

It is worth waiting 馃槏 fighting ~

@devongovett

This comment has been minimized.

Copy link
Member

devongovett commented Jan 27, 2018

@davidnagli did you mean to close this?

@devongovett devongovett reopened this Jan 27, 2018

@davidnagli

This comment has been minimized.

Copy link
Member

davidnagli commented Jan 27, 2018

Whoops sorry!!!!

@jackwen110200

This comment has been minimized.

Copy link

jackwen110200 commented Jan 30, 2018

waiting special

@emmanuelchucks

This comment has been minimized.

Copy link

emmanuelchucks commented Feb 3, 2018

Can't wait to see this implemented in Parcel

@jsiebern

This comment has been minimized.

Copy link
Contributor

jsiebern commented Feb 9, 2018

+1, I'm trying Parcel for the first time & it is a great experience, the only issue I have is that my bundle sizes are singnificantly bigger than with Webpack (I'm talking 300kb no gzip production mode)

@Siyfion

This comment has been minimized.

Copy link

Siyfion commented Feb 9, 2018

@jsiebern I know that this doesn't solve the root-issue, but perhaps think about doing some code-splitting? You could potentially provide a better experience to your end-users if you split the codebase and pre-fetched in the background after the initial load? Plus, when tree-shaking is implemented, it's still a decent thing to have done.

@jsiebern

This comment has been minimized.

Copy link
Contributor

jsiebern commented Feb 9, 2018

@Siyfion Unfortunately I'm shipping my code as part of a Wordpress plugin where every environment / url is totally different (and out of my control), code splitting won't work for me unfortunately

Edit: Just tried it for the kicks, it seems that Parcel does not have any issues with changing urls, I'm impressed. I might stick with it then, I need to do some testing, thanks for the nudge :)

@ConneXNL

This comment has been minimized.

Copy link

ConneXNL commented Feb 9, 2018

One example of where tree shaking makes a lot of sense to work without could configuration is when using a library like lodash. lodash-es recently added the webpack 4 "side effects: false" in the package.json (not sure if it's released yet).

@Siyfion

This comment has been minimized.

Copy link

Siyfion commented Feb 9, 2018

To be completely honest @ConneXNL, tree shaking makes sense for almost every library.

@mischnic

This comment has been minimized.

Copy link
Contributor

mischnic commented Feb 19, 2018

Just for reference, there is a pull request: #731.

@HenrikJoreteg

This comment has been minimized.

Copy link

HenrikJoreteg commented Feb 21, 2018

Any reason to not just use rollup? Also, if speed is a concern, one could potentially just do it when building for production.

The lack of treeshaking is the only thing keeping me from using parcel for production projects.

@HenrikJoreteg

This comment has been minimized.

Copy link

HenrikJoreteg commented Feb 21, 2018

Also, even if treeshaking only was applied for packages that have a 鈥榤odule鈥 field in the package.json that still seems like a big improvement to me.

@devongovett

This comment has been minimized.

Copy link
Member

devongovett commented Feb 22, 2018

Sure, I did get sending to rollup on build working at one point. It was really slow though. A 3s build to 15s is not acceptable IMO.

Tree shaking is our next big area of focus. Hopefully we'll do some experimentation and come up with something good over the next few weeks. 馃槃

@devongovett devongovett added this to the v1.8.0 milestone Mar 9, 2018

@wzrdtales

This comment has been minimized.

Copy link

wzrdtales commented Mar 12, 2018

Does this issue respect css treeshaking as well already?

@devongovett

This comment has been minimized.

Copy link
Member

devongovett commented Apr 2, 2018

See #1104, where scope hoisting is being discussed/implemented. You can check the scope-hoist branch to follow along with our progress!

@jbreckmckye

This comment has been minimized.

Copy link

jbreckmckye commented Apr 18, 2018

@devongovett

Sure, I did get sending to rollup on build working at one point. It was really slow though. A 3s build to 15s is not acceptable IMO.

If it's a production build - maybe it is? It could be an optional parameter. I can accept a 15s build on CI, so long as my devzone builds remain lightning-quick.

@fathyb fathyb referenced this issue Apr 18, 2018

Merged

Scope hoisting for ES6 and CommonJS modules #1135

14 of 14 tasks complete

@devongovett devongovett removed this from the v1.8.0 milestone May 1, 2018

@devongovett devongovett added this to the v1.9.0 milestone May 1, 2018

@ozra

This comment has been minimized.

Copy link

ozra commented Jun 5, 2018

Being used to compiling C++ with LTO opts, minutes wouldn't be a problem for production builds. It's only in dev where the speed really is needed imo. Tests take a whole lot more time to run through any way.

@xemasiv

This comment has been minimized.

Copy link

xemasiv commented Jun 10, 2018

Goddamn I love parcel. - my mind was fucking blown when I saw it install the missing dependencies.
I'm using it for dev right now and I can just imagine the comfort it gives to js newcomers.

Anyways ontopic : I personally think using parcel for prod would be a big tradeoff though since not everyone's prod requirements are the same - like me, some people are optimization freaks - maybe parcel can optionally accept custom configs?

It's prod anyways, I sincerely think this is the right spot to introduce optional webpack-level configurability.

Oh parcel <3

@devongovett

This comment has been minimized.

Copy link
Member

devongovett commented Jun 14, 2018

Tree shaking is now merged in v1.9.0! 馃殌

You can try it out with the --experimental-scope-hoisting flag. We'll enable it by default in a coming version.

Read more about how it works here: https://medium.com/@devongovett/parcel-v1-9-0-tree-shaking-2x-faster-watcher-and-more-87f2e1a70f79

@goyney

This comment has been minimized.

Copy link

goyney commented Jun 14, 2018

$ parcel build --experimental-scope-hoisting --out-dir ../build/dist --public-url ./ ./index.html

  error: unknown option `--experimental-scope-hoisting'
@devongovett

This comment has been minimized.

Copy link
Member

devongovett commented Jun 14, 2018

@goyney make sure you're running the latest version 馃槈

@goyney

This comment has been minimized.

Copy link

goyney commented Jun 14, 2018

Definitely on 1.9.0.

@friday

This comment has been minimized.

Copy link

friday commented Jun 14, 2018

If you are on 1.9.0, the output of parcel --version should be 1.9.0.

If it's not, then it's likely that you have installed 1.9.0 locally for the repo, but are running the command with a global installation of parcel from earlier. Try adding npx before your command to use the local version.

@goyney

This comment has been minimized.

Copy link

goyney commented Jun 14, 2018

Stupid me, I left out the word build. :( Carry on.

@kimamula

This comment has been minimized.

Copy link

kimamula commented Jun 15, 2018

It seems Parcel 1.9.0 only accepts false for the sideEffects option.
Are you planning to support specifying an array of file names for the sideEffects option as webpack does?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment