はじめに
ヤフー株式会社はフリマサービス「PayPayフリマ」を運営しています。PayPayフリマは送料無料でお買い物ができる個人間取引サービスで、2019年の10月にリリースしました。Android/iOSアプリは、2021年11月の時点で1000万ダウンロードを達成しました。
比較的最近に作られたこともあって、Kotlinのみで書かれています。アーキテクチャはいわゆる「推奨アーキテクチャ(MVVM)」かつシングルアクティビティで、ViewModelとRepository間はユースケース層を挟んで抽象化しています。アプリの構成もマルチモジュールになっており、モジュール数は現在では60以上に及びます。
新しめの作りでクリーンなアーキテクチャが維持されていることもあり、これまでPayPayフリマではJetpack Composeの導入は様子を見ていましたが、安定版が公開されたため、試験的に導入することにしました。そこで本記事では、Jetpack Composeの解説と、プロダクトへの導入手順や、実際に使ってみての使用感などをお伝えしようと思います。
Jetpack Composeとは
Jetpack Composeは、Google I/O 2019のDeveloper Keynoteで発表され、2020年8月にα版が公開された、新しいAndroid用UIツールキットです。それまでのViewベースのUIツールキットの拡張ではなく、全く新しいコンセプトで作られていて、コード量の削減や直感的な開発、ビルド速度の向上が見込まれています。
発表されてからというもの、Android開発者コミュニティからは熱い視線が注がれてきましたが、2021年の7月に安定版のバージョン1.0.0が公開されたことで、開発者たちの間でますます盛り上がっています。現在ではすでにTwitterやPinterestなど、有名なアプリでも導入がすすんでおり、弊社のグループ会社である株式会社ZOZOでもZOZOTOWNアプリに導入しています。
Jetpack Composeが誕生した背景
これまでのViewベースのUI Frameworkは、Android OSの歴史とともにありました。
2009年のAndroid 1.5リリースから10年以上にわたるスマートフォンの進化の過程で、ユーザーがアプリに求める機能や体験は非常に高いレベルに達しています。そうしたユーザーからの要求に合わせるように、UIツールキットも拡張されてきました。長年にわたって機能拡張が繰り返されてきたことによって、現在のViewベースのUIツールキットは非常に複雑な作りになっています。
一方で開発者サイドからは、WebでのReactの成功の経験から、複雑に変化する状態に合わせてレスポンシブに変化するデザインを実装するには宣言的なUIと、それに適合する単方向データフローなアーキテクチャが良いことがわかってきました。しかしながら、ViewベースのUI FrameworkではUIを宣言的に実装することが困難でした。
加えて、今のUIツールキットはAndroid OSの一部です。そのためUIに関して何か新しい機能が登場しても、使えるのは新しいOSだけということもありました。そうなると、その新しいOSバージョンが普及するまでは、実際にプロダクトで使うのは困難でした。ユーザーの新しい体験のために機能追加をしても、それをユーザーに効果的に届ける方法に欠けていたわけです。
これが顕著になったのがFragmentです。FragmentはAndroid OS 3.0で登場したコンポーネントでしたが、Android OS 3.0以降でしか使えないことが仇となって、さっぱり普及しませんでした。アプリ開発者としては、古い端末ユーザーのために既存のActivity主体のコードベースを保守しながら、新しいOSユーザーのためにFragment構成のコードベースを作りあげることはしたくなかったからです。Fragmentが広く普及するのは、Jetpackの前身であるSupportライブラリに組み込まれるのを待つ必要がありました。
このことからわかるのは、UIの改修はOSの更新から切り離す必要があること、Android SDKとは別個のライブラリとして配布することで、高速な更新と普及を可能にする必要があることです。Googleが新たに宣言的UIを実装するためのツールキットを開発するうえで、既存のSDKの改修ではなくJetpackライブラリの一部として、Android OSのバージョンに依存しない形で開発されたのは当然の流れでした。
Android UI Frameworkへの課題感
現在の高いレベルの体験を安全に生産性高く開発するためには、宣言的UIと単方向データフローなアーキテクチャーが適しているとはいえ、すでに動いているプロダクトに異なる考え方のアーキテクチャを組み込む決断は容易ではありませんでした。プロジェクト中に異なるアーキテクチャで命令的UIと宣言的UIが混在する状況は、お世辞にも好ましいとは思えません。チームメンバーにとっても新しいアーキテクチャに対する学習コストがかかります。それなのに、なぜJetpack Composeを導入することにしたのでしょうか。
パフォーマンスの悪化
ヤフーではいま、全社をあげてアプリのパフォーマンス改善に努めています。
既存のViewベースのフレームワークでは、UIが複雑になるにつれてパフォーマンスが著しく悪化し、特にRecyclerViewでは顕著な影響があります。
PayPayフリマでは「ホーム画面」や「商品画面」は、ユーザーがほしい商品を探し購入する上でとても重要な役割を果たしています。そのため、これらの画面には高い頻度で機能追加や改修が行われており、UIの表示がユーザーや商品の状態に応じて複雑に変化するようになっています。その結果、レイアウトも複雑なものとなっており、パフォーマンス面での問題を感じていました。
安全性の問題
現在のViewベースのUIフレームワークは命令的UIであり、UI要素を操作するコードが散逸しやすく、また状態管理が複雑化するにつれて処理が煩雑になる問題があります。そのため、すべての状態に対して整合性のある表示を行うためには、コードの全体を把握が求められることとなり、思いがけない条件の組み合わせによって不具合が発生する原因となっています。