Flutter가 싱글스레드로 되어있다?

seunghee song·2025년 8월 26일

Flutter에서 네트워크 요청은 메인 스레드를 막을까?

dart는 싱글 스레드 환경에서 동작합니다.
dart로 작성된 프로그램이 실행되면 이벤트가 큐에 들어가기 위한 이벤트 큐가 있고 이벤트 큐에 대기하고 있는 이벤트들을 주기적으로 처리합니다.

부하가 큰 작업이나 네트워크 요청은 어떻게 하나요?

네트워크 I/O는 논블로킹이라 메인 Isolate(UI)를 막지 않습니다.
안드로이드에서 네트워크 작업이나 시간이 오래걸리는 DB I/O나 네트워크 요청 작업은 Coroutine Dispatcher로 목적에 맞는 Thread로 전환해 무거운 작업도 빠르게 처리가 가능합니다. 이와 비슷하게 Flutter에서는 CPU 바운드 작업(큰 파싱/압축/암호화/ML 등)은 별도 Isolate로 분리해야 프레임 드랍을 막을 수 있습니다

Dart 실행 과정 요약

Isolate: 독립된 메모리 힙과 자신만의 이벤트 큐를 가진 실행 단위

이벤트 루프: 큐에 쌓인 일을 순차적으로 처리

event queue: I/O 완료, 타이머, UI 이벤트

하나의 Isolate는 동시에 한 일만 한다(=한 코어만 사용) 병렬 CPU가 필요하면 Isolate를 여러 개 쓴다.

네트워크 I/O는 왜 UI를 막지 않나?

await http.get(url)을 호출하면 dart의 HttpClient가 요청을 시작하고 즉시 Future를 반환합니다.
이 때문에 UI Isolate는 계속 다른 일을 처리 가능합니다.

운영체제의 네트워크 스택 + Dart VM의 I/O 핸들러가 소켓 상태를 감시·대기합니다.
즉 대기는 OS/런타임이 하고 Dart 코드는 멈춰 있지 않습니다.

데이터가 준비되면 이벤트 큐에 콜백 등록 한 후 UI Isolate의 루프가 자기 차례에 그 콜백을 실행합니다.
그때 await 다음 줄이 이어서 실행됩니다.
이에 따라 동시에 여러 요청을 보내도 UI가 멈추지 않습니다.

1 Isolate 1 코어

현대 모바일은 여러 코어를 가지는데 1 Isolate = 보통 1 스레드 → 그 Isolate의 Dart 코드는 한 코어에서만 돈다고 할 수 있습니다.
여러 Isolate를 만들면 서로 다른 코어에서 병렬로 실행 가능하지만 공식문서에 따르면 권장 되지 않는다고 합니다.

여기서 잠깐! non blocking 이란?

논블로킹은 호출이 즉시 반환되고 완료는 이벤트로 통지되는 모델을 뜻합니다.
별도 프로세스를 만드는 게 아닌 OS가 소켓 상태를 관리하고 Dart VM의 I/O 핸들러가 이벤트 큐에 콜백을 올려 UI Isolate가 그걸 처리합니다.

그렇다면 언제 새로운 Isolate를 만들어 써야 할까?

무거운 연산(=CPU 바운드) 작업 상황에서 필요하다.
예시: 대용량 JSON 파싱/변환, 암호화/압축/디코딩, 복잡한 정규식/토크나이징
Isonlate는 CPU 코어 수 + 2가 보통 적당하다고 합니다. 하지만 무조건 정답은 아니기에 최소 개수로 세팅한 후 개발을 하며 조정하는 것이 권장됩니다.

안드로이드와 비교해서 이해하기

안드로이드: Dispatchers.IO(스레드 풀)에 블로킹 I/O/파일 작업을 맡김 → Main 스레드 블로킹 방지
Retrofit/OkHttp는 내부적으로 백그라운드 스레드에서 요청 처리

Flutter/Dart: 기본 철학이 비동기 I/O → await만 쓰면 UI Isolate는 안 막힘
무거운 후처리는 Isolate.run/compute로 분리

profile
초코송이 개발자

0개의 댓글