Flutter 튜토리얼 54편: 웹 성능 최적화

Flutter 웹 성능 최적화#

Flutter 웹 앱은 모바일과 다른 성능 특성을 가집니다. 이 튜토리얼에서는 웹 환경에서 Flutter 앱의 성능을 측정하고 최적화하는 방법을 배웁니다.

학습 목표#

  • Flutter 웹의 렌더링 방식 이해하기
  • Chrome DevTools로 성능 분석하기
  • 웹 특화 최적화 기법 적용하기
  • 프로파일 모드 활용하기

1. Flutter 웹의 특성#

Why: 웹 환경이 다른 이유#

Flutter 웹은 모바일과 다른 환경에서 실행됩니다. 브라우저 위에서 동작하므로 브라우저의 특성과 제약을 이해해야 합니다.

What: 렌더러 옵션#

Flutter 웹은 두 가지 렌더러1를 제공합니다.

flowchart TD A[Flutter 웹] --> B{렌더러 선택} B --> C[HTML 렌더러] B --> D[CanvasKit 렌더러] C --> C1[작은 다운로드 크기] C --> C2[빠른 초기 로드] C --> C3[텍스트 렌더링 차이] D --> D1[일관된 렌더링] D --> D2[더 나은 성능] D --> D3[큰 다운로드 크기]
렌더러장점단점적합한 경우
HTML작은 크기, 빠른 초기 로드렌더링 차이 발생 가능텍스트 중심 앱
CanvasKit일관된 렌더링, 애니메이션 성능큰 초기 로드그래픽 중심 앱
auto환경에 맞게 자동 선택예측 어려움일반적인 경우

How: 렌더러 지정하기#

Terminal window
# CanvasKit으로 빌드
flutter build web --web-renderer canvaskit
# HTML로 빌드
flutter build web --web-renderer html
# 자동 선택 (기본값)
flutter build web --web-renderer auto

실행 시에도 렌더러를 지정할 수 있습니다:

Terminal window
# CanvasKit으로 실행
flutter run -d chrome --web-renderer canvaskit

Watch out: 주의사항#

CanvasKit은 약 2MB의 추가 다운로드가 필요합니다. 모바일 웹 사용자가 많다면 초기 로드 시간을 고려하여 HTML 렌더러를 선택할 수 있습니다.


2. Chrome DevTools 활용#

Why: Chrome DevTools가 필요한 이유#

Flutter DevTools는 Dart 코드 레벨의 성능을 분석합니다. 웹 앱의 전체적인 성능(네트워크, JavaScript, 렌더링)은 Chrome DevTools로 분석해야 합니다.

What: Performance 패널 이해하기#

flowchart TD A[Chrome DevTools] --> B[Performance 패널] B --> C[녹화 시작] C --> D[앱 사용] D --> E[녹화 중지] E --> F[분석] F --> F1[Main Thread] F --> F2[Compositor] F --> F3[GPU] F --> F4[Network]

How: 성능 녹화하기#

  1. Chrome에서 Flutter 웹 앱을 엽니다
  2. F12를 눌러 DevTools를 엽니다
  3. Performance 탭을 선택합니다
  4. 녹화 버튼(⏺)을 클릭하거나 Ctrl+E를 누릅니다
  5. 성능을 측정할 동작을 수행합니다
  6. 녹화 중지 버튼을 클릭합니다

How: Timeline 분석하기#

녹화 결과에서 다음을 확인합니다:

색상의미문제 시 조치
노란색JavaScript 실행Dart 코드 최적화
보라색레이아웃/스타일 계산위젯 트리 단순화
녹색페인팅리페인트 최소화
회색유휴 시간정상

How: 특정 구간 분석하기#

sequenceDiagram participant U as 사용자 동작 participant M as Main Thread participant R as Rendering U->>M: 버튼 클릭 M->>M: JavaScript 실행 M->>R: 렌더링 요청 R->>R: 레이아웃 계산 R->>R: 페인트 R-->>U: 화면 업데이트

프레임 드롭이 발생한 구간을 확대하여 어떤 작업이 오래 걸렸는지 확인합니다.

