24
loading...
This website collects cookies to deliver better user experience
<my-counter>
Web Componentgzip | |
---|---|
original by WebComponents DEV | 476 B* |
Svelte | 1884 B |
refactored | 355 B - savings: 25% |
optimized | 339 B - savings: 29% |
<file-size>
Web Component reports it is 476 Bytes.JavaScript
Tab in above JSFiddle.Template literals are great, but they suck up bytes, as meaningless white space and \n
newlines are still included in the minified file.
no need for a createElement('template')
when we only want the innerHTML once
template/content should not be added in the connectedCallback (as it can run multiple times)
super()
sets and returns the this scope
attachShadow()
sets and returns this.shadowRoot
so everything can be chained:
constructor() {
super()
.attachShadow({ mode: 'open' })
.innerHTML = "<style>*{font-size:200%}...
no need for a MyCounter class definition when it is used only once
customElements.define('my-counter', class extends HTMLElement {}
Nearly all of the 51 examples use inline event handlers (notation).
render() {
return html`
<button @click="${this.dec}">-</button>
<span>${this.count}</span>
<button @click="${this.inc}">+</button>
`;
}
Then we can do that as well
inc()
and dec()
methods on the element (which libraries do for you under the hood)id
references on the buttons are no longer needed
<button onclick="this.getRootNode().host.inc()">
<button onclick="this.getRootNode().host.dec()">
The Component uses shadowRoot to encapsulate styles and content. The id
on <span id="count">
is not required because we can target the only <span>
that exists in shadowDOM
All the refactored connectedCallback
does is set the span innerHTML to 0
connectedCallback() {
this.update(this.count);
}
Set the default 0 in HTML, and the connectedCallback is no longer required
"<span>0</span>"+
remove not required white space and ; from CSS
remove not required quotes from HTML attributes, because the Browser will add them
<button onclick=this.getRootNode().host.inc()>
<button onclick=this.getRootNode().host.dec()>
customElements.define("my-counter", class extends HTMLElement {
constructor() {
super()
.attachShadow({ mode: "open" })
.innerHTML =
"<style>" +
"*{font-size:200%}"+
"span{width:4rem;display:inline-block;text-align:center}" +
"button{width:4rem;height:4rem;border:none;border-radius:10px;background-color:seagreen;color:white}" +
"</style>" +
"<button onclick=this.getRootNode().host.dec()>-</button>" +
"<span>0</span>" +
"<button onclick=this.getRootNode().host.inc()>+</button>";
this.count = 0;
}
inc() {
this.update(++this.count);
}
dec() {
this.update(--this.count);
}
update(count) {
this.shadowRoot.querySelector("span").innerHTML = count;
}
}
);
The inc
, dec
and update
methods are not required, when count
is made a getter/setter
DRY (Don't Repeated Yourself) is great from a code maintenance Point-of-View. But from a delivery and performance PoV you do not want to be DRY; GZip loves repetitions
* {font-size:200%}
is applied to 2 elements only (button and span)
Setting font-size:200%
on both elements creates a larger file, but a smaller GZipped file!
(And the CSS parser has less work to do)
.count-- >
needs that extra space, to close the onclick
definition, or the minifier will add an -
escape code, adding 4 bytes.
<span>
can be replaced with <p>
no this.count = 0;
required because <p>0</p>
is the state
replacing seagreen
and white
with shorter #xxx
notation doesn't save extra bytes in this case, because the # doesn't exist yet in the code, thus requires extra GZip encoding bits.
customElements.define(
"my-counter",
class extends HTMLElement {
constructor() {
super().attachShadow({
mode: "open",
}).innerHTML =
"<style>" +
"p{font-size:200%;width:4rem;display:inline-block;text-align:center}" +
"button{font-size:200%;width:4rem;height:4rem;border:none;border-radius:10px;background:seagreen;color:white}" +
"</style>" +
"<button onclick=this.getRootNode().host.count-- >-</button>" +
"<p>0</p>" +
"<button onclick=this.getRootNode().host.count++>+</button>";
}
set count(p) {
this.shadowRoot.querySelector("p").innerHTML = p;
}
get count() {
return ~~this.shadowRoot.querySelector("p").innerHTML;
}
}
);
.innerHTML =
"<button style=font-size:200%;width:4rem;height:4rem;border:none;border-radius:10px;background:seagreen;color:white onclick=this.getRootNode().host.count-- >-</button>" +
"<p style=font-size:200%;width:4rem;display:inline-block;text-align:center>0</p>" +
"<button style=font-size:200%;width:4rem;height:4rem;border:none;border-radius:10px;background:seagreen;color:white onclick=this.getRootNode().host.count++>+</button>"
gzip | |
---|---|
original by WebComponents.DEV | 476 B* |
Svelte | 1884 B |
refactored | 355 B - savings: 25% |
optimized | 339 B - savings: 29% |