Flutter 튜토리얼 48편: 디버깅 도구 활용

요약#

핵심 요지#

  • 문제 정의: 앱이 예상대로 동작하지 않을 때 원인을 찾아야 한다. 로그만으로는 복잡한 문제를 파악하기 어렵다.
  • 핵심 주장: Flutter는 IDE 디버거, DevTools1, 코드 기반 디버깅 플래그를 제공해서 다양한 문제를 진단할 수 있다.
  • 주요 근거: 위젯 트리, 렌더 트리, 레이어 트리를 덤프해서 레이아웃 문제를 찾고, 성능 오버레이로 프레임 드랍을 확인할 수 있다.
  • 실무 기준: 간단한 문제는 로그로, 복잡한 레이아웃 문제는 인스펙터로, 성능 문제는 DevTools로 진단한다.
  • 한계: 디버그 모드에서만 작동하는 기능이 많아서 릴리스 빌드의 문제는 별도 접근이 필요하다.

문서가 설명하는 범위#

  • DevTools 개요와 주요 기능
  • IDE 내장 디버거와 브레이크포인트
  • 로깅 (print, log, debugPrint)
  • 위젯/렌더/레이어/포커스/시맨틱 트리 덤프
  • 레이아웃 디버깅 플래그
  • 성능 오버레이

읽는 시간: 20분 | 난이도: 초급


참고 자료#


문제 상황#

앱 개발 중 다양한 문제가 발생합니다.

자주 겪는 디버깅 상황#

// 문제 1: 위젯이 원하는 크기로 표시되지 않음
Container(
width: 100, // 왜 100px이 아니지?
child: Text('Hello'),
)
// 문제 2: 버튼 탭이 동작하지 않음
GestureDetector(
onTap: () => print('탭!'), // 왜 호출이 안 되지?
child: Container(color: Colors.blue),
)
// 문제 3: 앱이 버벅거림
ListView.builder(
itemCount: 1000,
itemBuilder: (context, index) {
// 어디서 성능 병목이 발생하지?
return ExpensiveWidget();
},
)

이런 문제들은 코드만 봐서는 원인을 찾기 어렵습니다. 디버깅 도구가 필요합니다.


해결 방법#

Flutter는 다양한 디버깅 도구를 제공합니다.

graph TD A[디버깅 도구] --> B[IDE 디버거] A --> C[DevTools] A --> D[코드 기반 도구] B --> E[브레이크포인트, 변수 검사] C --> F[인스펙터, 성능, 메모리] D --> G[로깅, 트리 덤프, 플래그]

챕터 1: IDE 디버거와 브레이크포인트#

Why#

NOTE

IDE 디버거는 가장 기본적인 디버깅 도구입니다. 코드 실행을 중단하고 변수 값을 검사할 수 있습니다.

지원 IDE:

  • VS Code (Flutter/Dart 확장 필요)
  • Android Studio / IntelliJ (Flutter 플러그인 필요)

What#

NOTE

브레이크포인트 설정 방법:

  1. IDE에서 설정: 라인 번호 왼쪽 클릭
  2. 코드에서 설정: debugger() 함수 사용
import 'dart:developer';
void someFunction(double offset) {
// offset이 30을 초과하면 중단
debugger(when: offset > 30);
// 이후 코드...
}

How#

TIP

VS Code 디버깅 단축키:

단축키동작
F5디버그 시작
F9브레이크포인트 토글
F10Step Over (다음 줄)
F11Step Into (함수 내부)
Shift+F11Step Out (함수 밖으로)

변수 검사:

브레이크포인트에서 중단되면 Debug 패널에서 변수 값을 확인할 수 있습니다. Watch 패널에 표현식을 추가해서 복잡한 값도 검사할 수 있습니다.

Watch out#

WARNING

디버그 모드 주의: 디버그 모드는 릴리스 모드보다 느립니다. 성능 문제를 진단할 때는 프로필 모드(--profile)를 사용하세요.


챕터 2: 로깅 기법#

