flutter-caching-data は何をしますか?
Flutterアプリにキャッシュ戦略を実装し、パフォーマンスとオフラインサポートを向上させます。ネットワークリクエストを減らしたり起動を高速化するためにアプリデータをローカルに保持する際に使用します。
主な機能
- データキャッシュ: APIレスポンスなどをローカルに保存し、高速なデータアクセスを実現
- 画像キャッシュ: ネットワーク画像をキャッシュして読み込み時間を短縮
- 設定情報の永続化: ユーザー設定やアプリ状態をローカルに保持
- キャッシュ有効期限管理: 古いデータを自動的に無効化
- メモリとディスクの階層化キャッシュ: 用途に応じて最適なストレージを選択
対応プラットフォーム
- Flutter(Dart)
- モバイル(iOS/Android)、Web、デスクトップ
実装例
APIデータのキャッシュ(sqflite使用)
import 'package:sqflite/sqflite.dart';
class CacheManager {
static Database? _database;
static Future<Database> get database async {
if (_database != null) return _database!;
_database = await openDatabase(
'app_cache.db',
version: 1,
onCreate: (db, version) async {
await db.execute('''
CREATE TABLE cache (
key TEXT PRIMARY KEY,
data TEXT NOT NULL,
expiresAt INTEGER NOT NULL
)
''');
},
);
return _database!;
}
static Future<void> set(String key, String data, {Duration ttl = const Duration(hours: 1)}) async {
final db = await database;
final expiresAt = DateTime.now().millisecondsSinceEpoch + ttl.inMilliseconds;
await db.insert(
'cache',
{'key': key, 'data': data, 'expiresAt': expiresAt},
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
static Future<String?> get(String key) async {
final db = await database;
final result = await db.query(
'cache',
where: 'key = ? AND expiresAt > ?',
whereArgs: [key, DateTime.now().millisecondsSinceEpoch],
);
if (result.isEmpty) return null;
return result.first['data'] as String;
}
static Future<void> clear() async {
final db = await database;
await db.delete('cache');
}
}
設定情報の永続化(shared_preferences使用)
import 'package:shared_preferences/shared_preferences.dart';
class SettingsCache {
static Future<void> saveString(String key, String value) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(key, value);
}
static Future<String?> getString(String key) async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString(key);
}
}
画像キャッシュ(cached_network_image使用)
import 'package:cached_network_image/cached_network_image.dart';
class CachedImageWidget extends StatelessWidget {
final String imageUrl;
const CachedImageWidget({Key? key, required this.imageUrl}) : super(key: key);
@override
Widget build(BuildContext context) {
return CachedNetworkImage(
imageUrl: imageUrl,
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
);
}
}
キャッシュ戦略のベストプラクティス
- 適切なTTLを設定する: データの鮮度要件に応じて有効期限を調整
- オフラインファースト設計: 可能な限りキャッシュからデータを取得し、バックグラウンドで更新
- エラーハンドリング: キャッシュエラーが発生した場合でもアプリがクラッシュしないようにする
- ストレージ制限の考慮: 大量のデータをキャッシュする場合は定期的なクリーンアップを実施