Maximize Cost Efficiency and Enhance Performance with Riverpod
“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:
- Logs the lifecycle.
- We have to call debounce at first ‘I will explain it in the next’.
- Cache for 3 seconds “default duration”.
- Creates a cancel token with an auto-cancel option
- After that GET Post with 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.
- CancelTokenExtension 😌
If we left the PostDetailsPage before the data was fetched, cancel the request and dispose of the provider.
- 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!