Realays Logo Realays
← 블로그 목록으로
DevLog 2025. 11. 5.

[Dalendar DevLog 1] 프로젝트의 시작과 기술 스택 선정

완벽한 달력 앱을 향한 여정의 시작, 그리고 React Native와 Expo를 선택한 이유에 대해 이야기합니다.

[Dalendar DevLog 1] 프로젝트의 시작과 기술 스택 선정

1편: 프로젝트의 시작과 기술 스택 선정

1. 들어가며: 완벽한 달력 앱을 향한 개인적인 여정

우리 일상에서 달력만큼 친숙한 도구는 드뭅니다. 스마트폰, 컴퓨터, 심지어 손목시계에도 달력은 기본 기능으로 자리 잡고 있습니다. 하지만 이토록 흔하게 사용하는 달력의 이면에는 상당한 기술적 복잡성이 숨어있습니다. 특히 한국은 1896년 태양력(양력)을 공식 채택한 이후에도 여전히 설날, 추석과 같은 주요 명절이나 제사를 음력 기준으로 기념하는 독특한 시간 문화를 가지고 있습니다.

이러한 문화적 이중성은 단순한 역사적 흥밋거리가 아닙니다. 개발자의 관점에서 보면, 이는 우리가 ‘단순하다’고 여기는 달력의 표면 아래에 숨겨진 사소하지 않은 엣지 케이스와 계산 오버헤드를 보여주는 구체적인 사례입니다. 바로 이 깨달음이 가능한 가장 효율적인 해결책을 찾고자 하는 제 집착에 불을 지폈습니다.

이 프로젝트는 단순히 또 하나의 달력 앱을 만드는 것을 넘어, 달력의 근간을 이루는 알고리즘의 본질을 탐구하고 성능을 극한까지 끌어올리기 위한 개인적인 여정에서 시작되었습니다. 이 시리즈를 통해 달력 계산의 비효율성을 개선하고, 현대적인 기술 스택을 활용하여 최고 성능의 달력 앱을 만들어가는 과정을 공유하고자 합니다.

2. 문제 정의: 왜 또 다른 달력 앱을 만들어야 하는가?

기존에도 수많은 달력 앱이 존재하는데 왜 새로운 앱을 개발하려 하는 걸까요? 그 이유는 두 가지 핵심적인 기술적 동기, 즉 알고리즘의 비효율성과 과거 네이티브 개발 경험에서 얻은 고통스러운 교훈에서 찾을 수 있습니다.

2.1. 기존 달력 알고리즘의 숨겨진 비효율성

달력 계산의 핵심은 특정 날짜를 구하는 수학적 연산입니다. 대부분의 달력 알고리즘은 나눗셈(division)과 나머지(remainder) 연산에 크게 의존합니다. 하지만 “Euclidean Affine Functions and Applications to Calendar Algorithms” 논문에 따르면, 이 두 연산은 CPU에서 수행되는 네 가지 기본 산술 연산 중 가장 느립니다. 각 나눗셈 연산은 나노초 단위로 측정되지만, 사용자가 달력을 빠르게 스와이프하며 수천 번 실행될 때 누적된 지연은 부드럽고 유려한 사용자 경험과 눈에 띄는 ‘버벅임(jank)’ 또는 끊김 현상의 차이를 만들어낼 수 있습니다.

이 논문은 자신들이 제안하는 알고리즘이 “널리 사용되는 C, C++, C#, Java 오픈소스 라이브러리”의 구현보다 “상당히 더 효율적”이라고 주장합니다. 이는 현재 우리가 사용하는 대다수의 달력 앱들이 잠재적인 성능 저하 요소를 안고 있을 수 있음을 시사합니다. 이 프로젝트의 핵심 목표는 바로 이 비효율적인 연산을 최적화하여 달력 계산 성능을 극대화하는 것입니다.

2.2. 이전 개발 경험에서 얻은 교훈

과거에 Android Kotlin 환경에서 달력 앱을 개발했던 경험은 새로운 프로젝트의 방향을 설정하는 데 중요한 교훈을 주었습니다. 당시 월간 달력 뷰를 구현하기 위해 중첩된 RecyclerView 구조를 사용했습니다.

