How to Debounce a Function in Dart ?(Perfect for Search Input in Flutter)
In modern Flutter apps, debouncing is essential when handling user input like search fields. Without it, every keystroke triggers a function—leading to performance issues or unnecessary API calls.
In this article, you’ll learn how to debounce a function in Dart, ideal for search inputs, form validations, or delayed actions. We’ll also provide a complete working example and explain the logic behind it.
What is Debouncing?
Debouncing is a technique that ensures a function is only executed after a specified time has passed since the last call. This is helpful when you want to reduce the frequency of expensive operations—like API calls during typing.
Use Case: Debounce Search Input in Flutter
Let’s say you want to search a database every time the user types in a TextField
. Without debouncing, you’ll hit the backend on every keystroke. That’s inefficient and expensive.
Debounce Logic in Dart
Here’s a simple debounce utility using Timer
:
import 'dart:async';
class Debouncer {
final int milliseconds;
VoidCallback? action;
Timer? _timer;
Debouncer({required this.milliseconds});
run(VoidCallback action) {
_timer?.cancel();
_timer = Timer(Duration(milliseconds: milliseconds), action);
}
dispose() {
_timer?.cancel();
}
}
Example: Debounced Search in Flutter
import 'package:flutter/material.dart';
import 'dart:async';
class DebouncedSearchPage extends StatefulWidget {
@override
_DebouncedSearchPageState createState() => _DebouncedSearchPageState();
}
class _DebouncedSearchPageState extends State<DebouncedSearchPage> {
final _debouncer = Debouncer(milliseconds: 500);
String _searchText = '';
void _onSearchChanged(String query) {
_debouncer.run(() {
setState(() {
_searchText = query;
});
print("Searching for: $query"); // Replace with your API call
});
}
@override
void dispose() {
_debouncer.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Debounced Search')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextField(
onChanged: _onSearchChanged,
decoration: InputDecoration(
labelText: 'Search...',
border: OutlineInputBorder(),
),
),
SizedBox(height: 20),
Text("Search Query: $_searchText"),
],
),
),
);
}
}
Debouncing in Dart is simple and powerful. With just a few lines of code, you can improve the performance of your Flutter app and enhance user experience. This approach is especially useful in search fields and auto-complete forms.
Pro Tip: You can also integrate this with state management tools like GetX, Bloc, or Provider for even cleaner architecture.
Want more Flutter tips? Keep visiting FlutterFever.com for tutorials, tricks, and performance hacks.
Frequently Asked Questions (FAQ)
Debouncing in Dart is a technique to delay the execution of a function until a certain period of inactivity has passed. It’s commonly used to control how often a function like a search or API call is triggered.
Without debouncing, every keystroke makes an API call, which can overload your backend. Debouncing ensures that the API is only called once the user has stopped typing for a short while.
You can create a Debouncer
class using Timer
from dart:async
, which cancels the previous timer and starts a new one with each function call.
Yes. Libraries like RxDart provide operators like debounceTime
for streams. GetX also supports debouncing with ever()
and debounce()
functions.
Debouncing delays the function until the activity stops, while throttling limits the function to fire only once in a specified period, even if calls keep coming.