Why#

NOTE

로깅은 가장 간단한 디버깅 방법입니다. 코드 실행 흐름과 변수 값을 확인할 수 있습니다.

What#

NOTE

로깅 함수 비교:

함수용도라이브러리
print()기본 출력dart
debugPrint()긴 출력 (잘림 방지)foundation
log()상세 로깅dart
stderr.writeln()에러 출력dart
import 'dart:developer' as developer;
// 기본 로깅
print('간단한 메시지');
// 긴 메시지 (잘리지 않음)
debugPrint('아주 긴 JSON 데이터...');
// 상세 로깅 (DevTools에서 필터링 가능)
developer.log(
'사용자 로그인',
name: 'auth.login',
error: jsonEncode({'userId': 123}),
);

How#

TIP

log() 함수의 장점:

import 'dart:developer' as developer;
void fetchUserData() {
developer.log(
'API 호출 시작',
name: 'api.user', // 카테고리 (필터링 가능)
time: DateTime.now(), // 타임스탬프
);
try {
// API 호출...
developer.log('API 호출 성공', name: 'api.user');
} catch (e) {
developer.log(
'API 호출 실패',
name: 'api.user',
error: e.toString(), // 에러 정보 (JSON 권장)
level: 1000, // 에러 레벨
);
}
}

DevTools Logging 뷰에서 name으로 로그를 필터링할 수 있습니다.

Watch out#

WARNING

릴리스 빌드에서 로그 제거:

print()는 릴리스 빌드에서도 출력됩니다. 성능과 보안을 위해 조건부 출력을 사용하세요.

import 'package:flutter/foundation.dart';
if (kDebugMode) {
print('디버그에서만 출력');
}

또는 debugPrint()를 사용하면 됩니다. 이 함수는 디버그 모드 체크 없이도 릴리스에서 무시됩니다.


챕터 3: DevTools 활용#

Why#

NOTE

DevTools는 Flutter 앱을 분석하는 웹 기반 도구입니다. 위젯 구조, 성능, 메모리, 네트워크 등을 시각적으로 분석할 수 있습니다.

What#

NOTE

DevTools 주요 기능:

기능
Flutter Inspector위젯 트리, 레이아웃 시각화
Performance프레임 타이밍, CPU 프로파일링
Memory메모리 사용량, 누수 감지
NetworkHTTP 요청/응답 모니터링
Logging로그 뷰어, 필터링
Debugger소스 레벨 디버깅

How#

TIP

DevTools 실행 방법:

방법 1: VS Code

  1. 앱 디버그 모드로 실행
  2. 명령 팔레트 (Cmd/Ctrl + Shift + P)
  3. “Dart: Open DevTools” 선택

방법 2: 커맨드 라인

Terminal window
# 앱 실행
flutter run
# 콘솔에 표시된 URL에서 DevTools 열기
# 예: http://127.0.0.1:9100

방법 3: Android Studio

  1. 앱 디버그 모드로 실행
  2. 하단 “Flutter Inspector” 탭 클릭
  3. “Open DevTools” 버튼 클릭

챕터 4: 위젯 인스펙터#

Why#

NOTE

위젯 인스펙터는 위젯 트리를 시각적으로 탐색할 수 있게 해줍니다. 레이아웃 문제, 예상치 못한 위젯 구조를 파악할 때 유용합니다.

What#

NOTE

인스펙터 기능:

  • Select Widget Mode: 앱 화면에서 위젯을 탭해서 선택
  • Widget Tree: 위젯 계층 구조 표시
  • Layout Explorer: 위젯 크기와 제약 조건 시각화
  • Details Tree: 선택한 위젯의 속성 표시

How#

TIP

코드에서 위젯 트리 덤프:

DevTools 없이도 위젯 트리를 확인할 수 있습니다.

import 'package:flutter/material.dart';
class AppHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Material(
child: Center(
child: TextButton(
onPressed: () {
// 위젯 트리 덤프
debugDumpApp();
},
child: const Text('Dump Widget Tree'),
),
),
);
}
}

