-
-
Notifications
You must be signed in to change notification settings - Fork 851
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
Tree shake big bundle size #180
Comments
I'm seeing a similar result with webpack, and I assume these are core utilities + dependencies getting pulled in. However, the project doesn't have a lot of dependencies: "dependencies": {
"@popperjs/core": "^2.1.1",
"@stencil/core": "^1.17.3",
"color": "^3.1.2",
"resize-observer-polyfill": "^1.5.1"
} The If anyone can shed light on this and provide a reasonable way to optimize it, I'm all ears. In the meantime, if you want a lighter initial footprint, the lazy loader is also a good option. |
Looks like TypeScript is starting work to include the ResizerObserver types. Technically, we don't need the polyfill since browser support for that feature matches browser support for Shoelace. It's mostly being used for types now, so that will save some bytes from the core dependencies. I think the rest of this is coming from the Aside from that, I don't think there's much more to remove from the core bundle. I believe Popper is only ~7 kB and Stencil core isn't negotiable. |
Even this code that doesn't involve any components: import { setAssetPath } from '@shoelace-style/shoelace';
setAssetPath(document.location.origin + '/static/shoelace/'); adds +207 KB to Webpack bundle size 🤯 Interestingly: I'm a complete noob when it comes to JS code compilation / optimization. I really hope someone knowledgeable about this matter can help this awesome project. |
So i just found out today you can use the minified version above with Webpack. you have to add this as a Webpack loader: https://www.npmjs.com/package/@open-wc/webpack-import-meta-loader And then once you have the import-meta-loader, you can do:
and now you can use web components! You dont even have to define anything. |
and what about the size? |
Bundles are still not great. With with the recommended: import * as shoelace from defineCustomElements()
shoelace.setAssetPath(document.currentScript.src)
shoelace.defineCustomElements() im getting 979kb parsed, 198kb gzipped. |
I'm using Shoelace with Svelte (Rollup config). The starter Svelte template is around 20kb. I add this
and it goes to 390kb. If I then add these two lines to make it actually work
it goes to 470kb. ? |
Analyzing the few dependencies Shoelace has:
So realistically the dependencies only account for a small percentage of these bytes. I wonder if there are additional optimizations that can be made through webpack (or whatever bundler you choose to use) when importing the custom elements bundle. |
I don't know why I didn't think of this before, but the Animista animations that come bundled with the animation component are ~200KB. 😳 I think dropping them from the default bundle and providing them as an opt-in import will be better. There will still be ~80 animations from animate.css which seem to be more generic and common. I suspect for some reason these imports are contributing to this, so we could see a nice drop from this change. Edit: this has been fixed. View the discussion |
Removing the animation component is a good move, but the root of the problem is that the animation component should not have been included into bundles which do not import it. E.g., people should be able to just use sl-button without importing the code for all the other components. Tools like rollup can't tree-shake the modules exported by this library, because they are all concatenated together dist/custom-elements/bundle/index.js. I have an idea on how to make this work, and will take a stab at it in the next few days. |
Tree shaking is not working with esbuild, an extremely fast bundler: $ echo "import {SlBadge} from '@shoelace-style/shoelace'" | npx esbuild --loader=js --bundle --outfile=out.js
1 warning (can be ignored!)
$ ls -lh out.js
-rwxrwxrwx 1 foo foo **367K** Feb 18 13:44 out.js Looking at the content of out.js:
at the end. The rest of it is pretty much intact. esbuild: 0.8.44 (possibly related?? esbuild/#175) |
The culprit with esbuild seems to be that shoelace components are extending HTMLElement. I've opened an issue for esbuild to tree-shake known globals. Hopefully it can be addressed soon. As possible work-around, wrapping the class definition in a PURE function in
|
I'm working on an experimental build using Shoemaker and esbuild that resolves this. The end result is a collection of ES modules that are properly tree-shaken and split into chunks. The nice thing about this is that the same bundle can be served from a browser and into webpack/Rollup/etc. I'll post more details once I get a bit further with it. |
This has been resolved in beta 28 which no longer uses Stencil. The new dist contains a collection of ES modules so you can load everything, cherry pick components, or import with a bundler. Part of the solution was adding the |
@claviska so now what's the difference in size? |
It depends entirely on what you import, whether you use Feel free to run additional tests and post an update for the community if you want. |
The original example before minification/gzip: import { SlButton } from '@shoelace-style/shoelace';
SlButton.register();
// Rollup - 37.9 KB
// webpack - 109 KB Of course, not all of this is button code. You're getting the bundler's boilerplate and shared chunks that button requires (like the renderer and Shoemaker), but these are only incurred once. |
|
I'm trying the amazing Shoelace for the first time today.
I'm working on a project with Rollup.
Everything works and is amazing.
One thing I don't like though.
Just adding the following lines of code to my project increases it by 232 KB (from 747 KB to 979 KB) javascript side only.
If I use this instead it increases by 383 KB (from 747 KB to 1130 KB).
As you can see from the images we have
@stencil/core/internal/client/index.js
of ~ 16 KB. Is it really needed?Is it really necessary to have those 232 KB all together? Can we tree-shaking?
The text was updated successfully, but these errors were encountered: