Open1
Flutterカクカク
カクつきの主な原因と解決策について、体系的に説明させていただきます。
- スクロール関連の問題:
// 悪い例
SingleChildScrollView(
child: Column(
children: [
// 大量のWidget
],
),
)
// 良い例
CustomScrollView(
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListItem(item: items[index]),
childCount: items.length,
),
),
],
)
- 不必要な再ビルド:
// 悪い例
class MyWidget extends StatelessWidget {
final int count = 0; // 毎回再ビルド
Widget build(BuildContext context) {
return Text('$count');
}
}
// 良い例
class MyWidget extends StatelessWidget {
const MyWidget({required this.count});
final int count;
Widget build(BuildContext context) {
return Text('$count');
}
}
- メモリリーク防止:
// 悪い例
class _MyStateState extends State<MyState> {
StreamSubscription? _subscription;
void initState() {
super.initState();
_subscription = stream.listen((_) {});
}
// disposeを忘れている
// 良い例
void dispose() {
_subscription?.cancel();
super.dispose();
}
- レイアウトのベストプラクティス:
// 悪い例:ネストが深い
Column(
children: [
Row(
children: [
Column(
children: [
// 複雑すぎる
],
),
],
),
],
)
// 良い例:コンポーネント化
class CustomComponent extends StatelessWidget {
Widget build(BuildContext context) {
return Column(
children: [
HeaderWidget(),
ContentWidget(),
FooterWidget(),
],
);
}
}
- 画像の最適化:
// 悪い例:大きな画像をそのまま使用
Image.network(url)
// 良い例:キャッシュと最適化
CachedNetworkImage(
imageUrl: url,
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
)
- アニメーションの最適化:
// 悪い例:重いアニメーション
setState(() {
// 多数のWidgetに影響する更新
});
// 良い例:AnimatedBuilderの使用
AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Transform.rotate(
angle: _controller.value * 2.0 * pi,
child: child,
);
},
child: const MyWidget(), // 再ビルドされない
)
- StateManagementの適切な使用:
// 悪い例:グローバルな状態更新
setState(() {
globalVariable = newValue;
});
// 良い例:Providerなどの状態管理の使用
final counterProvider = StateNotifierProvider<Counter, int>((ref) => Counter());
class Counter extends StateNotifier<int> {
Counter() : super(0);
void increment() => state++;
}
これらの問題に対する一般的な解決策:
-
CustomScrollView
とSliverList
の活用 -
const
コンストラクタの積極的な使用 - メモリリークの防止とリソースの適切な解放
- Widgetの適切な分割とコンポーネント化
- 画像の最適化とキャッシュの活用
- アニメーションの最適化
- 適切な状態管理の導入
パフォーマンス改善のためのベストプラクティス:
- DevToolsを使用したパフォーマンスの分析
- Flutter Performance Profilerの活用
- Timeline viewでのボトルネック特定
- メモリリークの検出と修正
- レイアウトの深さの最適化
これらの対策を適切に組み合わせることで、Flutterアプリのパフォーマンスを大幅に改善することができます。