Say I have a Web Component defined like this:
// web-component.js
export class WebComponent extends HTMLElement {
template = '/path/to/template.html';
tmpl = {};
constructor() {
super();
}
async connectedCallback() {
const html = fetch(this.template).then(response => response.text());
this.doSomething(await html);
}
doSomething(html) {
console.log(html);
}
}
document.addEventListener('DOMContentLoaded', customElements.define('web-component', WebComponent));
A template file like this:
//template.html
<template id="web-component">
<h1>Text Goes Here</h1>
</template>
And a web page like this:
//index.html
....
<head>
<script type="module" src="/path/to/web-component.js"></script>
</head>
<body>
<web-component>Foo</web-component>
<web-component>Bar</web-component>
<web-component>Baz</web-component>
</body>
....
The web browser is making three http requests to fetch the same template file. I want to store the html from the template file somewhere on the client so I'm only making a single http request.
I tried this:
async connectedCallback() {
const existing_template = document.body.querySelector('#web-component');
console.log(existing_template);
if (existing_template) {
this.doSomething(existing_template);
} else {
const html = fetch(this.template).then(response => response.text());
this.addTemplateToWebPage(await html);
this.doSomething(await html);
}
addTemplateToWebPage(html) {
const tag = document.createElement('body');
tag.innerHTML = html;
document.body.appendChild(tag.querySelector('template'));
}
But existing_template is always null, so I'm still making unnecessary http requests. I also tried this, with the same result:
connectedCallback() {
this.doSomething();
}
async doSomething() {
const existing_template = document.body.querySelector('#web-component');
console.log(existing_template);
if (existing_template) {
this.doSomethingElse(existing_template);
} else {
const html = fetch(this.template).then(response => response.text());
this.addTemplateToWebPage(await html);
this.doSomethingElse(await html);
}
}
doSomethingElse(html) {
console.log('doing something else');
}
How can I do this so I only have a single http request when calling the same template?
my-component.js
class MyComponent extends HTMLElement {
static file = '/path/to/template.html';
static template = false;
constructor() {
super();
if (!MyComponent.template) {
MyComponent.template = MyComponent.fetchTemplate();
}
}
async connectedCallback() {
const tmpl = await MyComponent.template;
this.tmpl = tmpl.cloneNode(true);
console.log(this.tmpl);
}
static async fetchTemplate() {
return await fetch (MyComponent.file)
.then (response => response.text())
.then (txt => {
const frag = document.createRange().createContextualFragment(txt);
return frag.querySelector('template').content;
});
}
}
template.html
<template id="my-component">
<h1>Text Goes Here</h1>
</template>