DEV Community

Cover image for 〈file-size〉 Web Component, because size does matter
Danny Engelman
Danny Engelman

Posted on • Updated on

〈file-size〉 Web Component, because size does matter

The <file-size> Web Component

Keep a watch on how many bytes you send down the wire,
when you deliver Web Components.

<!-- Load the <file-size> Web Component -->
<script src="https://file-size.github.io/element.js"></script>

<!-- Use the <file-size> Web Component -->
<file-size src="https://file-size.github.io/element.js"></file-size>
Enter fullscreen mode Exit fullscreen mode

✔️ displays the file content-length in Bytes
(only if the server allows CORS requests and provides the header)

✔️ Displays a thermal image, showing how well the file is GZIP compressed

  • (dark)blue = repetitive strings, optimal compression
  • red = can't be compressed, one Byte used to encode one Byte

✔️ alt + click the IMG opens original source file in another Browser Tab

Optional <file-size> attributes:

  • gz - open GZthermal image by default

    <file-size gz src="https://file-size.github.io/element.js"></filesize>

  • max=[bytes] - green/red display of file content-length

    <file-size max="64000" src="https://file-size.github.io/element.js"></filesize>

    default value is 48000 Bytes because the first computer I programmed in 1979, had 48 kiloBytes of RAM; and gzthermal errors on larger files.


Tips for better compression

🤏 Online tools that can help

🤏 Look for repereperepetitions

DRY is great from a Code Maintenance and Repetitive Strain Injury Point of View

But when you deliver, you want as many repetitions as possible.

this.setAttribute("one","ONE");
this.setAttribute("two","TWO");
this.setAttribute("three","THREE");
this.setAttribute("four","FOUR");
Enter fullscreen mode Exit fullscreen mode

Compresses better (and is faster!) than:

const setAttr = (x,y) => this.setAttribute(x,y);
setAttr("one","ONE");
setAttr("two","TWO");
setAttr("three","THREE");
setAttr("four","FOUR");
Enter fullscreen mode Exit fullscreen mode

Sure, the minified file is smaller, but the compressed file is larger

But... compression is done on the whole file, so your mileage may vary!

🤏 Name you methods well

If you already have the default boilerplate code

customElements.define("file-size", class extends HTMLElement {
    connectedCallback(){}
);
Enter fullscreen mode Exit fullscreen mode

Then try to re-use those strings in your method names and properties

  • defineSize could be better than initSize
  • extendsFile could be better than addtoFile

Again, compression is done on the whole file, so your mileage may vary!

🤏 Get rid of CAPITALS

Not because they are CAPITALS, but because CAPITALS are less used in code.

Here is an example from Lit, where 7 Bytes are used to encode 7 Uppercase characters.

Changing them to lowercase would most likely save 2 or 3 bytes in this code fragment, and more in the whole file.

🤏 Use onevent listeners

prepend on to all default Events.

details.ontoggle = (e) => details.open && gzthermal();
Enter fullscreen mode Exit fullscreen mode

does the same as:

details.addEventListener("toggle", (e) => details.open && gzthermal());
Enter fullscreen mode Exit fullscreen mode

Note the difference; onevent sets/overwrites a single handler; addEventListener allows for multiple handlers.

🤏 Be careful with Strings

let html = `
    <div>
      content
    </div>
`;
Enter fullscreen mode Exit fullscreen mode

looks great in your IDE, but the minified and GZipped files will contain those totally useless EndOfLine and Space characters

AFAIK, there is no IDE command that fixes this for you; you have to do it by hand.

let html=`<div>content</div>`;
Enter fullscreen mode Exit fullscreen mode

Or use: https://github.com/asyncLiz/minify-html-literals

A good minifier will concatenate these type of String notations:

let html = `<div>`+ // my
    `content` + // comments here
    `</div>`;
Enter fullscreen mode Exit fullscreen mode

output:

let html=`<div>content</div>`;
Enter fullscreen mode Exit fullscreen mode

🤏 Be smart, hunt for longer strings

<div class="...">
<div onclick="..." class="...">
<div style="..." class="...">
Enter fullscreen mode Exit fullscreen mode

can be written as:

<div class="...">
<div class="..." onclick="...">
<div class="..." style="...">
Enter fullscreen mode Exit fullscreen mode

Pay close attention to CSS strings; a good order can save serious bytes

🤏 Know what Browsers do

Browsers do not need quotes for attributes,

unless the value contains spaces or % characters (and maybe more)

When parsing, Browsers will add quotes

<div class="fancy"> can be written as: <div class=fancy>

A space will create another attribute:

let attrs = x => `class=${className}`;
let html = `<div ${attrs("fancy style=display:none")}>`;
Enter fullscreen mode Exit fullscreen mode

outputs

<div class="fancy" style="display:none">
Enter fullscreen mode Exit fullscreen mode
<div style="font:16px Arial">
Enter fullscreen mode Exit fullscreen mode

can be written as:

<div style=font:16px,arial>
Enter fullscreen mode Exit fullscreen mode

🤏 delete the last /

Some HTML tags are selfclosing and do not need a closing slash

<area>,<base>,<br>,<col>,<embed>,<hr>,<img>,<input>,<link>,<meta>,<param>,<source>,<track>,<wbr>


Credits




Discussion (1)

Collapse
elliott profile image
Elliott

If you choose to use Template Literals, you can use this library to minify strings which already has implementations for other builders:

github.com/asyncLiz/minify-html-li...