Stencil: Components without shadowdom are rendering twice when dynamically added to the DOM

Created on 14 Oct 2019  路  7Comments  路  Source: ionic-team/stencil

Stencil version:

@stencil/[email protected]

I'm submitting a:

[ x] bug report
[ ] feature request
[ ] support request => Please do not submit support requests here, use one of these channels: https://stencil-worldwide.herokuapp.com/ or https://forum.ionicframework.com/

Current behavior:
When using a Stencil webcomponent without Shadowdom the inner contents of the webcomponent gets rendered twice when the component is added dynamically to the DOM. We've seen the behaviour occurring with AngularJS.

Expected behavior:
The component should only render once and cleanup previous rendered content.

Steps to reproduce:

bug

Most helpful comment

The fix for the cloneNode is a special case, and may rarely need to be used. Additionally, it does add some extra weight to the runtime, which many may not even be used. So to start we'll make this an opt-in feature for those who need it, and if it continues to be a problem for the majority then we can enable it by default.

To enable the cloneNode fix, within the stencil.config.ts it has a new extras object, which can set cloneNodeFix to true.

{
  extras: {
    cloneNodeFix: true
  }
}

When this is enabled, the cloneNode fix will be included in the runtime.

All 7 comments

This is quite negatively impacting a project of ours at @Claromentis, and we can't find a workaround. 馃

The main reason we need to forego Shadow DOM is to allow form elements (<input>, <textarea>, <select>) to function correctly in a <form>.

If anyone knows of a workaround please do post it here. If we find one, we'll do the same.

The workaround we found was to wrap the component in a simple AngularJS directive, for now. For some reason, likely to do with the timing of DOM changes, this allows the component to behave properly.

@hexus I happened to look into this as well yesterday/today. I'm not happy with the outcome because I strongly feel that my solution is a rather hacky workaround and will fail in any other conditional rendering scenario. Me and Dennis are going to deep dive next week to find a more suitable fix on the Stencil side next week.

The behaviour of ngIf clones the element after hydration and slot insertion happens. When the ngIf component is added to the DOM again and sees the inserted slot as new slot content and renders it again.

The cloning is only done on init of ngIf therefore you only see a double render and not a slot inception ;)

If you're interested here's a monkey patch of the ngIf directive: https://gist.github.com/patricksevat/9b4608604de980395442c7b305d99b3b (use at your own risk ;))

Ah, we were seeing a "slot inception" issue when using ng-repeat. Perhaps that's a slightly different issue.

Hi @hexus ,
Me and @denniswiemer have found the root cause of this issue and we have a potential fix.
It might require some iterations with the core team to get to a proper solution, but just wanted to update you that a PR is coming ASAP

That's awesome news, thanks Patrick.

The fix for the cloneNode is a special case, and may rarely need to be used. Additionally, it does add some extra weight to the runtime, which many may not even be used. So to start we'll make this an opt-in feature for those who need it, and if it continues to be a problem for the majority then we can enable it by default.

To enable the cloneNode fix, within the stencil.config.ts it has a new extras object, which can set cloneNodeFix to true.

{
  extras: {
    cloneNodeFix: true
  }
}

When this is enabled, the cloneNode fix will be included in the runtime.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kensodemann picture kensodemann  路  3Comments

mitchellsimoens picture mitchellsimoens  路  3Comments

MrMcGibblets picture MrMcGibblets  路  3Comments

lcswillems picture lcswillems  路  3Comments

glemiere picture glemiere  路  3Comments