meteor-feature-requests
meteor-feature-requests copied to clipboard
Build Tool: Add Tree-Shaking Capability
We need to be able to remove unused code from our own code base and from imported dependencies when we ship for production. https://medium.com/@roman01la/dead-code-elimination-and-tree-shaking-in-javascript-build-systems-fb8512c86edf
It seems like dead code elimination has been turned on in dev. https://github.com/meteor/meteor/commit/9e65d8bea72068f042b41ffa0df55791b4c7d71f
The basic trick to tree-shaking is to prune unused exports (by removing some identifiers from export declarations) and then run a generic dead code elimination tool (such as UglifyJS) to get rid of any code that only needed to exist because of the unused exports.
The hard part is knowing when to stop, because dead code elimination might remove require calls and/or nested import declarations, which might result in additional unused exports, which might enable another round of dead code elimination.
If this iterative process is done right, you can remove whole dependency trees from your bundle, which is much more powerful than removing some bits of code from some modules, while leaving those slimmer modules, and all their dependencies, in the bundle.
Rollup will never implement this kind of tree-shaking, because Rollup mandates top-level import declarations, which can never be safely dead-code-eliminated.
Webpack doesn't implement iterative tree-shaking either, even though require-style dependencies can appear within code that could be dead-code-eliminated. Their loss!
In other words, there's room here to do tree shaking and dead code elimination better than anyone else, though it's going to be tricky to do it efficiently.
I would also like to stress that dead code elimination is an optimization, and optimizations are inherently best-effort. There are no guarantees that the static analysis will be able to identify every bit of unused code, and many reasons (such as performance) for it to give up trying. That's a good thing, since it's better to miss out on some optimizations than to wait forever for your bundler to finish, or (worse!) to end up with a broken bundle. When folks in the Webpack community complain that tree-shaking doesn't always work, they're missing this important perspective.
@benjamn yes it will be hard to achieve perfect tree shaking but if it goes about performance, could we make it optional with some extra flag? And only perform it when generating production build? I think in most cases it's not necessary to have tree shaking in development. The --production flag could also turn on tree shaking and dead code elimination.
It is also important to consider that unused imports can have intended side effects, and can also be used to change module evaluation order, which is important in solving cyclic dependency problems.
Maybe it's already provided but if not It would be nice to offer some output to developers about what is being shaken out and why. That way they have the chance to clean up their code so we don't keep shaking down the same dead code every time the cache is blown away.
Adding to the convo here - new Medium post I found yesterday for how to accomplish tree-shaking
https://medium.com/@ninjaPixel/improving-the-performance-of-your-meteor-app-423cc94dfbd3
Are you planning to start work on this feature? For me it seems pretty important to load to a user as a small bundle as possible, considering the 3rd world internet. We are a young startup and soon this can be our blocker in growth.
any update?
Even if there is a way to get better tree-shaking than rollup - it would be at least nice to have the same level of tree-shaking as rollup in the shorter term. ;-) This might be important for Svelte, since multi-component Svelte npm packages seem to rely heavily on Rollup's import level tree-shaking.