Closed kj7rrv closed 4 years ago
NOTE: the answer below is for an older verision of this library that implemented Material 2. See the update at the bottom for Material 3
Hello, unfortunately due to the nature of the global scope of customElements.define
and the fact that there cannot be two versions of lit-html
on a page, there needs to be some sort of dependency deduplication. Thus bundling our components means that we would need to bundle lit-html
and sub-components used which would cause duplication if you use multiple components that conflict. For example:
mwc-select
has a dependency of mwc-menu
and both of these have a dependency on lit-html
.
This means that if we bundle this, the bundle will have one version of each definition as well as one version of lit-html
.
Then assume you want to use mwc-menu
and then also import our mwc-menu
bundle alongside mwc-select
. This now means there are multiple definitions of mwc-menu
on the page and lit-html
on the page. This leads to:
mwc-menu
Until the polymer team creates another CDN that allows you to upload a package-json and if you do not care about bundling, I would recommend a JIT CDN such as unpkg
which supports ES modules with the ?modules
query param. e.g.
<head>
<script type="module" src="https://unpkg.com/@material/mwc-select?module"></script>
<script type="module" src="https://unpkg.com/@material/mwc-menu?module"></script>
<script type="module" src="https://unpkg.com/@material/mwc-list/list-item.js?module"></script>
</head>
<body>
<mwc-select>
<mwc-list-item></mwc-list-item>
<mwc-list-item value="apple">Apple</mwc-list-item>
</mwc-select>
<mwc-menu>
<mwc-list-item></mwc-list-item>
<mwc-list-item value="apple">Apple</mwc-list-item>
<mwc-menu>
Here is an example of unpkg working in jsbin which does no compilation.
UPDATE Material 3:
If you would like to import all of our components with one import and with fewer network requests, you can use https://esm.run and import the all.js
file. e.g.
<head>
<script type="module" src="https://esm.run/@material/web/all.js"></script>
</head>
<body>
<md-filled-select>
<md-select-option></md-select-option>
<md-select-option value="apple" headline="Apple"></md-select-option>
</md-filled-select>
<md-filled-button id="anchor">Open Menu</md-filled-button>
<md-menu fixed id="menu" anchor="anchor">
<md-menu-item></md-menu-item>
<md-menu-item value="apple" headline="Apple"></md-menu-item>
<md-menu>
<script>
anchor.addEventListener('click', () => {
menu.show();
});
</script>
</body>
followup: it is also recommended for unpkg to include the same package versions as a browser will only deduplicate modules by comparing the exact import strings. e.g.
So what you suggested would not require a build step?
On Mon, Apr 27, 2020 at 5:10 PM Elliott Marquez notifications@github.com wrote:
followup: it is also recommended for unpkg to include the same package versions as a browser will only deduplicate modules by comparing the exact import strings. e.g.
https://jsbin.com/lirufofuca/edit?html,output
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/material-components/material-components-web-components/issues/1219#issuecomment-620300671, or unsubscribe https://github.com/notifications/unsubscribe-auth/AN54XPYJJFZUHJZFV7LEIRTROYNGPANCNFSM4MQRAB2A .
correct, but out components will be unbundled and unminified
Was looking for the single @material/web@1.0.0-pre.17
CDN-hosted runtime-ready works-everywhere bundle I just knew Material Web was gonna have because Web Components! Disappointed. Disappointed that there's no single bundle. Disappointed that its shipping with a non-native dependency.
What is the likelihood of Material Web dropping lit and shipping a single bundle?
Have you tried unpkg.com and @material/web/all.js
?
<script src="https://unpkg.com/@material/web/all.js?module" type="module"></script>
<md-filled-button>No build</md-filled-button>
@asyncLiz I appreciate the response, but unfortunately that's not what developers are looking for.
This is the same problem Shoelace has, i.e. using all of Material results in a shocking 237 requests, 353kb transferred, and a page load speed (testing a blank page with a single md button) that ranges from 3 seconds up to 11 seconds (1 gigabit connection, Chrome, MB Pro).
Yes, we're in the era of lemons where it seems the more elaborate the more popular something is, like bundling components, but one of the promises of Web Components was such tooling and configuration (and headaches and latency) would go away. Material Web seems to be reinforcing expectations and tolerance for complexity.
I cringe at self-promotion, but I can't pretend there isn't a better way. Material Web could be built following similar techniques as Mdash, which is ~8kb (http://m-docs.org/#performance, about to be ~6kb in the next release) and Mdash includes 200+ utility classes when Material has none. Material is certainly a much prettier and more mature design system than Mdash, but a similar less-is-more approach to engineering and the entirety of Material Web could be had for 10-20kb in two requests.
I realize the project is well underway, but it might be worth considering some of the downsides in how Material Web has to be consumed and offering solutions.
I would recommend https://esm.run to load the all.js
package (example). It bundles per-package on the server size which unfortunately means it runs into incompatibilities when importing multiple specific components, but it works in the case when importing all.js
. Additionally, esm.run lowers the request amount down to 30, gzips down to 114kb, and will share any Lit dependencies across imports.
Additionally I'd like to discuss two topics:
Material web is much more than just styles
and
The goals of Material web
Material web is more than just styles – it's an entire set of interaction models a11y patterns. This undoubtedly will increase byte size, but these are expected by users for most UI libraries and is something that we cannot skimp on (a11y for legal reasons as well).
Some of the goals of Material web are to provide a component set that makes it easy for developers to develop with spec-compliant Material design components and principles and to do it in a manner that is maintainable for open source users and internal Google users. Both of these reasons are the reason why we do not offer utility classes:
External: we want to provide guard rails for users to stay within material spec which this specific implementation of the spec has undergone designer and a11y engineer reviews. We also want to clearly define what our support surface is (with an unsupported subclassing escape hatch).
Internal: Google is a monorepo, so whenever we make a change we have to migrate every user and their (seemingly countless) screenshot tests across Google at every single commit. Unlike a versioned repo, the onus of upgrading is on us and not each individual project doing a git update @material/web
. We have found over the years that CSS + DOM encapsulation is currently the best way to achieve this at scale as a helper class based approach means that we have to support possibly unsupported / out-of-spec use cases of our classes since we cannot enforce DOM structure (subclassing is disabled internally at google).
Also since some of us are borne from the Lit team, we really want to enable native web development and platform-based development, especially with web components. This is why we author all of our code to be used without a build system and via native ES modules, but as the current situation of the web platform falls, and as Alex Russell would likely agree with, is that bundling is a necessity for performance.
We want to have a good OOBE for buildless developers, but we currently are not over-indexing on this since at the current state of the platform is quite dismal for bundle-less performance. Additionally, there is no one-size-fits-all for the bundling situation since this is fundamentally a consumer-side concern, but we think that esm.run
could provide a good middle ground bundling w/ ESM dep imports for what you seem to be seeking, but unpkg.com
offers true graph deduplication. We also leave the door open for users that do not mind a bundling build step by simply writing our code as native ES modules.
I'd be happy to further this conversation in a GH discussion on the repo if you prefer to open one. We'd be interested in any further ideas you're willing to offer on the consumer side.
Really appreciate the offer to create a discussion thread, but I don't think that can go anywhere. Not that the Material team isn't open to ideas, it's just not realistic to make big changes to the project at this stage. Thanks though for suggesting it. Maybe we can have that discussion when Material 4 happens😁
Just for the sake of clarity, I am definitely aware that Material is more than styles, so is Mdash. They both have Web Components, with Mdash having more than that. And when I mentioned utility classes I was not suggesting Material should have them. I was just making the point that Mdash has 200+ utility classes in addition to its collection of components and it is still magnitudes smaller than Material.
For anyone interested in a version of Material that comes as a complete CDN package for probably less than 20kb, I've started such a project here
Thanks for the clarification on that point and for the constructive feedback
Is your feature request related to a problem? Please describe. Not everyone uses a build step. This is unusable without one.
Describe the solution you'd like I would like a way to use this with just CSS and JS from a CDN.