How to dynamic import web components to improve our application performance
If we’re building single-page web application with vanilla web components, we can dynamic import web components to improve the performance.
Let’s say we have a subscribe button on the page and a newsletter subscription modal will pops up should users click this button. This is a basic newsletter-modal
web components codes.
export default class newsletterModal extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.shadowRoot.innerHTML = `
<!-- component html here -->
<style>
/* component styles here */
</style>
`;
}
show() {
this.classList.add('visible');
}
hide() {
this.classList.remove('visible');
}
}
customElements.define('newsletter-modal', newsletterModal);
Here’s codes to achieve dynamic import our newsletter-modal
component. 50ms
timeout here is when show()
is called, we want the newsletter-modal to have a slide animation into the viewport. Not sure if this is a bug or I did something wrong there, but if I leave out the setTimeout
there, there is no CSS animations on that newsletter modal. Possible reason is that — just me guessing — our component is not fully ready to animate yet when show()
is called, this is such an interesting problem that I should revisit in future.
<newsletter-modal></newsletter-modal>
const button = document.querySelector('#subscribe-button');
button.addEventListener('click', (e) => {
import('./components/newsletterModal.js')
.then(() => {
return customElements.whenDefined('newsletter-modal');
})
.then(() => {
const timeout = setTimeout(() => {
document.querySelector('newsletter-modal').show();
clearTimeout(timeout);
}, 50);
})
.catch((error) => {
// your error handling here
console.error(error);
});
});
And here’s async/await
version.
const button = document.querySelector('#subscribe-button');
button.addEventListener('click', async (e) => {
try {
await import('./components/newsletterModal.js');
await customElements.whenDefined('newsletter-modal');
const timeout = setTimeout(() => {
document.querySelector('newsletter-modal').show();
clearTimeout(timeout);
}, 50);
} catch(error) {
// your error handling here
console.error(error);
}