Deep dive into WebComponents

The native way to make dynamic component-based web apps.

What are WebComponents and why should I use them?

WebComponents give you the possibility to create new HTML tags.

They aren’t new. They in fact were firstly announced back in 2011 and got very popular with the launch of Polymer, in 2014. The main issue was about the browser support, but nowadays, they have been natively implemented on all modern browsers.

The idea behind WebComponents is part of the success of many modern web frameworks: making elements that could be used multiple times. Just get a look at webcomponents.org to see what I mean.

WebComponents can be considered as the native equivalent to React, Angular or Vue.js. This way, you don’t have to include a huge amount of lines of code to make your web app work. The code is already built in the browser and ready to use, without worrying about downloading and executing tons of JavaScript.

This is a size comparison between the most common web frameworks:

  1. Vanilla Custom Elements → ready to use
  2. LitElement → ~5kb
  3. Vue.js → ~30kb
  4. React.js (with React DOM) → ~110kb
  5. AngularJS → ~160kb
  6. Angular → ~550kb

Our first web component!

What is the Shadow DOM?

Let’s talk about this line of code:

This is the reason why Custom Elements stay re-usable during the development of various web apps. You can consider the Shadow DOM as a sub-DOM that can’t be interfered by the root DOM.

For example, if we import a CSS file in our HTML file, the rules written in it won’t simply be considered by the Shadow DOM.

A real world example could be the social media buttons, like Twitter’s Tweet button or Facebook’s Like button. They must be independent and the styling of the page should not interfere with the styling of those elements.

The “mode” property can be set to “open” or “closed”.
When it’s set to open, the shadow root can be accessed by the “shadowRoot” property of the HTMLElement. Otherwise, if it’s set to “closed”, the “shadowRoot” property will be null. Note that it’s easy to circumvent that, as you’ll still be able to access to the shadow root using the “_root” property of the HTMLElement.

Making our code easier to write and more optimized

Making Custom Elements optimized can be hard. That’s where LitElement kicks in.

LitElement is part of the Polymer family and makes Custom Elements development easier with a set of handy features that will help us to write cleaner code and optimize performance.

Our first web component… with LitElement! 🔥

What is ‘<script type=”module” …>’?

It’s the way we tell the browser we’re using ES Modules.
In practice, when a JS file imports some other file (such as a library, a style sheet, an image, or whatever else…), it must be imported with the type=”module” attribute. In our case, we needed it to import LitElement directly from our clock-lit-element.js file.

The “properties” method

This method allows us to declare the properties of our element. All of them must have the a “type” property, that can be “String”, “Array”, “Object”, etc…Properties can be declared as attributes. They will be automatically converted to object properties. For example:

Will automatically set the “name” property to “Steve”.

Every time one of the properties changes, it will call the render method and will update the content efficiently, updating only what is needed, not the whole component.

The “styles” method

The “styles” method gives us a cleaner way to declare the CSS of our component.

The function can also return an Array, which is useful when we want to share CSS code with multiple elements.

For example:

The “render” method

This method generates the HTML structure of our Element.

It must return a value generated with the “html” function. To describe how it works, we must introduce the “string literals”, a new feature which is part of the ES6 features set. They are simple strings that must be declared with the backtick character.

Those kind of strings are great when you need to concatenate multiple strings.
For example:

When a function is called without the parenthesis and with a string literal (like html`<h1>Test</h1>`), JavaScript passes the function two parameters, the static strings and the dynamic generated values.

LitHtml is able to generate optimized HTML, updating only things that needs to be updated.

Communication between Elements

To make Elements communicate, we have two options:

  • Use the element instance and call its methods.
    This option is only available when making operations on child elements.
    Example:
  • Dispatch a global event.
    Example:

Thanks for your attention!

Here’s the public Gist link if you want to get a look. 😊

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store