lit / lit-element

LEGACY REPO. This repository is for maintenance of the legacy LitElement library. The LitElement base class is now part of the Lit library, which is developed in the lit monorepo.
https://lit-element.polymer-project.org
BSD 3-Clause "New" or "Revised" License
4.49k stars 319 forks source link

Provide release without support for non-evergreen browsers #612

Closed jhpratt closed 2 years ago

jhpratt commented 5 years ago

A project I'm working on will only support the last 2 versions of evergreen browsers, so I don't need any features specific to IE11 or older versions. Is it possible to have a release (even a branch would suffice) that has those blocks of code removed? This will reduce the overall size of LitElement, which has consistently grown recently.

blikblum commented 5 years ago

Such version of lit-html would be important also

jogibear9988 commented 5 years ago

I also think, many will provide their web apps only for the last 2 or 3 Versions of the current browsers (and no IE). Such a release would be nice!

LarsDenBakker commented 5 years ago

What sort of file size reduction are expecting from removing support?

jogibear9988 commented 5 years ago

don't know, but why should I include them when not needed. I do a big Visualization system with polymer 2 arm. I plan to switch to lit element, and for performance matters. I've pages with over thousand custom elements, and so also small reduces in size and speed matter.

And it's a page only used inside companies, so I can say, nobody uses other browsers we allow, and if so, it's okay when it does not work.

jhpratt commented 5 years ago

@LarsDenBakker I'm not entirely sure. I believe a nontrivial portion of lit-html/lit-element's code is to add support for browsers that don't support template elements, modern DOM APIs, and similar. As far as I know, the only thing explicitly excluded is a full WebComponents polyfill. The checks and branches for the polyfill are still present though, which aren't necessary if we know we're not using it. My browser choice certainly isn't out of the ordinary.

jhpratt commented 5 years ago

FWIW I recently switched away from Lit Element in favor of my own syntax and Babel plugin, in large part because of the size of this library. As a bonus, my plugin/syntax can statically determine a large portion of the changes at build-time.

If I need polyfills, that's on me to provide them. I don't believe the Lit Element should be providing them at all. The only thing that's happened was the removing of the performance label by someone who has extremely little activity on GitHub and appears to be in no way connected to this project officially.

After four months this issue has received no discussion whatsoever. In that time I was able to create a functional plugin that handled a large portion of what Lit Element can do, and do so at build-time rather than runtime and provide for smaller files.

Is this really such a big ask? Only three issues have more +1s than this:

Of the latter two issues that would affect code, both are marked as low severity, while this is medium and at +10. If wanted, I can go through the existing code for Lit Element and roughly determine what could be cut out, giving an approximate size savings; it would be by no means exact, but would give a general idea.

On a semi-related note, why was the performance label removed? Unused code absolutely affects performance; it still needs to be parsed, compiled to machine code, and ultimately not used at all.

justinfagnani commented 5 years ago

@jhpratt that's great that you've been able to create your own library. That's the promise of web components in action.

We have this marked as medium priority and I hope we'll get to it, though it'll very unlikely be with a separate build, as we strongly want only one build of each of our libraries, but via a build-tool plugin that replaces some imports, like shady-render from lit-html.

jogibear9988 commented 5 years ago

what if I use the library without a build run (as we do). we explicitly only support new browsers (so no IE, no EDGE) and I also would like to see a minimalistic version without polyfills

jhpratt commented 5 years ago

@justinfagnani Surely a build tool plugin could be used to provide multiple releases automatically? I know a number of libraries already do this for ES6+ and ES5 releases (which amounts to a separate file in the dist folder).

As @jogibear9988 said, not everyone has a build step. It would be ideal to just be able to <script type='module' src='https://yourcdn.com/lit-element'></script> and call it a day, knowing that no unnecessary code is being included.

justinfagnani commented 5 years ago

The problem with multiple isn't the effort, it's the existence of the multiple builds in the first place. If one library uses one build and another library uses a different one, then you get duplication, indexof breaks, etc.

We strongly prefer to ship single-source-of-truth modern JS, and let applications build as needed.

jhpratt commented 5 years ago

We strongly prefer to ship single-source-of-truth modern JS, and let applications build as needed.

