# <Dynamic> Optimized for Elements
The question here is if we had a compiled Dynamic could we avoid needing to spread namespaced properties.
By this I mean `prop:` `on:` `use:` `style:` `class:`. These are all special edge cases that allow you to do things multiple ways. Basically override base behavior. We already don't support `use:`, `on:`, `style:`, and `class:`, so it really comes down to `prop:`. To be fair all but `use:` could be supported. `use:` would require a different API/mechanism.
The idea is that if we had a compiled dynamic element instead of a runtime one or some way to indicate that a component was just supposed to represent an element, we could avoid needing to spread these more advanced behaviors.
I think the biggest contention here is probably `<Button>` etc.. where people make elements that are just wrappers of native elements and the hope is that users can interact with them the same.
## Compiled Dynamic Element
A compiled Syntax like:
```js
function Comp(props) {
return <$:props.element name="hi" title={props.title} />
}
```
could transform into native dom instead of component changes without requiring a spread.
Something like:
```js
function Comp(props) {
return createMemo(() => {
const el = createElement(props.element);
setAttribute(el, "name", "hi");
createRenderEffect(() => props.title, v => setAttribute(props.title));
return el;
});
}
```
Basically the same code as the normal transform if it didn't clone elements. Wrap it in a memo and you are basically good to go. I guess one consequence is changing the element would cause the children to re-render. But I imagine that is the case right now. Maybe we can hoist children to not do that:
```js
function Comp(props) {
return <$:props.element name="hi" title={props.title}>
<div>{props.count}</div>
</$:props.element>
}
```
Something like:
```js
const tmpl = template("<div>")
function Comp(props) {
return (() => {
const ref = createMemo(() => {
const el = createElement(props.element);
setAttribute(el, "name", "hi");
createRenderEffect(() => props.title, v => setAttribute(props.title))
return el;
});
const el2 = tmpl();
insert(el2, () => props.count);
createRenderEffect(ref, (el) => insert(el, el2));
return ref;
})()
}
```
Only weird thing is until the component is released the children exist. Even if the `props.element` is essentially null.
To be fair Dynamic could work this way as well but I don't believe it does. It would require specific children hoisting and management.
So this definitely more optimal than what we do with Dynamic today. Supporting Component functions though would be harder because we can't use `()` in the tag so any `createElement` helper has to unwrap functions so it might not be able to tell the difference between `() => "div"` and `Comp` and just run it with no props. Similarly it would be difficult to hoist children.
## Native Extensions
The crux of this does all come down to whether people want to be able to use `prop:` on a `<Button>` component though. It makes you start thinking about native built-ins on Custom elements. Like `is`. I would in some ways love if we got rid of `<Button>` and only had `<button>` especially with things like `<a>` and `<form>` so they could be progressively enhanced even when using say Kobalte.
The problem is they need to augment props.. Like let's pretend we had a syntax to do this from the compiler.. Like we saw:
```js
<Link:a href={href()} on:click={someHandler} />
```
The `Link` would need to be able to both transform props before they were applied and add additional things on this. Sort of chicken and the egg problem. Because if our `Link` is just a prop transformer how does it add properties. Well it would still need spread logic.
I guess if the goal of it was to only return the next props the compiler could do something like:
```js
// don't pass in namespaces
const props = Link({ get href() { href() } });
const el = createElement("a");
addEventListener(el, "click", someHandler)
createRenderEffect(() => props.href, v => setAttribute(el, "href", v));
// exclude "href"
spread(el, props, ["href"])
```
The problem is what if the custom element wants to say hide/show children, remove things that are part of the passed in props. And we are supposed to deoptimize spreads anyway so that everything can be set in a single way. Having seperate render effects vs spreads gets us into all sorts of trouble. It's arguably less here because we ensure seperation. But what's the real benefit here. So we can do pass through on namespaced attributes.. like even if it spread everything else same gain:
```js
// don't pass in namespaces
const props = Link({ get href() { href() } });
const el = createElement("a");
addEventListener(el, "click", someHandler)
spread(el, props)
```
And is this worth it just to support namespaces on elements without making it a component API? I'm struggling.
I think I have to accept it can be a component API and be happy that there are so few.
## Is there a way to have fewer namespaces?
I guess the first question is do we need `on:`. Thoughts on events:
1. Delegation is absolutely necessary for Portals, and optimal Hydration techniques. So by default we delegate. But we don't have to make it not opt-out able.
2. we support array syntax for bindless delegation which is nice. The compiler handles it where it can and otherwise it is just an array object.
3. We've added objects to the `on:` which we could adopt for the normal syntax perhaps, so in the same way you can set `capture: true` you could basically view this as opting out of delegation.
However, I think the biggest awkwardness is casing. We'd need to ensure all events were cased exactly by name. Ie.. it would need to be `onclick` not `onClick`.. trying to come up rules around capitalization seems awkward as does saying that all custom events can't be cased. So my gut here is no, and since we already don't support them in spreads it isn't a big deal.
It really is just about `prop:`. Well something to think about.