Watch out: 주의사항#

Chrome DevTools의 Performance 탭은 많은 정보를 표시합니다. 처음에는 Main Thread와 FPS 그래프에 집중하세요. 빨간색 막대가 있는 곳이 성능 문제가 발생한 지점입니다.


3. 디버그 플래그 활용#

Why: 상세한 타이밍 정보가 필요한 이유#

Chrome DevTools는 전체적인 성능을 보여주지만, Flutter 내부에서 어떤 작업이 오래 걸렸는지는 알 수 없습니다. 디버그 플래그를 사용하면 Flutter 내부의 타이밍 정보를 확인할 수 있습니다.

What: 사용 가능한 디버그 플래그#

import 'package:flutter/rendering.dart';
// 위젯 빌드 타이밍
bool debugProfileBuildsEnabled = false;
// 사용자 위젯만 프로파일링
bool debugProfileBuildsEnabledUserWidgets = false;
// 레이아웃 타이밍
bool debugProfileLayoutsEnabled = false;
// 페인트 타이밍
bool debugProfilePaintsEnabled = false;
플래그측정 대상사용 시점
debugProfileBuildsEnabled모든 위젯 빌드빌드 병목 찾기
debugProfileBuildsEnabledUserWidgets사용자 위젯만내 코드에 집중
debugProfileLayoutsEnabled레이아웃 계산레이아웃 병목 찾기
debugProfilePaintsEnabled페인팅렌더링 병목 찾기

How: 디버그 플래그 활성화#

import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/material.dart';
void main() {
// 프로파일/디버그 모드에서만 활성화
if (kDebugMode || kProfileMode) {
debugProfileBuildsEnabled = true;
debugProfileBuildsEnabledUserWidgets = true;
debugProfileLayoutsEnabled = true;
debugProfilePaintsEnabled = true;
}
runApp(const MyApp());
}

How: 타임라인에서 확인하기#

디버그 플래그를 활성화한 후 Chrome DevTools의 Performance 패널에서 녹화하면 Flutter 이벤트가 타임라인에 표시됩니다:

Build: MyHomePage (1.2ms)
Build: Scaffold (0.8ms)
Build: AppBar (0.3ms)
Build: Column (0.5ms)
Layout: RenderFlex (0.4ms)
Paint: RenderDecoratedBox (0.2ms)

Watch out: 주의사항#

디버그 플래그는 성능에 영향을 줍니다. 배포 빌드에서는 반드시 비활성화해야 합니다. kDebugMode 또는 kProfileMode 체크를 잊지 마세요.


4. 프로파일 모드 사용#

Why: 프로파일 모드가 필요한 이유#

디버그 모드는 많은 검사와 디버깅 기능이 활성화되어 있어 실제 성능을 측정하기 어렵습니다. 프로파일 모드는 릴리스에 가까운 성능을 보여주면서 디버깅 도구를 사용할 수 있습니다.

What: 빌드 모드 비교#

flowchart LR A[빌드 모드] --> B[Debug] A --> C[Profile] A --> D[Release] B --> B1[느림, 디버깅 가능] C --> C1[빠름, 디버깅 가능] D --> D1[가장 빠름, 디버깅 불가]
모드JIT/AOT성능디버깅
DebugJIT느림전체 가능
ProfileAOT빠름제한적 가능
ReleaseAOT가장 빠름불가

How: 프로파일 모드로 실행#

Terminal window
# 웹에서 프로파일 모드 실행
flutter run -d chrome --profile

VS Code 설정:

{
"configurations": [
{
"name": "Flutter Web (Profile)",
"request": "launch",
"type": "dart",
"deviceId": "chrome",
"flutterMode": "profile"
}
]
}

How: 프로파일 빌드 후 테스트#

Terminal window
# 프로파일 모드로 빌드
flutter build web --profile
# 로컬 서버로 테스트
cd build/web
python -m http.server 8000
# 브라우저에서 http://localhost:8000 접속

Watch out: 주의사항#

웹에서 프로파일 모드는 flutter run으로만 사용할 수 있습니다. 정적 파일로 빌드하면 프로파일 기능을 사용할 수 없으니 주의하세요.


