《Flutter 网络请求缓存策略:内存缓存与持久化缓存的实现》
·
Flutter 网络请求缓存策略:内存缓存与持久化缓存的实现
在移动应用中,网络请求缓存是优化性能的关键策略。Flutter 通过内存缓存(快速访问)和持久化缓存(长期存储)的双层机制,有效减少重复网络请求,提升用户体验。以下是具体实现方案:
一、内存缓存实现
内存缓存使用 Map 结构存储临时数据,生命周期与 App 进程绑定:
class MemoryCache {
static final Map<String, dynamic> _cache = {};
// 添加缓存(带过期时间)
static void set(String key, dynamic value, {Duration? expire}) {
_cache[key] = {
'data': value,
'expire': expire != null ? DateTime.now().add(expire) : null
};
}
// 获取缓存(自动验证过期)
static dynamic get(String key) {
final item = _cache[key];
if (item == null) return null;
if (item['expire'] != null &&
DateTime.now().isAfter(item['expire'])) {
_cache.remove(key);
return null;
}
return item['data'];
}
}
二、持久化缓存实现
使用 shared_preferences + hive 实现跨会话存储:
class PersistentCache {
static late Box _box;
// 初始化(App启动时调用)
static Future<void> init() async {
_box = await Hive.openBox('network_cache');
}
// 存储数据
static Future<void> set(String key, dynamic value) async {
await _box.put(key, {
'data': value,
'timestamp': DateTime.now().millisecondsSinceEpoch
});
}
// 读取数据(带缓存有效期检查)
static dynamic get(String key, {Duration maxAge = const Duration(days: 7)}) {
final item = _box.get(key);
if (item == null) return null;
final timestamp = item['timestamp'];
final age = DateTime.now().millisecondsSinceEpoch - timestamp;
if (age > maxAge.inMilliseconds) {
_box.delete(key);
return null;
}
return item['data'];
}
}
三、网络请求整合缓存策略
class CachedHttp {
Future<dynamic> get(String url) async {
// 1. 检查内存缓存
final memoryData = MemoryCache.get(url);
if (memoryData != null) return memoryData;
// 2. 检查持久化缓存
final persistentData = PersistentCache.get(url);
if (persistentData != null) {
MemoryCache.set(url, persistentData); // 回填内存缓存
return persistentData;
}
// 3. 发起网络请求
final response = await http.get(Uri.parse(url));
final data = jsonDecode(response.body);
// 4. 更新缓存系统
MemoryCache.set(url, data, expire: const Duration(minutes: 10));
PersistentCache.set(url, data);
return data;
}
}
四、缓存策略优化技巧
-
分级缓存策略
- 内存缓存:高频数据,设置短时效(如 10 分钟)
- 持久化缓存:重要数据,设置长时效(如 7 天)
-
缓存失效机制
- 时间戳验证:
DateTime.now().millisecondsSinceEpoch - 版本号控制:当 API 结构变更时清除缓存
- 时间戳验证:
-
存储优化
- 使用
gzip压缩 JSON 数据 - 敏感数据加密存储:
final encrypted = encryptData(data, key); await _box.put(url, encrypted);
- 使用
-
缓存清理策略
// 定期清理过期缓存 void cleanExpiredCache() { _box.keys.forEach((key) { if (PersistentCache.get(key) == null) { _box.delete(key); } }); }
五、性能对比指标
| 请求方式 | 平均耗时 | 流量消耗 |
|---|---|---|
| 无缓存 | 1200ms | 100% |
| 内存缓存 | 15ms | 0% |
| 持久化缓存 | 50ms | 0% |
实践建议:对实时性要求高的数据(如股票行情)优先使用内存缓存,对稳定性要求高的数据(如用户资料)使用持久化缓存。结合
flutter_bloc的hydrated_bloc可自动实现状态持久化缓存。
更多推荐
所有评论(0)