Ideas for Lit 3.0 #3604
Replies: 13 comments 5 replies
-
Constructible stylesheets is must in my opinion. Some more suggestions from my side:
This is kind of tedious if multiple lit-element components are used in an application. Built-in support to manage this from inside the lit-element would be great! |
Beta Was this translation helpful? Give feedback.
-
@superflows-dev Lit doesn't do anything with slots, and it's very likely to stay that way. The behaviors you're describing are standard shadow DOM behavior and custom elements behavior and any changes there should be taken up with WICG/webcomponents most likely. |
Beta Was this translation helpful? Give feedback.
-
I would love to see more built-in UI utilities (like Angular CDK):
|
Beta Was this translation helpful? Give feedback.
-
There seems to be a handful of opt-in/pre-compile paths that could be perused, possibly without the need for breaking changes. Things that could be interesting: Template pre-compiling Support for Working in this area, it would seem that the apply path could be customizable, so that if there was a smarter place to put the styles that Support for some sort of
Expanded built-in controller support Getting started mode |
Beta Was this translation helpful? Give feedback.
-
I miss from Vue the Scoped Slots. It lets you delegate the rendering of some parts of the component using the variables given by the component. One interesting use case is Lists. The component creates the list layout and can even hide part of the list (like infinite scrolling) and delegates into the parent the display of each element. Another use case highlighted in the Vue guide is creating renderless components. This is just a bit of sugar in the code, but it is a good side effect. |
Beta Was this translation helpful? Give feedback.
-
With respect to slots, there's a nascent proposal @kevinpschaaf is working on that should address some of these use cases, see #3591. |
Beta Was this translation helpful? Give feedback.
-
Lit's update model is currently asynchronous. This provides a simple, interoperable way to efficiently render changes when properties are set (e.g The main drawback is that it means Lit element rendering doesn't exactly match how native elements update and render (e.g. input.value = 'hi' synchronously renders this value). There are a couple of ways this could be improved:
|
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
Using |
Beta Was this translation helpful? Give feedback.
-
To be honest, at this point I can't think of much further that could be improved about Lit. I'm really happy with how Lit 2.0 turned out and how it performs. For me personally, working with it is a breeze and I love the commitment to native platform APIs and the resulting simplicity. Thanks for all the great work and effort. I've found myself using reflected attributes a lot for styling and querying, but I understand that it's not fully encouraged (mainly due to limited encapsulation). While support for
Here I think that Apart from that, I'd love to see a documentation section and / or video tutorial on how to build a Lit app – in combination with lit-labs modules such as context, motion, router, etc. I think Lit is publicly still perceived as an interoperable components library (which on it's own is great), but developing an entire app with it is just as easy and could be more encouraged. |
Beta Was this translation helpful? Give feedback.
-
Splitting class MyElement extends LitElement {
// Equivalent to `@property`
@reactive
@attribute({type:Number})
count = 0;
// Equivalent to @state
@reactive
#privatePropWithNativeDecorators = 'foo';
} This also allows this use case where you want to set an attribute on host (that is reactive or not reactive) but not expose the property as a settable public property: class MyElement extends LitElement {
@attribute({reflect: true, name: 'md-list-item', readonly: true})
#isListItem = true;
} |
Beta Was this translation helpful? Give feedback.
-
Have you considered an idea of hiding protected overridable methods from public API by using Elix symbols approach? Beforeimport { LitElement, html } from 'lit';
class MyElement extends LitElement {
render() {
return html`<slot></slot>`;
}
} Afterimport { LitElement, html, $render } from 'lit';
class MyElement extends LitElement {
[$render]() {
return html`<slot></slot>`;
}
} Check out the |
Beta Was this translation helpful? Give feedback.
-
First class support for React and Nextjs, it would help make lit more popular since it would be easier to build React design system using Lit. |
Beta Was this translation helpful? Give feedback.
-
As we did well before planning lit-html 2.0 and lit-element 3.0, I'd like to start collecting ideas for what could be changed in a possible Lit 3.0.
To be really clear, there is no current plan for breaking changes, nor Lit 3.0. I just want to gather and document ideas that might require a new major version. There have been a lot of changes in the web platform in the last two years that we could possibly use that we should look at.
Also, it's important to remember that because of web components and Lit's very low-coupling between components, different versions of Lit are compatible with each other. Of course, this is not a panacea as some customers have single-version policies, and any upgrade pain is a cost sink against other development work.
This is not an exhaustive list, and some ideas in here may be bad! There's also a mix of large and small ideas, but even a small breaking change is a breaking change and should wait till the next major version.
Goals
As always our goals are to be as backwards compatible as possible, but also be smaller, faster, more standard, and more interoperable.
Platform features we could use
Possible changes
All packages
Drop IE 11 support
IE11 support is opt-in right now via the polyfill-support modules, but it costs us real time and effort in managing the CI runners for it. It would be very nice to officially drop support and not test on it aymore.
Publish ES2022 or later
This would reduce code size by letting us stop downleveling optional chaining, nullish coalescing, and logical assignment. Those expressions would get very slightly faster too.
Use native private fields
Native private fields are interesting not necessarily because of the runtime enforced privacy, but because all JS tooling knows that they're indeed private and what the visibility scope of the privacy is (the class body). Because there is no way for an expression outside of the class body to access a private field, they can be very safely renamed. This could drastically simply our build setup since we won't have to configure Terser to understand our naming conventions around what is renameable. It could even allow us to publish unminified sources again, since any modern Terser config would be able to apply good minification to our sources.
Use
Object.hasOwn()
It's a few less characters, and can be torn off to be more minimizable:
ReactiveElement and LitElement
Use native decorators
Native decorators (aka Stage 3 decorators) are well on their way to being implemented. They're in Babel and recently mostly landed in TypeScript.
Native decorators would allow us to deprecate our non-standard decorators, and eliminate the syntax differences between JavaScript and TypeScript usage.
We can add native decorators without breaking changes, but we could also simplify things by removing other ways of declaring reactive properties:
properties
blockcreateProperty()
APIaddInitializer()
These could be disruptive changes, so would need a lot of deliberation.
Reorganize decorators
Right now
@property()
has a lot of options. Many are related to a property being an attribute. We might be able to get some simplification and clearer guidance if we split those up:@property()
creates a reactive property, and it's only a JS property that triggers an update when it changes.@attribute()
creates an observed attribute, and optionally reflects@state()
could go away, as it's just@property
.We could also try to guide usage a bit more around input and output properties. Generally a property should be used as input or output but not both. We could replace
@property()
with@input()
and@output()
decorators. Linters could warn if an element is writing to it's own@input()
, and we could make an internal-only setter API for@output()
s.Stop reflecting initial values
Native elements do not spontaneously sprout attributes. Lit elements currently do for reflecting properties because we can't tell what is an initial value vs what's set externally. Native decorators may let us do that so we can reflect only on external values.
Assume native Constructible Stylesheets
This would let use simplify the CSS tag management code a little. We would need a great polyfill, however. It's also not a lot of code.
Make lifecycle more SSR friendly
We could make some lifecycle methods client-only and recommend moving client initialization into client-safe methods, etc.
lit-html
Land the template compiler
The template compiler pre-processes templates so that prep work doesn't have to be done at first-render time. We think it can improve first-render performance by 15-20%
What it doesn't do now is reduce code size. About 1k of lit-html is used to process templates, and since
render()
can take regularTemplateResult
s as well asCompiledTemplateResult
s, a minifier or bundler has to keep that code around. We could vend a function likerenderCompiled()
that doesn't call into the main code path and allowsrender()
to be tree-shaken away.Add spread operator and "attribute templates"
Spread ended up being difficult to add to lit-html because it introduces the possibility of collisions on binding names, and takes some effort to not introduce a dependency on the ordering of property changes on rendering. We may be able to revisit spread and make subtle breaking changes if necessary.
If we can do spread, then we can also do
attr
templates - which contain just attribute, property, and event bindings, but no host tag or child content.Use WeakRefs for async directive detachment
Depending on what async directives do on disconnection, they make be able to use finalizer-timing to clean up other resources and so we could remove the complexity around notifying directives of disconnection from the DOM.
Beta Was this translation helpful? Give feedback.
All reactions