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!
Manuel Moya Ferrer is a highly skilled freelancer who serves as a technical architect, developer, and DevOps engineer. He specializes in Salesforce solutions, covering all technical aspects of their development lifecycle.
Matthias Rolke
Freelance DevOps Consultant
Matthias is a freelance DevOps consultant for the Salesforce platform and an advisor for Hutte. He loves open-source software and maintains a few SFDX-related tools.
Article Highlights
Dynamic LWC creation is now possible without Aura Components, a major update anticipated in Winter '24, enhancing developer flexibility in Salesforce environments.
Implementing dynamic LWCs can lead to performance lags due to increased network trips required for fetching module dependencies, which highlights a trade-off between flexibility and performance.
The tag and lwc:is directive are critical in the dynamic instantiation process, offering a structured yet flexible method to render components based on runtime conditions.
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.
In the past, this limitation was one of the reasons to use Aura components. With this solution, we have one more reason to avoid Aura components in our projects and instead use LWCs.
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.
Harald is the Co-Founder of Hutte, bringing his vision of no-code DevOps to life. His passion enables teams and individuals to focus on what matters most – bringing value to the users they build for.