5. 웹 특화 최적화#

Why: 웹만의 최적화가 필요한 이유#

웹 환경은 모바일과 다른 특성이 있습니다. 네트워크 지연, 브라우저 캐싱, 초기 로드 시간 등을 고려해야 합니다.

What: 초기 로드 최적화#

flowchart TD A[초기 로드 최적화] --> B[지연 로딩] A --> C[트리 쉐이킹] A --> D[압축] A --> E[캐싱] B --> B1[deferred 임포트] C --> C1[사용하지 않는 코드 제거] D --> D1[gzip/brotli 압축] E --> E1[Service Worker]

How: 지연 로딩 구현#

// 지연 임포트 선언
import 'package:myapp/features/heavy_feature.dart' deferred as heavy;
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
routes: {
'/': (context) => const HomePage(),
'/heavy': (context) => FutureBuilder(
future: heavy.loadLibrary(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return heavy.HeavyFeaturePage();
}
return const LoadingPage();
},
),
},
);
}
}

How: 이미지 최적화#

// 웹에 최적화된 이미지 로딩
Image.network(
'https://example.com/image.webp', // WebP 형식 사용
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return Center(
child: CircularProgressIndicator(
value: loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded /
loadingProgress.expectedTotalBytes!
: null,
),
);
},
)

How: 폰트 최적화#

pubspec.yaml
flutter:
fonts:
- family: Roboto
fonts:
- asset: fonts/Roboto-Regular.ttf
- asset: fonts/Roboto-Bold.ttf
weight: 700

웹에서는 폰트 서브세팅을 고려하세요:

// 사용하는 글자만 포함된 폰트 사용
// 또는 Google Fonts의 텍스트 파라미터 활용

What: 렌더링 최적화#

// 불필요한 리빌드 방지
class OptimizedWidget extends StatelessWidget {
const OptimizedWidget({super.key}); // const 생성자
@override
Widget build(BuildContext context) {
return const Column( // const 위젯
children: [
Text('고정 텍스트'),
Icon(Icons.star),
],
);
}
}
// RepaintBoundary로 리페인트 영역 제한
RepaintBoundary(
child: ComplexAnimatedWidget(),
)

Watch out: 주의사항#

지연 로딩을 과도하게 사용하면 사용자 경험이 저하될 수 있습니다. 자주 사용하는 기능은 메인 번들에 포함시키고, 드물게 사용하는 대용량 기능만 지연 로딩하세요.


6. 웹 성능 체크리스트#

초기 로드 최적화#

  • 적절한 렌더러 선택 (HTML/CanvasKit)
  • 지연 로딩 적용
  • 이미지 최적화 (WebP, 적절한 크기)
  • 폰트 최적화 (서브세팅)
  • 불필요한 패키지 제거

런타임 성능#

  • const 생성자 활용
  • 불필요한 리빌드 방지
  • RepaintBoundary 적절히 사용
  • 무거운 작업은 분리 (Isolate/Web Worker)

측정 및 분석#

  • 프로파일 모드로 테스트
  • Chrome DevTools Performance 분석
  • Lighthouse 점수 확인
  • 실제 디바이스에서 테스트

마무리#

이번 튜토리얼에서는 Flutter 웹 앱의 성능을 측정하고 최적화하는 방법을 배웠습니다.

핵심 정리#

주제핵심 내용
렌더러 선택HTML (빠른 로드) vs CanvasKit (일관된 렌더링)
분석 도구Chrome DevTools Performance 패널
디버그 플래그debugProfileBuildsEnabled 등
최적화 전략지연 로딩, const, RepaintBoundary

다음 단계#


참고 자료#

Footnotes#

  1. 렌더러(Renderer)는 Flutter 위젯을 실제 화면에 그리는 엔진입니다. 웹에서는 HTML 또는 CanvasKit 중 선택할 수 있습니다.

공유

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

Flutter 튜토리얼 54편: 웹 성능 최적화
https://moodturnpost.net/posts/flutter/flutter-performance-web/
작성자
Moodturn
게시일
2026-01-08
Moodturn

목차