Stencil version:
@stencil/[email protected] and all older
I'm submitting a:
[x] bug report
[ ] feature request
[ ] support request
Current behavior:
I have projects in Ember and React. I created a library of Stencil components with components like:
I replaced Ember and React components with brand new Stencil components. I observed performance problems after this replacement. You can see differences in linked videos. First for old, React components, second for Stencil.
https://www.youtube.com/watch?v=fyLq41L3CCc
https://www.youtube.com/watch?v=A23JFnCYxro
The problem occurs both in Ember and React.
Render is slower in an unacceptable way. In youtube example, the difference is really small, but for 30 rows dashboard, the final result is visible 1.5 seconds later.
Observations in my app context:
Expected behavior:
Rendering should be at least that quick as in original components
Steps to reproduce:
Create a container with several stencil components. Show/hide this container using a button with simple action and conditional statement in your template
Related code:
Example of usage:
<BF sizeSm={2}>
<select
optionNameField={'name'}
onSelect={this.onChange}
optionsArray={this.props.names}
valueObject={this.state.selectedName}
/>
</BF>
<BF sizeSm={3}>
<ac-multiselect
optionsArray={this.props.types}
valuesArray={this.state.selectedTypes}
onChangeHandler={this.onChangeType}
optionNameField="name"
optionValueField="type"
/>
</BF>
Example of component implementation:
export class Text implements ComponentInterface {
@Prop({ reflect: true }) color: TextColor = TextColor.black;
@Prop({ reflect: true }) size: TextSize = TextSize.md;
@Prop({ reflect: true }) weight: TextWeight = TextWeight.normal;
@Prop({ reflect: true }) uppercase: boolean;
private colorClass(): string {
return `text-color-${this.color}`;
}
private sizeClass(): string {
return `text-size-${this.size}`;
}
private weightClass(): string {
return `text-weight-${this.weight}`;
}
private uppercaseClass(): string {
return this.uppercase ? 'text-uppercase' : '';
}
private classes(): string[] {
return [
this.sizeClass(),
this.weightClass(),
this.colorClass(),
this.uppercaseClass()
].filter(Boolean);
}
render() {
return (
<Host class={{ ...getClassMap(this.classes()) }}>
<slot />
</Host>
);
}
}
Other information:
I did a simple performance test. Render 1000 components (text field) on the plain React page. Stencil was faster than React. Problem is appearing only when I'm using components in a regular structure.
We're running into similar issues where updates in the state of a component that renders child components shows a flash of unstyled content even for child components that are already lazy loaded.
Is the bottleneck related to virtual dom? would it be faster if stencil is built with svelte.js?
I don't think so, I turned off virtual DOM
try removing the reflect: true on the component and see if this improves things, seeing similar issues.
Most helpful comment
We're running into similar issues where updates in the state of a component that renders child components shows a flash of unstyled content even for child components that are already lazy loaded.