콘솔에 전체 위젯 트리가 출력됩니다.

출력 예시:

MyApp
└TextButton(dirty, dependencies: [MediaQuery, _InheritedTheme])
└Text('Dump Widget Tree')

dirty는 위젯이 다시 빌드되어야 함을 의미합니다.


챕터 5: 렌더 트리와 레이어 트리#

Why#

NOTE

레이아웃 문제는 위젯 트리만으로 파악하기 어려울 때가 있습니다. 렌더 트리는 실제 레이아웃 계산 결과를 보여줍니다.

What#

NOTE

트리 덤프 함수:

함수용도
debugDumpApp()위젯 트리 덤프
debugDumpRenderTree()렌더 트리 덤프 (크기, 제약조건)
debugDumpLayerTree()레이어 트리 덤프 (합성 정보)
debugDumpFocusTree()포커스 트리 덤프
debugDumpSemanticsTree()시맨틱 트리 덤프 (접근성)

How#

TIP

렌더 트리로 레이아웃 디버깅:

TextButton(
onPressed: () {
debugDumpRenderTree();
},
child: const Text('Dump Render Tree'),
)

출력에서 확인할 정보:

RenderPositionedBox#dc1df
│ constraints: BoxConstraints(w=800.0, h=600.0) // 제약조건
│ size: Size(800.0, 600.0) // 실제 크기
│ alignment: Alignment.center
└─child: RenderPadding#8455f
│ constraints: BoxConstraints(56.0<=w<=800.0, 28.0<=h<=600.0)
│ size: Size(100.0, 48.0)
│ padding: EdgeInsets(8.0, 0.0, 8.0, 0.0)
  • constraints: 부모가 전달한 제약조건
  • size: 위젯이 결정한 크기
  • 제약조건이 예상과 다르면 레이아웃 문제의 원인

relayoutBoundary: 이 값이 크면 작은 변경에도 많은 위젯이 다시 레이아웃됩니다. 성능 최적화 포인트입니다.


챕터 6: 레이아웃 디버깅 플래그#

Why#

NOTE

코드 기반 플래그는 앱 전체에 시각적 디버깅 정보를 오버레이합니다. 빠르게 레이아웃 문제를 파악할 수 있습니다.

What#

NOTE

주요 디버깅 플래그:

플래그효과
debugPaintSizeEnabled모든 박스에 테두리 표시
debugPaintBaselinesEnabled텍스트 기준선 표시
debugPaintPointersEnabled탭 영역 강조
debugPaintLayerBordersEnabled레이어 경계 표시
debugRepaintRainbowEnabled리페인트 영역 색상 표시

How#

TIP

레이아웃 디버깅 활성화:

import 'package:flutter/rendering.dart';
void main() {
debugPaintSizeEnabled = true; // 박스 테두리 표시
runApp(const MyApp());
}

표시되는 정보:

  • 청록색 테두리: 모든 박스의 경계
  • 파란색 영역: 패딩
  • 노란색 화살표: 정렬 방향
  • 회색 영역: 자식이 없는 Spacer

탭 영역 디버깅:

버튼이 눌리지 않을 때 유용합니다.

debugPaintPointersEnabled = true;

탭하면 탭 가능한 영역이 청록색으로 표시됩니다. 표시되지 않으면 위젯이 히트 테스트 영역 밖에 있는 것입니다.


챕터 7: 성능 오버레이#

Why#

NOTE

성능 오버레이는 실시간으로 프레임 렌더링 성능을 보여줍니다. UI 버벅거림(jank) 원인을 빠르게 파악할 수 있습니다.

What#

NOTE

성능 오버레이 구성:

  • 상단 그래프: GPU 스레드 (래스터라이저)
  • 하단 그래프: UI 스레드 (Dart 코드)

녹색 선: 16ms (60fps 목표) 선을 넘으면 프레임 드랍 발생

How#

TIP

코드에서 성능 오버레이 활성화:

