[Dalendar DevLog 1] プロジェクトの始まりと技術スタック選定
完璧なカレンダーアプリに向けた旅の始まり、そしてReact NativeとExpoを選んだ理由について話します。
![[Dalendar DevLog 1] プロジェクトの始まりと技術スタック選定](/images/blog/dalendar_dev_1_ideation.png)
1編: プロジェクトの始まりと技術スタック選定

1. はじめに: 完璧なカレンダーアプリに向けた個人的な旅
私たちの日常でカレンダーほど親しみのあるツールは稀です。スマートフォン、コンピュータ、さらには腕時計にもカレンダーは基本機能として定着しています。しかし、これほどありふれたカレンダーの裏側には、かなりの技術的複雑さが隠れています。特に韓国は1896年に太陽暦(新暦)を公式採用した後も、依然として旧正月、秋夕のような主要な名節や法事を旧暦基準で記念する独特な時間文化を持っています。
このような文化的二重性は単なる歴史的な興味深い点ではありません。開発者の観点から見ると、これは私たちが「単純だ」と考えているカレンダーの表面下に隠された、小さくないエッジケースと計算オーバーヘッドを示す具体的な事例です。まさにこの気付きが、可能な限り最も効率的な解決策を見つけようとする私の執着に火をつけました。
このプロジェクトは単にカレンダーアプリをもう一つ作ることわりを超えて、カレンダーの根幹をなすアルゴリズムの本質を探求し、性能を極限まで引き上げるための個人的な旅から始まりました。このシリーズを通じてカレンダー計算の非効率性を改善し、現代的な技術スタックを活用して最高性能のカレンダーアプリを作っていく過程を共有しようと思います。
2. 問題定義: なぜまた別のカレンダーアプリを作らなければならないのか?
既存にも数多くのカレンダーアプリが存在するのに、なぜ新しいアプリを開発しようとするのでしょうか?その理由は2つの核心的な技術的動機、つまりアルゴリズムの非効率性と過去のネイティブ開発経験から得た苦痛な教訓に見出すことができます。
2.1. 既存のカレンダーアルゴリズムの隠れた非効率性
カレンダー計算の核心は特定の日付を求める数学的演算です。大部分のカレンダーアルゴリズムは割り算(division)と剰余(remainder)演算に大きく依存します。しかし「Euclidean Affine Functions and Applications to Calendar Algorithms」論文によると、この2つの演算はCPUで実行される4つの基本算術演算の中で最も遅いです。各割り算演算はナノ秒単位で測定されますが、ユーザーがカレンダーを素早くスワイプして数千回実行されるときに累積された遅延は、滑らかで流れるようなユーザー体験と目立つ「カクつき(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を使用してプロジェクトの基本構造を設定し、効率的なカレンダーアルゴリズム実装のための第一歩を踏み出す過程を詳しく扱います。ご期待ください。
![[Dalendar DevLog 2] 堅固なアプリの骨組み - アーキテクチャとデータ構造設計](/images/blog/dalendar_dev_2_architecture.png)
![[Dalendar DevLog 3] コア機能実装 1 (バックエンド & ロジック)](/images/blog/dalendar_dev_3_math_logic.png)
![[Dalendar DevLog 4] コア機能実装 2 (フロントエンド & UI)](/images/blog/dalendar_dev_4_ui_structure.png)