Flutter의 Element 재사용 메커니즘
canUpdate() 메서드
Flutter는 Widget.canUpdate() 메서드를 사용하여 Element 재사용 여부를 결정합니다
// Flutter 프레임워크의 실제 canUpdate() 메서드
static bool canUpdate(Widget oldWidget, Widget newWidget) {
return oldWidget.runtimeType == newWidget.runtimeType
&& oldWidget.key == newWidget.key;
}
재사용 판단 과정
- 프레임 빌드 시: Element Tree의 각 노드를 검사
- 비교 수행: 새 위젯의 타입과 키를 이전 위젯과 비교
- 재사용 결정:
- 타입과 키가 같으면 → Element 재사용, 참조만 업데이트
- 다르면 → 기존 Element 제거 후 새로 생성
성능에 미치는 영향
// 좋은 예: Element 재사용
Widget build(BuildContext context) {
return Container( // 항상 Container 타입 유지
color: isActive ? Colors.blue : Colors.grey,
child: Text(message),
);
}
// 나쁜 예: Element 재생성
Widget build(BuildContext context) {
return isActive
? Container(child: Text(message)) // Container 타입
: SizedBox(child: Text(message)); // SizedBox 타입 - 타입 변경으로 인한 Element 재생성
}
문제가 있는 코드 만들어 보기


import 'package:class_key/components/custom_container.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: MyHomePage(),
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// 자료 구조(메모에서 데이터를 넣고 빼고 수정..)
List<Widget> containers = [
CustomContainer("1", key: ValueKey(1)),
CustomContainer("2", key: ValueKey(2)),
CustomContainer("3", key: ValueKey(3)),
];
// 변수
Widget extraContainer = const CustomContainer("Extra");
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: containers,
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
if (containers.length == 3) {
containers.insert(0, extraContainer);
} else if (containers.length == 4) {
containers.removeAt(0);
}
});
},
child: Icon(
Icons.add_box_rounded,
size: 42,
),
),
);
}
}
import 'dart:math';
import 'package:flutter/material.dart';
//
class CustomContainer extends StatefulWidget {
final String name;
const CustomContainer(this.name, {super.key});
@override
State<CustomContainer> createState() => _CustomContainerState();
}
class _CustomContainerState extends State<CustomContainer> {
late Color color = getRandomColor();
// 부모 위젯에 멤버, 메서드에 접근하는 방법은 내부적으로 widget 변수가
// 설계 되어 있다.
@override
Widget build(BuildContext context) {
print("${widget.name} - 에 build() 메서드가 호출 됨");
return Container(
height: 150,
width: 150,
color: color,
child: Center(
child: Text(
widget.name,
style: TextStyle(
color: Colors.black,
fontSize: 24,
),
),
),
);
}
Color getRandomColor() {
final Random random = Random();
return Color.fromRGBO(
random.nextInt(256),
random.nextInt(256),
random.nextInt(256),
1,
);
}
}'Flutter' 카테고리의 다른 글
| 카메라 다루기 1단계 (0) | 2025.08.20 |
|---|---|
| Flutter Key 및 상태 관리의 기본 개념 - 성능 최적화 팁 (0) | 2025.08.20 |
| Flutter Key 및 상태 관리의 기본 개념 - Flutter의 세 가지 트리 구조 (0) | 2025.08.19 |
| Flutter Gesture (0) | 2025.08.19 |
| dart HTTP 요청과 응답 처리 및 파싱 (0) | 2025.08.19 |