Maximize Cost Efficiency and Enhance Performance with Riverpod

Shatha Naami
4 min readJul 18, 2023

“Unlock Cost Savings and Supercharge Your App: Harness the Power of Riverpod to Reduce Server Expenses, Optimize API Requests, and Enhance App Performance”

Discover the transformative power of Riverpod, the tool that streamlines server operations and reduces request volume. With Riverpod, you can optimize your server’s performance, minimize costs, and elevate the user experience. Seamlessly integrate with APIs and leverage invaluable extensions.

Provider Lifecycle Callbacks

In the caching example, we’ve used three provider lifecycle callbacks to execute custom dispose logic at runtime.

In total, there are five different callbacks that we can use:

init

Efficient State Initialization with Riverpod: Streamlining App State Management

Riverpod utilizes listeners to efficiently manage states behind the scenes. When using a provider, such as through read, watch, or listen, a new listener is added.

The first usage of a provider in Riverpod signifies its initialization. This ensures that your app’s states are effectively managed and ready to be utilized. Simplify your state setup and benefit from Riverpod’s streamlined approach.

onCancel & onDispose

Riverpod intelligently manages listeners to ensure optimal resource utilization. When all listeners are removed, the provider enters a paused/passive state while still preserving resources until a new listener is added.

For non-autoDispose providers or when the keepAlive link is invoked, the dispose method is not called. However, with autoDispose providers, the onDispose method is executed, releasing all associated resources.

onResume

But if we add a new listener again, onResume will be called and the provider will be active again. but this time it will give us the cached data and not execute the provider again.

Gift

refresh

Invoke the refresh method to dispose of and reinitialize the provider, returning the new value.

invalidate

Unlike refresh, invalidate immediately reinitializes the provider without waiting for a new value.

Let’s Start with a Real Example 🚀

To provide a comprehensive understanding of the underlying processes, I will supplement our example with a recorded video demonstration.

As you can observe, we fetch the data only once. When revisiting the page before the cache duration elapses, it displays the cached data. However, once the cache duration “3 seconds” expires, it fetches the data anew.

The first function in our example is GET: Post With ID

Here are explanations for the code:

  1. Logs the lifecycle.
  2. We have to call debounce at first ‘I will explain it in the next’.
  3. Cache for 3 seconds “default duration”.
  4. Creates a cancel token with an auto-cancel option
  5. After that GET Post with Id.
GET — POST/ID

To implement this caching mechanism, we simply utilize the ref.cacheFor(); extension in this example.

Additionally, we can acquire the keepAlive link and conveniently dispose of the provider as needed. In this specific scenario, we dispose of the provider when canceling the request.

NOW, let’s move on to explain the most important part of the example.

Extensions 🤝

- CacheExtension 😌

When navigating to the PostDetailsPage, the postProvider initializes and retrieves data from the server. Upon returning to the PostListPage, the provider attempts to dispose of itself by invoking the onCancel and onDispose methods (as it is an autoDispose provider). However, the provider remains active due to the keepAlive functionality, preventing disposal and preserving the state.

If the provider is canceled, a timer starts. If we reopen the PostDetailsPage before the timer expires, both the timer and the disposal process are canceled. However, if we do not revisit the PostDetailsPage and allow the timer to run out, the keepAlive link is severed, triggering the self-disposal of the provider.

cache-extension

- CancelTokenExtension 😌

If we left the PostDetailsPage before the data was fetched, cancel the request and dispose of the provider.

cancel-token-extension

- DebounceExtension 😌

To mitigate potential issues and minimize server costs, it is advisable to invoke the method only when the user ceases pressing the button, instead of allowing rapid and multiple button clicks. This approach ensures expected behaviors and efficient utilization of server resources.

So, we need to call debounce only when refreshing the process.

— Current DebounceExtension implementation

Closing Remarks 🤓

While it is possible to implement data caching on the API side, this article has primarily focused on showcasing caching capabilities within Riverpod. By exploring Riverpod’s caching mechanisms, we have delved into efficient data storage and retrieval, providing valuable insights into optimizing app performance.

References

Github Project

Take the opportunity to download the final project and embark on your own exploration of its capabilities!

--

--

Shatha Naami
Shatha Naami

Written by Shatha Naami

👋 Hello! I'm Shatha, a passionate mobile engineer specializing in Flutter development. I love creating beautiful and high-performing cross-platform mobile apps

No responses yet