작성자: Shams Zakhour (Senior Technical Writer) 이 글의 원문은 ByteDance Team에서 중국어로 작성하였으며, 이후 영문으로 번역되었습니다. 영문 버전은 여기서 확인하실 수 있습니다.
ByteDance가 지금까지 수 년간 사용하고 기여해온 기술인 Flutter가 최근 Google I/O에서 집중 조명을 받았습니다. Google에서 개발해 오픈소스로 제공하는 이 프런트엔드 UI 개발용 다중 플랫폼 프레임워크는 GitHub에서 120,000개 이상의 별점을 받았습니다.
Google I/O에서 Flutter의 제품 관리자 Zoey Fan은
ByteDance에서 어떻게 이 프레임워크를 채택했는지 들려주었습니다.
ByteDance의 70개 이상의 앱이 Flutter를 다중 플랫폼 솔루션으로 사용합니다.
Flutter를 사용하면 Android 및 iOS용으로 별도의 앱을 개발할 때보다 개발 시간을 33% 단축할 수 있습니다.
현재 ByteDance는 500여 명의 Flutter 개발자를 보유하고 있으며 그중 200명 이상이 개발에 Flutter를 활발하게 활용하고 있습니다. 이들 개발자는 모바일 앱뿐 아니라 웹, 데스크톱, 임베디드 플랫폼에서도 Flutter로 다양하게 실험하며 개발하고 있습니다.
그 밖에도, ByteDance는 조직 전반에 걸쳐 많은 기본 작업을 수행했으며 수십 개의 Pull 요청(PR)을 제출하여 Flutter 프로젝트에 크게 기여해왔습니다.
Flutter를 효과적으로 활용하기 위해 ByteDance는 무엇을 했을까요?
ByteDance에서 Flutter의 역사는 2년 전에 시작되었습니다.
당시에 ByteDance 프런트엔드 엔지니어링 팀은 사내 다수의 팀에서 다중 플랫폼을 염두에 두고 개발해야 했지만 고효율, 고성능, 다중 플랫폼 개발을 위한 도구가 부족하다는 사실을 알게 되었습니다.
Google이 Flutter를 오픈소스로 제공했을때 ByteDance 팀은 Flutter를 사용하면 Android, iOS, 웹과 같은 플랫폼을 지원하는 앱을 한 번만 개발하면 된다는 사실을 깨달았습니다. 또한, Flutter에는 자체 렌더링 엔진이 있으므로 여러 플랫폼에 걸쳐 더욱 일관된 성능을 달성할 수 있었습니다.
Flutter를 사용하면 Android, iOS 및 웹 버전의 앱이 자동으로 동기화됩니다. 각 플랫폼을 위한 UI를 별도로 프로그래밍할 필요가 없으므로 중복 작업의 상당 부분이 제거됩니다.
비즈니스 개발을 더 효율적으로 지원하고자, ByteDance 팀은 성능 최적화, 앱 프레임워크 개발, 컨테이너화, 앱에 추가 기능 지원과 같은 프레임 워크 자체에 대한 기본적인 작업을 수행했습니다. 또한, 프레임 차트에서 초당 프레임 수(FPS) 정보와 타임라인 이벤트 차트를 비롯한 Flutter 성능 도구를 개선하기도 했습니다. 이 두 차트 모두 Flutter DevTools의 Performance View에 포함됩니다.
Flutter를 채택할 때 ByteDance 팀은 몇 가지 고유한 도전에 직면했습니다.
예를 들어, Flutter를 앱 설치 패키지에 추가되어야 해서사용자가 다운로드하는 앱의 크기가 커집니다. 또한, Flutter는 네이티브 코드보다 더 큰 Dart 프로그래밍 언어를 사용하므로 패키지 크기가 더 늘어납니다.
ByteDance 팀은 iOS 데이터 섹션을 압축하고 Skia 라이브러리와 기타 라이브러리(예: BoringSSL, ICU, 텍스트 렌더링, libwebp)를 제거하여 패키지 크기를 최적화하기 위한 특별한 계획을 시작했습니다. ByteDance 팀은 Flutter Dart 코드를 iOS 네이티브 코드와 비교해 분석했는데, 동일한 비즈니스 기능을 실현하는 데 Dart 코드가 더 많은 기계어 코드 명령을 생성한다는 사실을 알게되었습니다. 그 차이를 해소하려고 Instruction의 정렬을 줄이고, 일부 디버깅 트랩 명령을 제거하고, null의 중복된 초기화 저장소를 삭제하고, 기본 명령 모드로 RawInstruction 헤더를 제거하고, StackMap을 압축하고, CodeSourceMap을 제거하는 등의 방법을 취했습니다.
이러한 각각의 최적화가 개별적으로 패키지 크기가 0.2~4MB 정도 감소했고, 결합했을 때 전체 패키지 크기가 상당히 줄었습니다. ByteDance 팀은 이렇게 터득한 경험을 Google 엔지니어와 공유했고, 더 많은 커뮤니티에서 알 수 있도록 Flutter 오픈소스 프로젝트에 여러 개선 사항을 적용하였습니다.
하지만 ByteDance가 자사 최초의 Flutter 앱을 출시할 때 새로운 문제가 발생했습니다. 사용자들로부터 "앱에서 스크롤할 때 UI가 왜 심하게 버벅거리는 거죠?"라는 불만 사항이 있었습니다.
ByteDance 팀에서 이 문제를 살펴봤더니, FlutterView가 TextureView를 확장할 때 UI가 SurfaceView를 확장할 때보다 눈에 띄게 더 버벅거린다는 점을 확인했습니다. 그러나 공식 Timeline 도구에서 렌더링된 각 프레임에 대한 UI 스레드 시간과 GPU 스레드 시간은 거의 동일하고, 다만 가끔씩 TextureView는 때때로 조금 앞서 나가기도 합니다.
이런 측정항목이 실제 사용자 경험과 모순되어 팀을 당혹스럽게 만들었습니다.
ByteDance 팀은 처음에는 Timeline 도구를 사용해 문제를 해결하려 했지만 소용이 없었습니다. 결국 이 도구의 소스 코드를 조사한 후에야 문제의 근본 원인을 발견했습니다.
SurfaceView는 TextureView보다 성능이 좋았습니다. SurfaceView는 자체 표시 경로가 있고 렌더링도 자체 OpenGL 환경설정에서 수행되었으므로 SurfaceFlinger와 독립적으로 상호 작용할 수 있었고 삼중 버퍼링을 최대한 활용할 수 있었습니다. 반면에, TextureView는 렌더링을 위해 호스트 창의 표시 경로에 의존하는 일반 뷰였습니다. 즉, UI 및 GPU 스레드가 작업을 마친 직후에 렌더링이 수행되지는 않았지만, 뷰가 SurfaceFlinger와 상호 작용할 수 있으려면 먼저 메인 스레드와 renderThread를 기다려야 했던 것입니다. 이는 SurfaceView의 것보다 훨씬 긴 렌더링 파이프라인이었습니다.
이 조사 결과는 팀에서 버벅거림 문제를 해결하는 데 도움이 되었을 뿐만 아니라, Flutter 오픈소스 프로젝트에 10개의 PR이 제출되는 성과로도 이어졌습니다. 이같이 기본 작업이 완료되면서 Flutter는 ByteDance에서 멀티 플랫폼 앱 개발을 위한 주력 프레임워크가 되었습니다. ByteDance 팀에서 Flutter를 사용해 수행한 작업은 모바일 개발 프레임워크인 veMARS를 사용하는 외부 개발자에게 곧 제공되어 개발자 커뮤니티 전체에 도움이 될 것입니다.
실험부터 프로덕션까지, ByteDance가 Flutter를 사용한 방식
ByteDance가 Flutter를 실제로 사용하기까지 순조롭지만은 않았습니다.
ByteDance 팀은 처음에는 완성형 제품을 선택한 후 Flutter로 앱의 동영상 재생 기능을 다시 구현할 계획이었습니다.
원래 Android 및 iOS용 네이티브 코드로 작성된 이 기능은 Flutter로 다시 쓰는 일이 간단치 않았습니다. 6개월 후, 팀은 모든 라이브 데이터를 호환 가능하게 만드는 것이 어렵고 기존 비즈니스 로직을 업데이트하기 버거울 것이라는 결론에 이르렀습니다.
그래서 완성형 제품의 기존 기능을 새로운 프레임워크로 업데이트하는 것은 생산적이지 않다는 결론을 내렸습니다. Flutter의 강점은 새로운 앱에서 더욱 그 빛을 발합니다. 팀장은 이렇게 덧붙였습니다. "완성형 제품에서는 모든 것이 네이티브 Android 또는 iOS 기술로 이미 잘 만들어져 있습니다. 사소한 개선만을 위해 Flutter로 기능을 다시 구현하는 건 그다지 실익이 없습니다. Flutter 엔진이 패키지에 포함되므로 패키지 크기도 커집니다. 하지만 신제품이나 새로운 시나리오에서는 Flutter로 생산성을 크게 높일 수 있습니다."
팀은 이처럼 변화된 사고방식으로 교육과 같은 새로운 비즈니스 분야로 초점을 돌렸습니다.
중국에서 사용되는 ByteDance의 교육 앱 중 하나는 학생의 한자 획순 학습에 도움을 주고 있는데, 팀에서는 획순 추적 기능을 추가하고 싶었습니다.
팀은 이 기능을 구현하려고 몇몇 오픈소스 프로젝트에서 영감을 얻어 SVG 경로를 사용해 획순을 표현하기로 했습니다. 이를 통해 경로를 조정되고 적절히 배치하면서 글자를 구성하게 됩니다.
가상 브러시 펜의 움직임을 안내하도록 각 획의 골격을 정의했으며, 이에 따라 펜이 마치 서예에서 볼 수 있는 붓놀림처럼 움직입니다.
골격의 정의된 순서를 기준으로, 특정 반경의 원이 각 골격을 따라 그려지고 이런 원이 함께 획을 형성합니다. 그 후, 애니메이션의 프레임 속도가 버벅거림을 방지할 정도로 충분히 높도록 보장하기 위해 키 프레임을 추가했습니다.
이를 통해 다음 GIF에서와 같이 부드러운 추적 효과를 만들 수 있었습니다.
Flutter로 만든 이 기능으로 현재 일반적으로 사용되는 문자 대부분을 포함한 9,000여 자의 한자를 지원합니다. 네이티브 코드로 개발하는 것에 비해, Flutter로 개발한 덕분에 시간과 리소스를 절약했습니다.
현재, ByteDance에서 제공하는 다수의 앱은 Flutter 및 기타 기술의 강점을 결합한 하이브리드 개발 방식을 채택하고 있으며, 새로운 앱의 경우 순수하게 Flutter만 사용해 개발하고 있습니다. Xigua Video, TikTok Volcano, Open Language와 같은 앱의 경우, Flutter는 팀의 생산성을 약 33% 높였습니다.
최신 기술을 적극적으로 수용하는 ByteDance 직원들
지금도 ByteDance의 Flutter 팀은 최신 기술을 계속 탐구하는 데 여념이 없습니다. 팀장의 말에 따르면, "저희 팀에는 글로벌 비전을 가진 많은 기술 전문가가 있으며, 앞으로도 계속해서 전 세계의 기술 발전을 예의주시하고 기술 구현을 치열하게 논의할 것입니다. 저희는 많은 기술 기업과 긴밀한 관계를 맺고 협업하고 있습니다. 그 예로, Google과는 매 분기마다 회의를 갖고 서로 진행 상황 및 의견을 비롯해 필요한 부분이나 아이디어를 공유합니다."
하루는 GitHub의 Dart 오픈소스 프로젝트 관리자가 ByteDance 팀장에게 이렇게 말했다고 합니다. "팀원 중 누군가가 Dart에 PR을 12건 이상을 제출했던데, 모두 정말 훌륭하고 잘 생각해냈더군요."
그 관리자가 칭찬하는 팀원은 Frank였습니다. Frank는 열정적으로 오픈소스 개발에 기여하고 있는데 불과 3년 전에 학사 학위를 받은 직원입니다. Frank는 2015년 대학교 1학년 때 오픈소스 세계에 첫발을 들여놓았습니다. 그가 만들어 GitHub에 오픈소스로 공개한 프로젝트 중 하나는 700개 이상의 별표를 받았습니다. Frank는 "연간 다운로드 횟수가 수백 회였고 많은 게임 개발자가 그 프로젝트를 사용하여 데모를 만듭니다"고 말했습니다.
대학 졸업 후, ByteDance의 Flutter 팀에 입사해 Dart와 Flutter에 대한 다수의 PR에 기여하면서 팀에서 가장 활발한 오픈소스 기고자로 손꼽히게 되었습니다. Frank는 패키지 크기 문제를 해결하는 과정에서 Dart GitHub 프로젝트에서 관련 문제를 선제적으로 추적해 Specializer 구성 요소에 추가 조율이 필요하다는 것을 알게 되었습니다. 그는 Dart 컴파일러 미들웨어를 개선한 패치를 만들어 프로젝트에 제출했습니다. 다수의 코드 블록이 영향을 받고 몇 가지 사소한 문제가 있다는 이유로 처음에는 이 패치가 승인되지 않았습니다. 이 패치는 일곱 차례나 수정한 후에야 패치가 승인되었는데, 일주일 후 코드베이스에 병합되었습니다.
ByteDance의 Flutter 팀에는 Frank처럼 열렬한 오픈소스 마니아가 많습니다.
ByteDance 팀은 혁신에 대한 이런 열정적인 태도를 다음과 같이 요약했습니다.
"실제로 업계에는 완성형 기술을 선호하는 사람들이 많지만, 어떤 기술이든 발전하는데는 시간이 걸리는 법이며, 최첨단 기술을 원하는 저희 같은 사람들은 항상 있을 것입니다.”
이는 Flutter와 같은 새로운 기술에 특히 잘 들어맞는 말입니다. 이런 새로운 분야에는 대담하게 첫 걸음을 떼는 사람이 있어야 합니다. ByteDance에서는 Flutter 엔지니어링 팀뿐 아니라 이 팀에서 지원하는 엔지니어링 팀도 새로운 기술을 적극적으로 시도하고 수용합니다. 이러한 시도가 ByteDance에 크게 도움이 되어 생산성도 상당히 높일 수 있었습니다.
ByteDance는 항상 업계 발전에 기여하고자 했는데, Flutter가 그 중 하나가 될 것으로 보입니다.