Flutter에서 네트워크 요청은 메인 스레드를 막을까?
dart는 싱글 스레드 환경에서 동작합니다.
dart로 작성된 프로그램이 실행되면 이벤트가 큐에 들어가기 위한 이벤트 큐가 있고 이벤트 큐에 대기하고 있는 이벤트들을 주기적으로 처리합니다.
네트워크 I/O는 논블로킹이라 메인 Isolate(UI)를 막지 않습니다.
안드로이드에서 네트워크 작업이나 시간이 오래걸리는 DB I/O나 네트워크 요청 작업은 Coroutine Dispatcher로 목적에 맞는 Thread로 전환해 무거운 작업도 빠르게 처리가 가능합니다. 이와 비슷하게 Flutter에서는 CPU 바운드 작업(큰 파싱/압축/암호화/ML 등)은 별도 Isolate로 분리해야 프레임 드랍을 막을 수 있습니다
Isolate: 독립된 메모리 힙과 자신만의 이벤트 큐를 가진 실행 단위
이벤트 루프: 큐에 쌓인 일을 순차적으로 처리
event queue: I/O 완료, 타이머, UI 이벤트
하나의 Isolate는 동시에 한 일만 한다(=한 코어만 사용) 병렬 CPU가 필요하면 Isolate를 여러 개 쓴다.
await http.get(url)을 호출하면 dart의 HttpClient가 요청을 시작하고 즉시 Future를 반환합니다.
이 때문에 UI Isolate는 계속 다른 일을 처리 가능합니다.
운영체제의 네트워크 스택 + Dart VM의 I/O 핸들러가 소켓 상태를 감시·대기합니다.
즉 대기는 OS/런타임이 하고 Dart 코드는 멈춰 있지 않습니다.
데이터가 준비되면 이벤트 큐에 콜백 등록 한 후 UI Isolate의 루프가 자기 차례에 그 콜백을 실행합니다.
그때 await 다음 줄이 이어서 실행됩니다.
이에 따라 동시에 여러 요청을 보내도 UI가 멈추지 않습니다.
현대 모바일은 여러 코어를 가지는데 1 Isolate = 보통 1 스레드 → 그 Isolate의 Dart 코드는 한 코어에서만 돈다고 할 수 있습니다.
여러 Isolate를 만들면 서로 다른 코어에서 병렬로 실행 가능하지만 공식문서에 따르면 권장 되지 않는다고 합니다.
논블로킹은 호출이 즉시 반환되고 완료는 이벤트로 통지되는 모델을 뜻합니다.
별도 프로세스를 만드는 게 아닌 OS가 소켓 상태를 관리하고 Dart VM의 I/O 핸들러가 이벤트 큐에 콜백을 올려 UI Isolate가 그걸 처리합니다.
무거운 연산(=CPU 바운드) 작업 상황에서 필요하다.
예시: 대용량 JSON 파싱/변환, 암호화/압축/디코딩, 복잡한 정규식/토크나이징
Isonlate는 CPU 코어 수 + 2가 보통 적당하다고 합니다. 하지만 무조건 정답은 아니기에 최소 개수로 세팅한 후 개발을 하며 조정하는 것이 권장됩니다.
안드로이드: Dispatchers.IO(스레드 풀)에 블로킹 I/O/파일 작업을 맡김 → Main 스레드 블로킹 방지
Retrofit/OkHttp는 내부적으로 백그라운드 스레드에서 요청 처리
Flutter/Dart: 기본 철학이 비동기 I/O → await만 쓰면 UI Isolate는 안 막힘
무거운 후처리는 Isolate.run/compute로 분리