To me, this indicates that you (at least personally) agree with my opinion that polyfills should be provided by the user of the library, no?

I'm not a huge fan of multiple builds either, but forcing a polyfill onto everyone, even when I know I won't need it, is useless at best.

There's a significant portion of Lit Element & Lit HTML that's the polyfill and checks for support. In the app I am building, I don't care about IE, which is what most (all?) of the polyfills are for. A growing number of people are no longer supporting IE, as I'm sure you're well aware.

Not to be rude, but it certainly seems like you're in the minority here. There's very much a demand for Lit Element without the polyfills present. That would obviously be a breaking change, but people seem to want it.

LarsDenBakker commented 5 years ago

I hope that everyone appreciates the fact that we're discussing reducing the size of a fully featured library like lit-element from 6.8kb to ~6-5kb. That's quite a milestone in front-end development :)

Perhaps it's possible to create a separate 'register' module which can be imported by an application which needs to support legacy browsers, and just registers/overwrites hooks in LitELement to use things like shady render. You can use that without build tools as well. This can also be useful when creating multiple outputs of an application with different browser targets.

jogibear9988 commented 5 years ago

We strongly prefer to ship single-source-of-truth modern JS, and let applications build as needed.

If we should use a build step everytime, why was "ES6 import" support natively implemented in the browser? I firstly used polymer, cause of not requireing a build step.

And when the non relative imports are natively supported (as said in a IO talk a while ago) none will be needed

logicalphase commented 5 years ago

When did Polymer not require a build step?

jogibear9988 commented 5 years ago

polymer2 ? never I think

polymer3 ? none if you use the polymer webserver (or our own wich also rewrites the imports).

also in electron you could use a custom protocol handler so you could directly load non relative es6 imports.

logicalphase commented 5 years ago

Polymer 2 relied on polymer-cli and it's tools to build it. Polymer 3 as well.

LitElement has like 0.5 kb worth of checking code, which prevents having to add it to the polyfills, but those checks mainly degrade gracefully like in the case of Constructable Stylesheets, etc.

I don't disagree that what you want is where we're all headed, but as someone who isn't building for IE11 I'm not worried about the state of the release. We'll get there.

jogibear9988 commented 5 years ago

if you used polymer2 in chrome, you don‘t needed a build step for your app. we never used it.

LarsDenBakker commented 5 years ago

Import maps are already behind a flag in chrome, with that you dont require a build step either.

You can use shims polyfills for import maps on older browser just like you had polyfill html imports.

If you are not doing any kind of builing I dont see why you care so much about shaving off 2kb. Id be really surprised if that has any impact on your performance.

Of course it is better to not include it, but here are serious downsides to consider as well.

logicalphase commented 5 years ago

Yes, you can do it, but aside from intranet or electron or snap apps, I don't yet think I'd want to go to production without accounting for how many bytes I'd be pushing to a screen just to not use roll-up and Babel to optimize it . I know we're close, but I wouldn't recommend running without a build step in all but edge cases right now. Just my thoughts, and you know where that can lead to 🤯

jogibear9988 commented 5 years ago

Yes, but you see, it depends on the use case.

So it would be nice, if somemone would like to support IE10 or others, he could include the polyfils, but it is no must.

CaptainCodeman commented 5 years ago

For everyone thinking that import maps are some panacea that will solve world hunger or at least mean "no build", I think you may have to prepare for some disappointment. If you are loading lots of little files, and it's a cascade of dependencies, then the latency will quickly add up and make things s-l-o-w.

Yes, I know, "http/2 server push all the thingz!" ... so now you need more hosting support and, well, a build step to generate all the manifests or whatever is going to decide what to push. Oh, and you've figured out how to not over push using Cache Aware Server Push (CASPer) ... right?

Bottom line: I don't think import maps are going to solve much other than for little demo examples. Beyond that you are going to be much better off having a build and even with import maps, you still have a build step to generate them whether you want to admit it's a "build" or not.

A decent build is really not complicated and takes a minuscule amount of time to run but you can still pretend you don't have one during development by making the build happen as server middleware instead.

I don't want to have my production app loading 101 copies of Google's / Polymer's copyright notice, a bundled app is always going to win.