import 'package:flutter/material.dart';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
showPerformanceOverlay: true, // 성능 오버레이 표시
title: 'My App',
home: const MyHomePage(),
);
}
}

DevTools에서 활성화:

Flutter Inspector에서 “Performance Overlay” 버튼을 클릭합니다.

해석 방법:

  • UI 스레드 느림: Dart 코드 최적화 필요 (빌드 메서드, 애니메이션)
  • GPU 스레드 느림: 복잡한 그래픽, 큰 이미지, 과도한 클리핑

챕터 8: 애니메이션 디버깅#

Why#

NOTE

애니메이션 문제는 정상 속도에서 파악하기 어렵습니다. 애니메이션을 느리게 해서 문제를 찾을 수 있습니다.

What#

NOTE

애니메이션 속도 조절:

방법 1: DevTools

Flutter Inspector에서 “Slow Animations” 버튼 클릭 (20% 속도로 재생)

방법 2: 코드

import 'package:flutter/scheduler.dart';
void main() {
// 50배 느리게 (50.0 = 1/50 속도)
timeDilation = 50.0;
runApp(const MyApp());
}

How#

TIP

timeDilation 사용 주의:

// 앱 시작 시 한 번만 설정
void main() {
timeDilation = 5.0; // 5배 느리게
runApp(const MyApp());
}
// 실행 중 변경하지 마세요!
// 특히 줄이면 시간이 역행하는 것처럼 보여서 문제 발생

기본값 복원:

디버깅이 끝나면 timeDilation = 1.0으로 복원하거나 코드를 제거하세요.


챕터 9: 프레임 타이밍 디버깅#

Why#

NOTE

특정 작업이 프레임 예산(16ms)을 초과하는지 확인해야 할 때가 있습니다. 프레임 배너를 출력해서 확인할 수 있습니다.

What#

NOTE

프레임 타이밍 플래그:

import 'package:flutter/scheduler.dart';
void main() {
debugPrintBeginFrameBanner = true; // 프레임 시작
debugPrintEndFrameBanner = true; // 프레임 끝
runApp(const MyApp());
}

출력 예시:

I/flutter : ▄▄▄▄▄▄▄▄ Frame 12 30s 437.086ms ▄▄▄▄▄▄▄▄
I/flutter : Debug print: 내 로그 메시지
I/flutter : ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀

How#

TIP

Timeline API로 상세 성능 측정:

import 'dart:developer';
void expensiveOperation() {
Timeline.startSync('expensive_operation');
// 측정할 코드
for (int i = 0; i < 1000000; i++) {
// 복잡한 계산
}
Timeline.finishSync();
}

DevTools Performance 탭에서 expensive_operation 구간을 확인할 수 있습니다.


한계#

디버깅 도구에는 몇 가지 제한이 있습니다.

디버그 모드 한정: 대부분의 디버깅 플래그와 기능은 디버그 모드에서만 작동합니다. 릴리스 빌드의 문제는 로깅과 크래시 리포팅 서비스에 의존해야 합니다.

성능 영향: 디버그 모드는 릴리스 모드보다 훨씬 느립니다. 정확한 성능 측정은 프로필 모드(flutter run --profile)에서 수행하세요.

네이티브 코드 디버깅: Flutter 디버거는 Dart 코드만 디버깅합니다. 네이티브 코드(Kotlin, Swift)는 Android Studio나 Xcode의 네이티브 디버거를 사용해야 합니다.

다음 튜토리얼에서는 에러 처리와 보고 방법을 알아봅니다.

Footnotes#

  1. DevTools(데브툴즈): Flutter 앱의 성능, 메모리, 레이아웃을 분석하는 웹 기반 개발 도구다.

공유

이 글이 도움이 되었다면 다른 사람과 공유해주세요!

Flutter 튜토리얼 48편: 디버깅 도구 활용
https://moodturnpost.net/posts/flutter/flutter-debugging-tools/
작성자
Moodturn
게시일
2026-01-08
Moodturn

목차