하지만 이 구조는 수많은 기술적 고충을 안겨주었습니다. 예를 들어, 무한히 스크롤되는 월간 달력의 환상을 만들어내기 위해, 저는 RecyclerView의 초기 위치를 Int.MAX_VALUE/2로 설정하는 흔하지만 지저분한 편법에 의존해야 했습니다. 이는 현재 월을 알아내는 것조차 간단하지 않다는 것을 의미했습니다. 현재 스크롤 위치를 거대한 중앙값에서 빼는 (position - center 같은) 방식의, 오류에 취약한 계산을 끊임없이 수행해야 했습니다.

게다가 매월 뷰를 렌더링할 때마다, 로직은 날짜를 표시하기 위해 42개의 아이템(6x7 그리드)을 담는 dayList를 수동으로 구성하고 채워야 했습니다. 이전 달과 다음 달의 날짜로 그리드를 채우기 위해 중첩된 루프와 복잡한 달력 연산이 필요했습니다. 이는 번거로울 뿐만 아니라, 빠른 스크롤 시 렌더링 성능에 병목 현상을 일으켰습니다.

이러한 네이티브 UI 구현의 복잡성과 프레임워크와의 씨름은 더 효율적이고 유연한 개발 방식의 필요성을 절감하게 만들었고, 이번 프로젝트에서 새로운 기술 스택을 선택하는 결정적인 배경이 되었습니다.

3. 고성능 앱을 위한 기술 스택 선정 및 초기 고민

앞서 정의한 문제점과 이전 개발 경험을 바탕으로, 이번 프로젝트에서는 다음과 같은 기술 스택을 선정했습니다.

3.1. 크로스플랫폼을 위한 선택: React Native (Expo)

이 선택은 중첩된 RecyclerView와 그 복잡한 생명주기 관리 같은 네이티브 UI 컴포넌트와 씨름했던 과거의 고통에 대한 직접적인 대응입니다. 하나의 코드 베이스로 Android와 iOS 양쪽 플랫폼을 모두 지원할 수 있다는 점은 개발 생산성을 획기적으로 높여줍니다. 특히, 초기 프로젝트 설정의 번거로움을 줄이고 빠르게 개발에 집중할 수 있도록 도와주는 Expo 프레임워크를 함께 사용하기로 결정했습니다.

3.2. 알고리즘의 정확성을 위한 선택: TypeScript

“Euclidean Affine Functions” 논문에서 제안된 고도로 최적화되었지만 수학적으로는 밀도 높은 알고리즘을 순수 JavaScript로 구현하는 것은 재앙을 자초하는 일입니다. 미묘한 타입 강제 변환 버그 하나가 모든 성능 향상을 조용히 무효화시킬 수 있습니다. TypeScript의 강력한 정적 타입 시스템은 이런 수준의 정밀도를 요구하는 작업에 필수적인 안전장치(guardrails)를 제공하며, 코드의 안정성과 유지보수성을 크게 향상시킵니다.

3.3. 미래 확장성을 고려한 선택: Node.js

이것은 단순히 미래를 대비하는 것을 넘어, 전체적인 아키텍처 철학에 관한 것입니다. 장기적으로 사용자 계정 연동이나 클라우드 동기화 같은 기능이 필요할 수 있음을 고려할 때, 백엔드로 Node.js를 선택함으로써 우리는 프론트엔드부터 백엔드까지 통일된 TypeScript/JavaScript 생태계를 유지할 수 있습니다. 이는 코드 재사용성을 극대화하고 개발팀의 인지적 효율성(cognitive efficiency)을 높이는 전략적인 결정입니다.

4. 앞으로의 계획

이 프로젝트는 단순히 또 하나의 달력 앱을 만드는 것을 넘어, 기존 달력 알고리즘의 비효율성을 개선하고, 네이티브 UI 구현의 복잡성을 극복하며, 현대적인 크로스플랫폼 기술 스택을 활용하여 최고 성능의 달력 앱을 만드는 도전입니다. 성능에 대한 집착과 기술적 호기심이 이 여정의 원동력입니다.

다음 편에서는 실제로 Expo와 TypeScript를 사용하여 프로젝트의 기본 구조를 설정하고, 효율적인 달력 알고리즘 구현을 위한 첫걸음을 내딛는 과정을 자세히 다루겠습니다. 많은 기대 바랍니다.

관련 포스트