LitElement renders and re-renders asynchronously, updating in response to batched property changes (see Element update lifecycle for more information).
During an update, only the parts of the DOM that change are re-rendered. To get the performance benefits of this model, you should design your element's template as a pure function of its properties.
To do this, make sure the render
function:
- Does not change the element's state.
- Does not have any side effects.
- Only depends on the element's properties.
- Returns the same result when given the same property values.
Also, avoid making DOM updates outside of render
. Instead, express the element's template as a function of its state, and capture its state in properties.
The following code uses inefficient DOM manipulation:
dom-manip.js
// Anti-pattern. Avoid!
constructor() {
super();
this.addEventListener('stuff-loaded', (e) => {
this.shadowRoot.getElementById('message').innerHTML=e.detail;
});
this.loadStuff();
}
render() {
return html`
<p id="message">Loading</p>
`;
}
We can improve the template by capturing the load message as a property, and setting the property in response to the event:
update-properties.js
constructor() {
super();
this.message = 'Loading';
this.addEventListener('stuff-loaded', (e) => { this.message = e.detail } );
this.loadStuff();
}
render() {
return html`
<p>${this.message}</p>
`;
}
{% include project.html folder="docs/templates/design" openFile="update-properties.js" %}