Performance
Reactivity
If you want to create performant web components, you have to use reactivity selectively. It doesn't mean you should ditch it altogether, instead, it's good to know when to use it and when not.
Consider the following example:
import { MinzeElement } from 'minze'
const nestedArray = []
for (let i = 0; i < 100; i++) {
nestedArray.push({ num: i })
}
class MyElement extends MinzeElement {
reactive = [['nestedArray', nestedArray]]
html = () => `${this.nestedArray[0].num}`
onReady() {
for (let i = 0; i < 100; i++) {
this.nestedArray[0].num = i
}
}
}
MyElement.define()<my-element></my-element>
<my-element></my-element>
<my-element></my-element>
<my-element></my-element>
<my-element></my-element>What's happening here?
We created a huge array of objects and made it deeply reactive. Then we created a loop in the onReady hook and reassigned one of the object's properties a bunch of times. Finally, we are rendering a template that displays the reassigned value. This seems simple but there's a lot going on under the hood:
- Minze had to iterate over every property inside the
nestedArrayand make them all reactive. That happened100times for each used element. Sincemy-elementwas used 5 times the total is500. - The template has been rerendered
100times because it includes a reactive property. Again sincemy-elementwas used 5 times the total is500.
In total, our elements performed about 1000 steps that are not necessary for the end result.
A much better approach
import { MinzeElement } from 'minze'
const nestedArray = []
for (let i = 0; i < 100; i++) {
nestedArray.push({ num: i })
}
class MyElement extends MinzeElement {
reactive = [['nestedArray', nestedArray]]
nestedArray = nestedArray
html = () => `${this.nestedArray[0].num}`
onReady() {
for (let i = 0; i < 100; i++) {
this.nestedArray[0].num = i
}
this.rerender()
}
}
MyElement.define()<my-element></my-element>
<my-element></my-element>
<my-element></my-element>
<my-element></my-element>
<my-element></my-element>Here we are not defining any reactive properties at all and instead, we are rerendering the component manually once our reassignment loop inside the onReady hook is done.
Using this approach our total count for all under the hood steps is 10 for all 5 elements together. Each component is initially rendered 1 time and at the end, it's rerendered again.
This can be further optimized by using the onStart hook instead of the onReady hook, which is executed before the first render.