Flutter 란?

Flutter는 구글에서 2017년도에 발표한 dart 언어를 기반으로 한 오픈소스 크로스 플랫폼 GUI 프레임 워크입니다.
지원 플랫폼은 Android, IOS, Mac OS, Window, Linux, Web이 있습니다.

이번 주제에서는 Flutter가 어떻게 Multi Platform 을 지원하는가 에 대해 알아보겠습니다.

다양한 Multi Platform 지원 방법론

Native App

native_app_architecture.jpg 작성한 코드를 통해 직접적으로 Platform OEM Widget을 호출 하여 렌더링 하고
하드웨어 서비스에 접근 하는것을 볼 수 있습니다

Hybrid App

hybrid_app_architecture.jpg UI렌더링은 Js를 이용해 WebView를 통해서 진행하고
Platform service는 Bridge를 통해 접근 합니다.

해당 방법의 단점은 WebView 특성상 자연스럽지 않은 제스처나 UI렌더링.
Platform 위젯 사용 불가 및 떨어지는 성능등이 있을 수 있고
Platform service는 Bridge를 통해 제어를 하긴 하지만 구현이 어렵고 Bridge 호출 비용이 크다는 단점이 있습니다.

React Native

react_native_architecture.jpg hybrid app과는 다르게 WebView를 사용하지 않고 Platform OEM Widget을 사용해 렌더링 합니다.
그러나 마찬가지로 js를 이용해 Bridge를 통해서 Platform UI에 접근하여 UI를 렌더링 하고
Service도 마찬가지로 Bridge를 통해 접근 하는것을 확인 할 수 있습니다.
Bridge를 사용하는 방식은 앞서 Bridge 호출 비용이 커 성능 이슈가 발생할 수 있으며
Platform OEM widget을 통해 렌더링 하기 때문에 플랫폼 별로 UI가 다르게 나타날 수 있습니다.
만약 UI 또는 제스처가 통일 되어야 하는 앱이라면 해당 점도 큰 단점으로 다가 올 수 있습니다.

Flutter

flutter_architecture.jpg 반면 Flutter의 간략한 아키텍처를 보면 다른 Multi Platform 구조 와는 다르게 App 에서 진행 합니다.
이는 빠른 렌더링 뿐 아니라 멀티 플랫폼에서 통일성있는 UI를 제공할 수 있다는 아주 큰 장점이 있습니다.
조금 더 상세한 구조는 아래에서 확인 해 보겠습니다.

Flutter의 Multi Platform

flutter_architecture_detail.png Flutter의 상세 아키텍처로 목적에 따라 계층이 구분 됩니다.

  • Framework 계층
    간단하게 dart nativ로 작성되어 Flutter api와 직접 작성한 dart 코드들이 있는 계층입니다.
  • Engine 계층
    C 와 C++로 작성되어 low level에서 UI렌더링, 하위 Embedder계층의 Api를 사용하여
    Framework 계층에 기능을 제공등을 하여 Flutter가 멀티 플랫폼을 구현 할 수 있게 해주는 핵심 계층입니다.
  • Embedder 계층
    Platform Api, 이벤트 루프, 제스처 터치 등 행위 감지 기능 등을 포함한 계층입니다.

이중 Flutter 의 Multi Platform 방법론을 위해 중점적으로 소개 드릴 계층은
Engine 계층, 특히 Rendering, Platform Channels 관련을 중점적으로 알아보겠습니다.

SKIA Engine

Flutter가 APP 수준에서 Rendering을 하기위해 사용하는 기술은 SKIA 입니다.
Skia 엔진은 C++로 개발 된 오픈 소스 2D 그래픽 라이브러리로 OpenGL을 사용합니다.
OpenGL을 사용한 SKIA는 Window, MacOs, Ios, Android, Linux, Web 모든 플랫폼에서 사용 가능 하며
flutter 가 Multi Platform을 지원 할 수 있게 된 핵심 요소중 하나 입니다.

