8

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?

1
  • NB: wires that take dynamic parameters are called once the parameters have defined values/values change. This could be at any point in your component's active lifecycle.
    – Phil W
    May 29 at 13:19

1 Answer 1

14

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.

5
  • I do think you should mention the delay of wire invocation until dynamic parameters have defined values.
    – Phil W
    May 29 at 18:28
  • @PhilW You're not wrong. I thought it was insignificant wrt "initial loading", but you're right, it should be included.
    – sfdcfox
    May 29 at 21:46
  • You also state all calls are queued up and sent as a single call. I thought that is only true when you exceed the boxcarring threshold of 5 though honestly haven't investigated behaviour on single component initialization so would be interested for you to explicitly confirm.
    – Phil W
    May 30 at 6:06
  • @PhilW See this. Of course, it could change in the future, but the point is, for now, anything you call before the first renderedCallback will likely go at once, even bypassing the typical "boxcar" effect. Limiting your code to call as few methods as possible will improve loading performance.
    – sfdcfox
    May 30 at 6:15
  • Ah, fair enough - always good to learn new things 😀. Yes, of course, this is all undocumented behaviour quite intentionally, so it is important not to rely on such behaviours. That said, boxcarring itself has been acknowledged by Salesforce, and in separate discussions they have said it is something they would consider providing some control over (since it really can detrimentally impact user experience).
    – Phil W
    May 30 at 6:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.