Stencil: Flickering when using conditional rendering

Created on 27 Aug 2019  路  5Comments  路  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:

There is noticable flickering when using conditional rendering even with the simplest stencil component I could come up with.

Expected behavior:

No flickering.

Steps to reproduce:

I created a simple repo to reproduce the error https://github.com/m00k/stencil-render-performance. Use the buttons to switch between components.

Related code:

{this.showNo === 0 && <app-cmp1 class='cmp'></app-cmp1>}
{this.showNo === 1 && <app-cmp2 class='cmp'></app-cmp2>}
{this.showNo === 2 && <app-cmp3 class='cmp'></app-cmp3>}
{this.showNo === 3 && <app-cmp1 class='cmp'></app-cmp1>}

Cmp1
CmpEmpty
Cmp2

Other information:

Tested with Chrome Version 76.0.3809.132 (Official Build) (64-bit) on Linux Ubuntu 18.10
Might be duplicate of https://github.com/ionic-team/stencil/issues/1703

triage

Most helpful comment

I think this is a very serious bug that causes our app to look very janky and broken. If there is a way to mitigate this, this would be great. Thanks.

All 5 comments

Using functional components there is no flickering (https://github.com/m00k/stencil-render-performance/tree/functional-components).

{this.showNo === 0 && <Cmp1/>}
{this.showNo === 1 && <Cmp2/>}
{this.showNo === 2 && <Cmp3/>}
{this.showNo === 3 && <Cmp1/>}

Unfortunately this is not always an option.

You can actually see this exact same issue in action on the Ionic documentation page: Screen Recording 2019-10-22 at 11 47 AM
It first updates the already mounted custom-elements that are common between the pages over two frames, and then in the last frame it hydrates the requisite custom-elements that are not present on the first page.

It seems that the vdom is able to update any components that are already mounted on the page really quickly (often within a single animation frame), but mounting any new custom elements within a vdom render always requires at least one additional animation frame to complete. This is pretty disappointing for more complex use cases because it makes dynamic UIs built using Stencil components always feel subtly janky. I'm uncertain if this is a limitation of how custom-elements mount, or if it's a limitation of how the Stencil vdom rendering implementation throttles DOM updates, or perhaps some combination of the two..

I think this is a very serious bug that causes our app to look very janky and broken. If there is a way to mitigate this, this would be great. Thanks.

Might be related to: https://github.com/ionic-team/stencil/issues/2148

I was able to get around the flicker by adding

extras: {
initializeNextTick: false,
},
to my stencil.config.ts

Here is the commit that adds this to the config.

Here is the version notes about it.

@jordanranz You saved me another day of debugging Shadow DOM and Stencil. Thank you!

Was this page helpful?
0 / 5 - 0 ratings