-
- Notifications
You must be signed in to change notification settings - Fork 4.7k
Closed
Labels
Description
Describe the problem
when hydratable: true
, svg_element
function is output even if no svg element in a component.
For example, if you have a simple component like the following:
<main> <h1>Hello world!</h1> </main>
compiled:
function svg_element(name) { return document.createElementNS("http://www.w3.org/2000/svg", name); } ... function claim_element(nodes, name, attributes, svg) { return claim_node( nodes, (node) => node.nodeName === name, (node) => { const remove = []; for (let j = 0; j < node.attributes.length; j++) { const attribute = node.attributes[j]; if (!attributes[attribute.name]) { remove.push(attribute.name); } } remove.forEach((v) => node.removeAttribute(v)); }, () => (svg ? svg_element(name) : element(name)) ); }
minified(formatted):
function m(t, n, e, o) { return _( t, (t) => t.nodeName === n, (t) => { const n = []; for (let o = 0; o < t.attributes.length; o++) { const r = t.attributes[o]; e[r.name] || n.push(r.name); } n.forEach((n) => t.removeAttribute(n)); }, () => o ? (function (t) { return document.createElementNS("http://www.w3.org/2000/svg", t); })(n) : s(n) ); }
This isn't a bug (because it works fine), but it does increase the bundle size slightly.
Describe the proposed solution
Pass svg_element
function, instead of 1
.
- src/compiler/compile/render_dom/wrappers/Element/index.ts
get_claim_statement(nodes: Identifier) { const attributes = this.attributes .filter((attr) => !(attr instanceof SpreadAttributeWrapper) && !attr.property_name) .map((attr) => p`${(attr as StyleAttributeWrapper | AttributeWrapper).name}: true`); const name = this.node.namespace ? this.node.name : this.node.name.toUpperCase(); -const svg = this.node.namespace === namespaces.svg ? 1 : null; +const svg = this.node.namespace === namespaces.svg ? '@svg_element' : null; return x`@claim_element(${nodes}, "${name}", { ${attributes} }, ${svg})`; }
- src/runtime/internal/dom.ts
-export function claim_element(nodes: ChildNodeArray, name: string, attributes: { [key: string]: boolean }, svg) { +export function claim_element(nodes: ChildNodeArray, name: string, attributes: { [key: string]: boolean }, create_element: (name: string) => Element | SVGElement = element) { return claim_node<Element | SVGElement>( nodes, (node: ChildNode): node is Element | SVGElement => node.nodeName === name, (node: Element) => { const remove = []; for (let j = 0; j < node.attributes.length; j++) { const attribute = node.attributes[j]; if (!attributes[attribute.name]) { remove.push(attribute.name); } } remove.forEach(v => node.removeAttribute(v)); return undefined; }, -() => svg ? svg_element(name as keyof SVGElementTagNameMap) : element(name as keyof HTMLElementTagNameMap) +() => create_element(name) ); }
Alternatives considered
Also, element
function is output even if the component has only svg elements.
If it is important to improve that as well, more changes are needed.
Importance
nice to have