공부/flutter

[Flutter] Const construtor

iris3455 2025. 10. 18. 22:55

 

1. 개념

const는 위젯을 한 번만 메모리에 올려두고 재사용하도록 만들어, 불필요한 객체 생성과 빌드 호출, 그리고 GC(가비지 컬렉션) 부담을 줄여주는 기술이다. Dart 언어에서는 이러한 객체를 컴파일 타임 상수(Constant Object) 라고 부른다.

 

 

2. 원리

const Text('Hello');

 

이렇게 선언된 위젯은 앱이 실행되기 전에, 컴파일 시점에 미리 생성된다. 즉, 런타임마다 새로 만들어지는 것이 아니라 한 번만 만들어져 계속 재사용되는 객체라는 뜻이다. 따라서 const 인스턴스는 컴파일 타임에 이미 결정되므로, 불필요한 객체 생성이 없고 가비지 컬렉션(GC) 대상이 되지 않는다. 즉 동일한 const 인스턴스를 재사용하기 때문에 빌드 속도가 향상되고 메모리 또한 절약되므로 렌더링을 효율적으로 할 수 있다.

 

인스턴스 생성 (instantiate)

실제로 객체를 메모리에 새로 만드는 일

 

리빌드 (rebuild)

build() 메서드가 다시 호출되어 위젯 트리를 “묘사”하는 일

 

const t1 = Text('Hello');
const t2 = Text('Hello');

print(identical(t1, t2)); // true ✅

 

Dart는 Canonicalization(정규화) 과정을 통해 같은 내용의 const 객체를 하나만 유지한다. 그래서 t1과 t2는 실제로 같은 인스턴스이고, 메모리 상에서도 한 번만 존재하게 된다.

 

한마디로 만약 setState()로 부모 위젯이 rebuild 된다면? build()가 다시 호출될 수는 있다. 하지만 const widget는 이미 컴파일 타임에 만들어진 동일 인스턴스라서 새로운 객체를 만들지 않고 기존 인스턴스를 재사용한다.

  • build() 호출됨
  • Text 객체는 새로 생성되지 않음
  • 동일 인스턴스를 다시 참조함

아래 코드로 테스트 해볼수 있다.

class WidgetConstA extends StatelessWidget {
  final String text;
  const WidgetConstA({required this.text});
}

class WidgetNonConstB extends StatelessWidget {
  final String text;
  WidgetNonConstB({required this.text});
}

const widgetA1 = WidgetConstA(text: 'A');
const widgetA2 = WidgetConstA(text: 'A');
final isIdenticalA = identical(widgetA1, widgetA2);  // true (같은 인스턴스)
final isEqualA = widgetA1 == widgetA2;               // true (같은 객체)

final widgetB1 = WidgetNonConstB(text: 'B');
final widgetB2 = WidgetNonConstB(text: 'B');
final isIdenticalB = identical(widgetB1, widgetB2);  // false (다른 인스턴스)
final isEqualB = widgetB1 == widgetB2;               // false (다른 객체)

 

 

 

3. const 남용 주의

const는 위젯을 재사용하도록 만들어 성능을 높이는 중요한 키워드지만, 이미 상수로 추론되는 문맥에서 중복으로 사용하는 것은 불필요한 코드가 된다. Dart의 Linter 규칙인 unnecessary_const 는 바로 이런 중복 사용을 경고한다. Dart에서는 “상수 컨텍스트(const context)” 안에서는 내부 요소가 자동으로 const로 간주되기 때문이다. 즉, 바깥에서 한 번만 const를 선언해도 그 안의 모든 객체와 컬렉션은 이미 상수다.

 

// 올바를 사용
const primaryColors = [
  Color('red', [255, 0, 0]),
  Color('green', [0, 255, 0]),
  Color('blue', [0, 0, 255]),
];

// 잘못된 사용
const primaryColors = const [
  const Color('red', const [255, 0, 0]),
  const Color('green', const [0, 255, 0]),
  const Color('blue', const [0, 0, 255]),
];

 

https://dart-ko.dev/guides/language/effective-dart/usage#const%EB%A5%BC-%EB%B6%88%ED%95%84%EC%9A%94%ED%95%98%EA%B2%8C-%EC%82%AC%EC%9A%A9%ED%95%98%EC%A7%80-%EB%A7%88%EC%8B%AD%EC%8B%9C%EC%98%A4

 

효과적인 Dart: 사용법

언어 기능을 사용하여 유지 관리 가능한 코드를 작성하기 위한 가이드라인.

dart-ko.dev