What to know about the dynamic instantiation of LWCs

Until Winter '24, the only way to dynamically create Lightning Web Components (LWCs) was via Aura Components. Fortunately, that will no longer be the case going into Winter '24. Yes, you heard it right!

What to know about the dynamic instantiation of LWCs
Table of contents

Until Winter '24, the only way to dynamically create Lightning Web Components (LWCs) was via Aura Components. Fortunately, that will no longer be the case going into Winter '24. Yes, you heard it right!

This feature update is undoubtedly one of the most beloved by Salesforce Developers in the community.

Why or why not create LWCs dynamically?

Some folks in the community may say, "It's a best practice not to create LWCs dynamically." That's true to some extent, but not always.

Let us first consider why you may not want to import LWCs dynamically:

Performance overhead

Since the component is being dynamically instantiated, the framework cannot load all the modules (including the modules of child LWCs ) that are part of the component. The framework requires a network round trip to fetch all the modules (unless already stored in the browser cache). So, the more dynamic LWCs you have, the more network trips will result in a significant performance lag.

Risk of non-statically analyzable imports

Future framework optimizations can enhance code where dynamic imports are statically analyzable. So, you're at a disadvantage if you're having non-statically analyzable imports.

Knowing the downsides of dynamic LWC instantiation, you might be curious why it might be a bad idea to instantiate the LWCs statically. Let's start by stating the apparent advantages of dynamic LWCs:

Flexibility and customization

One of the primary advantages is the amount of flexibility and customization it brings to the overall solution.

Avoid loading large and unique use-case modules

This advantage may not look huge at the surface, but if you have an LWC that is composed of multiple static child components – with each child component having significantly sized JavaScript modules – your LWC can take as long as 10-15 seconds to load because of the import of a large number of modules.

Ultimately, realizing what fits best for your use case is essential. Remember, just because you can doesn't mean you should.

How to create an LWC dynamically?

Before you start, you must ensure that Lightning Web Security is enabled in your org to create LWCs dynamically.

Go to:

  • "Setup"
  • "Quick Find" box
  • Search "Session"
  • Select "Session Settings"
  • Select "Use Lightning Web Security for Lightning Web Components and Aura Components"
  • Click "Save."

Ensure you empty the browser cache after turning the Lightning Web Security on or off to ensure that the correct files are loaded in the browser.

'lightning__dynamicComponent' capability

To create an LWC dynamically, the component's configuration file must include the 'lightning__dynamicComponent' capability.

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>59.0</apiVersion>
<capabilities>
<capability>lightning__dynamicComponent</capability>
</capabilities>
</LightningComponentBundle>

Dynamic component syntax

To dynamically instantiate a Lightning Web Component, the '<lwc:component>' managed element is used along with the 'lwc:is' directive in the HTML file of the component.

<template>
<div class="container">
<lwc:component lwc:is={componentConstructor}></lwc:component>
</div>
</template>
'<lwc:component>' serves as a placeholder in the DOM that renders the specified dynamic component. You must use '<lwc:component>' with the 'lwc:is' directive. The directive provides an imported constructor at runtime to the '<lwc:component>' managed element. 'lwc:is' accepts an expression that resolves to a 'LightningElement' constructor at runtime.

Import the custom element in the component's JavaScript file using the dynamic import syntax.

import { LightningElement } from "lwc";
export default class extends LightningElement {
componentConstructor;
// Use connectedCallback() on the dynamic component
// to signal when it's attached to the DOM
connectedCallback() {
import("c/concreteComponent")
.then(({ default: ctor }) => (this.componentConstructor = ctor))
.catch((err) => console.log("Error importing component"));
}
}

You can also use 'async-await' instead of '.then().'

It's not a one-size-fits-all solution

The introduction of dynamic instantiation for Lightning Web Components in Winter '24 is a significant and highly anticipated update that has captured the attention of Salesforce Developers. This feature offers a fresh approach to building flexible and customizable solutions, allowing Developers to choose between dynamic and static instantiation based on their specific use cases and requirements.

There is no one-size-fits-all answer to whether dynamic or static instantiation is the right choice. Each use case should be carefully evaluated to determine which approach aligns best with a project's goals and constraints.

To learn more, check out the LWC Dev Guide.