stencil icon indicating copy to clipboard operation
stencil copied to clipboard

bug: taskQueue: 'immediate' causes lifecycle events out of order

Open k1w1 opened this issue 1 year ago • 2 comments

Prerequisites

Stencil Version

4.25.0

Current Behavior

When taskQueue: 'immediate' is set in the configuration and lazyLoad is false then the render method is called before the connectedCallback is called.

In https://github.com/ionic-team/stencil/blob/v4.25.0/src/runtime/bootstrap-custom-element.ts#L91 the component is initialized before the originalConnectedCallback is called. When the component is intialized the first render is scheduled at https://github.com/ionic-team/stencil/blob/v4.25.0/src/runtime/initialize-component.ts#L187 and happens synchronously, so render is called before connectedCallback is called for the first time. This seems inconsistent with the documentation, and is a problem because any initialization code in connectedCallback is not run.

We want to use taskQueue: 'immediate' so that web-components behave more like regular HTML elements, in particular appearing in the DOM synchronously. The delayed rendering of taskQueue: async causes a lot of extra complexity around things like measuring the size of DOM elements that contain web components.

Expected Behavior

Lifecycle callbacks should be called in order, even with taskQueue: 'immediate'.

System Info


Steps to Reproduce

Use taskQueue: 'immediate' in stencil.config.ts.

Code Reproduction URL

https://github.com/k1w1/lifecycle-order-bug

Additional Information

The reproduction repo shows the problem. Note that you must explicitly visit /src/index.html to see the component run. Here is a screenshot of the output showing the out-of-order lifecycle callbacks.

Image

k1w1 avatar Jan 25 '25 05:01 k1w1

@k1w1 thanks for raising the issue. Are you setting taskQueue: 'immediate' for any particular reason?

christian-bromann avatar Jan 25 '25 18:01 christian-bromann

We have been using Stencil for a long time, very successfully, but one thing that has caused a lot of confusion to our developers, and complexity in our code, is that rendering is asynchronous. Our code mixes regular HTML and web-components. Code that works fine when you wrap regular HTML doesn't work when you wrap web components, e.g. because if it tries to measure the size of the children the result is wrong if you don't wait for the first render. This takes code that is simple when working with HTML and makes it more complex when web components are involved. Many of the people on our team (myself included) thought this was just a drawback of web components in general, and it was with surprise that I recently realized it was coming from Stencil.

With the component library our first priority is developer ergonomics - that is the reason to use a component library in the first place - and so the desire to use immediate rendering is to better match regular HTML.

k1w1 avatar Jan 28 '25 16:01 k1w1