4

I can't seem to grasp or find out why you should use HTML templates with web components when you can simply define the HTML inside the web component (shadowRoot.innerHTML).

What is the benefit of creating a template and cloning it inside the web component? I can see there being a reason if two web components share the same HTML but beside that I have no idea.

Is there something fundamentally important that I'm missing?

Sridhar Ratnakumar
  • 81,433
  • 63
  • 146
  • 187
Billy
  • 69
  • 1
  • 6

2 Answers2

6

Yes, too many blogs do document.createElement("template") where an .innerHTML will do the same ... and with less code ... and faster.

Note, Templates are not tied to the Custom Elements API or shadowDOM.
Each of the 3 Web Components technologies can be used without the other.

Templates

Templates are great when you want to store re-usable content in the HTML Document, because it does not get parsed.

In the old days we would use a <div hidden> and pray its contents did not affect the rest of the page.

Just like the old days you can read the Template.innerHTML and do whatever you want with the String value.

More modern approach is to clone the Template, just be aware that .content property is required, and you get a Document-Fragment value in return.

<template id="MY-TEMPLATE">
 <article>
  ...
 </article>
</template>

document.getElementById("MY-TEMPLATE").content.cloneNode(true)

Templates & shadowDOM

When you have Custom Elements with shadowDOM, Templates are great to define that shadowDOM content.

Why so many developers want to do HTML-in-JS and CSS-in-JS I don't understand.
If you have an HTML document, store the content there, way easier to edit.

<template id="MY-ELEMENT">
  <style>
    /* style shadowDOM here */
  </style>
  <slot></slot>
</template>

All your MY-ELEMENT then needs to do is:

super()  // or this when done in the connectedCallback
  .attachShadow({mode: 'open'})
  .append(document.getElementById(this.nodeName).content.cloneNode(true))

Performance

an innerHTML String with HTML content will get parsed for every usage.

A template is parsed once, so does save on CPU cycles, when you use the same template many many multiple times

Usage

My personal preference is to keep as much HTML (and CSS) inside <TEMPLATEs> in HTML as possible. Only when I want my components not to be configurable I use static HTML in JS, with .innerHTML, not .createElement("template") for code brevity over (minor) performance gain

Only in SDWCs (Self Destructing Web Components) that need to load/execute ASAP I contain everything inside the Component:

customElements.define('my-head',class extends HTMLElement{
  connectedCallback(){
    // generate <HEAD> content, <SCRIPTS> and <STYLE> CSS-in-JS here

    this.remove();

  }
});

Danny '365CSI' Engelman
  • 16,526
  • 2
  • 32
  • 49
  • Danny you have helped me more than you will ever know to learn web components. You are a Web component hero on stack overflow. I really like your style and outlook. I was looking at litelement (since most blogs and videos point in that direction), but after seeing one of your comments, I am sticking with vanilla JS. – run_the_race Nov 07 '21 at 13:39
  • I agree and am using templates too, but the problem is how does one bundle the HTML with the JS now that `HTML imports` have been depreciated. Keeping it all in the JS (although slower) has the advantage of portability – run_the_race Nov 07 '21 at 13:42
  • In JS you define HTML as text strings – Danny '365CSI' Engelman Nov 09 '21 at 18:48
  • I have been wondering about the deliverability too. @Danny'365CSI'Engelman Can you expand on that last comment? Do you mean you create a multi-line string in you JS file (something line `var componentTemplate = "")`? This does seem to be like HTML-in-JS though, which I take from you reply, you are not a fan of. – tbrlpld Jul 18 '23 at 04:45
0

What is the benefit of creating a template and cloning it inside the web component?

Speed. Parsing a string and generate internal html objects takes some extra time compared to just cloning nodes. If the web component is used in many places and each will parse string and convert it to html objects. Compare that with just parsing once.

tutorial about web components

Per Ghosh
  • 449
  • 5
  • 10