그러나 이런 SKIA에도 문제가 있습니다.
Skia 엔진은 기본적으로 화면 렌더링이 60hz로 동작하도록 설계되어 화면을 업데이트 합니다.
따라서 해당 조건을 만족하기 위해서는 1프레임당 16.7ms 안에 렌더링을 완료 해야 합니다.
만약 그러지 못한다면 새로운 UI가 그려지지 않고 화면은 업데이트 되지 않아 사용자는 버벅인다고 느낄 수 있습니다.
이때 스키아 엔진이 렌더링 하는 과정을 간략하게 살펴보면
Flutter Framework에서 작성된 UI들을 SKIA가 GPU에서 컴파일 할 수 있도록 Shader를 생성하고
이를 GPU에서 컴파일 합니다 이때 해당 작업은 최대 200ms 까지도 거릴수 있는 높은 부하를 가지는 작업이고
컴파일 과정이 런타임에서 UI 렌더링 과 동시에 진행되어 화면 렌더링이 60hz를 지키지 못할 가능성이 높습니다
이러한 문제를 shader complile junk라 부릅니다.
이러한 문제를 해결 하기 위한 소프트웨어적 방법도 존재 하지만 Skia 엔진 자체가 비교적 오래되고 Flutter 만을 위한 엔진이 아닌 이유로
google에서는 이러한 문제를 해결하기 위해 Flutter만을 위한 렌더링 엔진을 새로 발표합니다.

Impeller Engine

Impeller 엔진은 skia 엔진과 동일하게 flutter Rendering 엔진으로 Flutter
framework에서 작성된 UI들을 받아 Shader를 생성합니다.
이때 skia와는 다르게 Impeller 엔진이 Flutter build 시 shader를 미리 컴파일 한 것들을 번들형태로 가지고 있어
gpu가 컴파일 하는 과정을 없에 shader compile junk를 해결 할 수 있습니다.

추가로 impeller 엔진은 Anit-Aliasing, Clipping 과 같은 대체 렌더링 기술을 통해
Skia 이상의 고품질 UI Rendering 을 가능하게 합니다.

Platform Channels

platform-channels.png Flutter에서 platform Service 와 통신 할 수 있게 해주는 기술로는 Platform Channel이 존재합니다.
해당 방법론은 Flutter Framework와 platform 사이에 MethodChannel이라는 채널을 하나 생성하여
Framework 에서 Platform 에게는 binary message
Platform에서 framework에게는 결과값을 비동기적으로 주고받을 수 있게 해주는 기술입니다.

1
2
3
4
    // Dart side
    const channel = MethodChannel('foo');
    final greeting = await channel.invokeMethod('bar', 'world') as String;
    print(greeting);
1
2
3
4
5
6
7
8
    // Android (Kotlin)
    val channel = MethodChannel(flutterView, "foo")
    channel.setMethodCallHandler { call, result ->
      when (call.method) {
        "bar" -> result.success("Hello, ${call.arguments}")
        else -> result.notImplemented()
      }
    }
1
    결과값 >> "Hello, world"

Paltform Channels는 간단한 기술적 방법론이지만 이를 통해
flutter framewor가 multi platfor의 여러 이벤트 api 등을 호출하여
단일 코드로 platform 서비스를 접근할 수 있게 해주는 핵심 기술입니다.
또한 지원하지 않거나 특별하게 Platform Native에서 구현이 필요한 경우
개발자가 직접 작성하여 구현 할 수도 있습니다.

지금까지 flutter가 멀티 플랫폼을 구현 할 수 있는 핵심 기술 두가지를 알아보았습니다.
마지막으로 flutter 의 장단점 알아보고 마치겠습니다.

Flutter의 장단점

잘 알려진 Flutter 의 단점

  1. Flutter에서 지원하지 않는 기능은 결국 Native에서 구현 해야함.
  2. 네이티브 앱 보다 Resource를 많이 사용.
  3. 아직까지는 Web 지원 미흡.
  4. 모든 UI 렌더링이 Vector이미지 형태로 생기기 때문에 요소 복사 불가능.

팀 내에서 경험한 Flutter의 단점

  1. InputField 및 SoftKeyboard 관련 버그
  2. SEO 문제

Flutter 의 장점

  1. 단일 언어로 multi platform 개발 가능.
  2. Multi platform에서 동일한 UI 렌더링.
  3. 네이티브 앱에 가까운 성능.
  4. Google의 사후 지원과 강력한 커뮤니티.

참고 문서

  1. https://docs.flutter.dev/resources/architectural-overview
  2. https://docs.flutter.dev/perf/impeller
  3. https://www.youtube.com/watch?v=vd5NqS01rlA&embeds_referring_euri=https%3A%2F%2Fdocs.flutter.dev%2F&embeds_referring_origin=https%3A%2F%2Fdocs.flutter.dev&source_ve_path=Mjg2NjY
  4. https://hackernoon.com/whats-revolutionary-about-flutter-946915b09514