Client-Side Caching of Apex Method Results

To improve runtime performance, annotate the Apex method with @AuraEnabled(cacheable=true), which caches the method results on the client. To set cacheable=true, a method must only get data, it can’t mutate (change) data.

Marking a method as cacheable improves your component’s performance by quickly showing cached data from client-side storage without waiting for a server trip. If the cached data is stale, the framework retrieves the latest data from the server. Caching is especially beneficial for users on high latency, slow, or unreliable connections. Cacheable methods perform better, so use them when possible.

To use @wire to call an Apex method, you must set cacheable=true.

To call an Apex method imperatively, you can choose to set cacheable=true.

The caching refresh time is the duration in seconds before an entry is refreshed in storage. The refresh time is automatically configured in Lightning Experience and the Salesforce mobile app.

The default cache duration can change as we optimize the platform. When you design your Lightning web components, don't assume a cache duration. If a component knows that a cached value is invalid, for example when underlying data changes, it can query the server for updated data and refresh the cache with refreshApex() from @salesforce/apex.

The ldsDeleteRecord component in the lwc-recipes repo calls refreshApex().

To refresh stale Apex data, invoke the Apex method and then call notifyRecordUpdateAvailable(recordIds) to update the Lightning Data Service (LDS) cache. Lightning Data Service doesn’t manage data provisioned by imperative Apex calls. After you invoke the Apex method, call notifyRecordUpdateAvailable(recordIds) to signal to Lightning Data Service that some records are stale and refresh those records in the cache.

To refresh Apex data provisioned via an Apex @wire, call refreshApex(). The function provisions the data using the configuration bound to the @wire and updates the cache.

The parameter you refresh with refreshApex() must be an object that was previously emitted by an Apex @wire.

Sometimes, you know that the cache is stale. If the cache is stale, the component needs fresh data. To query the server for updated data and refresh the cache, import and call the refreshApex() function. Invoke refreshApex() only when necessary because it incurs a network trip to query the server.

The refreshApex() function returns a Promise. When the Promise is resolved, the data in the wire is fresh. The return value from the Apex method is only available on the @wire. The @wire has fresh data when the Promise resolves, but the actual value to which the Promise resolves is meaningless. Use a then() block to work with the refreshed data, such as setting a property on the page.

  • Where valueProvisionedByApexWireService is either a property annotated with an Apex @wire, or if you annotated a function, the argument that the wired function receives.

Let’s look at an example. This component displays a list of opportunities over a specified amount. A user can click to mark all the opportunities as Won. When the opportunities are updated, the cache data becomes stale. So after the code updates the opportunities, it calls refreshApex() to query the server for updated data and refresh the cache.

Shows a list of opportunities over a specified amount.

Let’s look at the JavaScript code for the <c-opportunities-over-amount> component. First it imports refreshApex and the Apex methods from @salesforce/apex.

Then it calls the Apex method getOpptyOverAmount with a dynamic value, amount. The data is rerequested whenever this.amount changes. The system provides the data from the client-side cache or from the server.

The code calls refreshApex() in the handleClick method. Changing the stage to Closed Won impacts the CloseDate field, which means that the @wire data is stale. The Close Date field changes to today's date when you have a close date in the future.

To tell the system that the data is stale, call refreshApex(). The wire adapter marks its cache as stale, requeries the server for updated data, updates its cache, then notifies its subscribers. When that happens, the component's this.opptiesOverAmount property updates, which triggers a rerender with the new data. The close date is now July 18, 2019 (today’s date) and the opportunity stage is now “Closed Won”.

Shows a list of opportunities that are marked as Closed Won.

The OpptiesOverAmountApex class contains the getOpptyOverAmount method, which retrieves a list of opportunities over the specified amount. It also contains the updateOpptyStage method, which updates the opportunity stage for opportunities over the specified amount to “Closed Won” using the update DML operation.

To refresh a wired function, pass the argument the wired function receives (which is the wired value) to refreshApex(). In this sample code, the wired function is wiredGetActivityHistory(value). Hold on to the value provisioned by the wire service and pass it to refreshApex().

Call refreshApex() imperatively using a new function. To track the provisioned value, define a new property, wiredActivities, and use it in wiredGetActivityHistory(value). Destructure the provisioned value to extract the data and error objects easily.

See Also