Back to the subject ... it's best practice to NOT include polyfills, there's a comprehensive article about it here: https://www.w3.org/2001/tag/doc/polyfills/

jogibear9988 commented 5 years ago

yes, but for example I don‘t want a build to be needed during development. And a build is not always as easy or fast. In our solution a build using the polymer-cli taks about 25minutes.

jogibear9988 commented 5 years ago

And how do I do a build if I load customer modules wich are not build (cause we have only one release for all customers) and this modules also es6 import files removed in the build...

CaptainCodeman commented 5 years ago

And a build is not always as easy or fast. In our solution a build using the polymer-cli taks about 25minutes.

A 25 minute build means something is seriously wrong IMO. Polymer CLI isn't a great example as it rarely seemed fast but I don't think a faulty build process is a legitimate argument against builds. "I have a car that won't go, therefore cars don't work" is faulty logic.

how do I do a build if I load customer modules wich are not build

A build doesn't mean you can't still import things that you don't want to include in the build. As I said, you can just do the bare import specifier transforms using middleware during development to pretend there is no build.

Personally, I think it's a mistake and it's far better to have a consistent process during development and deployment. Typically, you don't do the full process for development, leaving minification for example to staging and production use, but it helps if you can run the exact same code that you'll be deploying in the exact same way locally.

jhpratt commented 4 years ago

@justinfagnani Why the "needs discussion" label? So far in this thread it's basically been unanimous.

CaptainCodeman commented 4 years ago

I don't think we've really discussed how or even exactly what, we've just argued for why.

Personally, I'd love the option to not include polyfills as I prefer to load those myself and I don't care about IE at all. Having multiple versions of lit-html and lit-element (with and without support) would definitely cause issues - everything should import the same thing. So maybe an approach would be to provide some 'compat' file that could be loaded first by those who want IE support and appropriate hooks or default no-op calls used so the single version imported will operate regardless.

But unless there's worthwhile savings to be gained, it maybe just not worth the effort or at least priority over other things.

justinfagnani commented 4 years ago

@jhpratt unanimous among the commenters on a thread doesn't mean much. It's a self-selected group and doesn't include much of the Polymer team itself.

We still need to discuss if:

  1. If it's even worth doing something here. The cost of the shady-render code in lit-html is pretty small in the grand scheme of things.
  2. The consequences of doing something. The ShadyCSS integration is relatively transparent in most cases, and the benefit is that LitElement components are likely to be IE11 compatible. Depending on the solution, like with @CaptainCodeman's campat-file idea, we could have default IE11-incompatible components that otherwise would have worked fine.
  3. Whether we need to do that thing. Many build tools / bundlers already include options to replace modules, and all that needs to be done here is to replace the import of lit-html/lib/shady-render.js with lit-html.
  4. What approach we take if we do something. That could vary from a build-time tool to do import replacement, to trying to move most of the shady-render code into ShadyCSS itself so that the hooks in lit-html are smaller.
  5. Whether this resolves itself naturally in an upcoming breaking change (to be clear, there isn't one planned yet).
chase-moskal commented 4 years ago

hello folks, just thought i'd chime in with a couple thoughts

  @justinfagnani: Many build tools / bundlers already include options to replace modules, and all that needs to be done here is to replace the import of lit-html/lib/shady-render.js with lit-html.

for those using import maps (pehaps via es-module-shims) — we can easily heed the above advice via import maps specifier remapping — this should allow us to avoid the polyfills :+1:

  @justinfagnani: Whether this resolves itself naturally in an upcoming breaking change (to be clear, there isn't one planned yet).

perhaps we could add a new lit-element.modern.js entrypoint which avoids polyfills without a breaking change — or alternatively embrace the breaking change and create lit-element.legacy.js?

i'm sure everyone would agree that an ideal architecture would make the above possibilities trivial

cheers friends, :wave: chase

jhpratt commented 4 years ago

Any updates on this? The issue has been open for over a year.

jhpratt commented 4 years ago

Ping @justinfagnani for an update.

kevinpschaaf commented 2 years ago

Closing, as a major feature of Lit 2 was moving virtually all non-evergreen support into a separate polyfill-support module. Read more in https://lit.dev/docs/tools/requirements/#polyfills.