Order of execution of @wire in lwc

lightning-web-componentslwc-domlwc-wire-adapter

I know that @wire methods are always executed once our component is loaded. I want to dig deep into this and want to understand the order of execution with respect to the component's life cycle. When it is actually that the @wire method will be invoked. Is it after constructor(), before renderedcallback()?
If that is the case then is it not always beneficial to get data using Imperative apex(from the constructor()) to improve performance(loading of component) instead of @wire?

Best Answer

In a typical wire setup, the life cycle will be:

  • constructor
  • wire provisions empty object ({data, error} are each undefined)
  • connectedCallback
  • render
  • renderedCallback
  • wire provisions results from server
  • render (if dirty data)
  • renderedCallback (ditto)

Using imperative Apex in the constructor, you end up with:

  • constructor
  • connectedCallback
  • render
  • renderedCallback
  • Apex call returns data
  • render (if dirty data)
  • renderedCallback (ditto)

In other words, you'll have at least two render cycles either way. Combining the two ends up with up to 3 render cycles (initial, Apex, wire, in that order).

With either scenario, any server-side code will be delayed until after the first renderedCallback. The initialization process of components is atomic (here, meaning a single indivisible unit of execution). All asynchronous actions (both wire and Apex), up to the allowed limit of 2,500 actions, will be queued up and sent to the server in a single call.

As such, there is no inherent benefit in trying to call Apex from the constructor. If you want your component to load an initial state faster (e.g., so you can show a "loading template"), you may want to actually use connectedCallback with imperative Apex:

async connectedCallback() {
  await Promise.resolve();
  let apexResults = await Promise.all([ method1(params), method2(params) ])
  // Do something with results
}

The await Promise.resolve() allows all of the wire methods to go first, in a separate server roundtrip, then the Apex methods will be called afterwards in a second roundtrip. This trades overall load time for a faster initial render. If you have really "heavy" components, using a small delay with this method should give a better impression that the page is loading faster than it actually is.

Also note that wire handlers won't trigger with reactive parameters when those reactive parameters are still undefined. Consequently, if one wire handler depends on another, there may be multiple render/renderedCallback cycles in a cascading fashion. However, this can also break up the rendering cycle to give a more responsive UI.