Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

『メルカリ』 アプリの画面描画を高速化する技術、バックエンド・iOS・Androidの基本設計

多くのユーザーに愛されるフリマアプリ『メルカリ』ですが、そのスムーズな画面描画はどのような技術で生み出されているのでしょうか。同アプリの高速表示の秘密を、バックエンド、iOS、Androidの3方向からメルカリ社のエンジニア4人に聞きました。

『メルカリ』 アプリの画面描画を高速化する技術、バックエンド・iOS・Androidの基本設計

2013年の登場以降、すさまじい勢いでユーザーを増やしているフリマアプリ『メルカリ』。バリエーション豊かな商品や直感的で使いやすいUIなど、ユーザーを惹きつける要素は数多くあります。

そのなかでも特に、心地よいユーザー体験を生み出している重要な要素があります。画面の描画が非常にスムーズなことです。その体験を支えるのは、高速表示を実現するための高い技術力です。

『メルカリ』の開発者たちは、どんな技術を用いて“使い勝手の良いアプリ”を作り出しているのでしょうか。そして、いかなる観点のもとにツールやアーキテクチャの改善を続けているのでしょうか。バックエンド、iOS、Androidなど幅広い領域のエンジニアの方々に、その秘密を語っていただきました。

1 「フリマアプリ-メルカリ フリマでかんたんショッピング」をApp Storeで

2 フリマアプリ「メルカリ」

3
久保達彦(くぼ・たつひこ) 4 @cubicdaiya (写真・右上)
Webサービスや組込みソフトウェア、広告配信システムの開発を経て、2014年よりメルカリに加わる。ソフトウェアエンジニアとして、サービスの信頼性やパフォーマンスの向上に必要なソフトウェアの開発・運用に携わる。
高山征大(たかやま・もとひろ) 5 @mootoh(写真・右下)
2016年にソフトウェアエンジニアとしてメルカリに入社し、現在は Androidチームのエンジニアリングマネージャー。それ以前は iOSアプリ開発や並列プログラミング言語の研究開発などに従事。
Tim Oliver(ティム・オリバー) 6 @TimOliverAU (写真・左下)
メルカリJPプロダクトチームのiOSエンジニアでオーストラリア出身。メルカリ入社前は、San FranciscoのRealmというモバイル・フレームワークのスタートアップでCocoaの開発を担当。Edith Cowan大学でデジタル・メディアを専攻。
Israel Ferrer Camacho(イスラエル・フェレール カマチョ) 7 @rallat (写真・左上)
メルカリAndroidチームのソフトウェアエンジニアとしてアプリのアーキテクチャと開発者の生産性向上に従事。 メルカリ入社以前は、TwitterのAndroidエンジニアとしてTwitter、Periscope、Fabricなどを担当。Barcelona LaSalle大学でコンピューターサイエンスを専攻。

バックエンドの高速化を支える技術

【Tips1】 画像のファイルサイズを最適化し、アプリ全体の通信量を抑える

──『メルカリ』の商品一覧画面は、非常に多くの画像を表示していますが描画が非常に高速です。何か特別な技術が使われているのでしょうか?

久保 画像をたくさん使用するモバイルアプリをなめらかに動かすためには、データ通信量を抑える工夫が重要になります。

『メルカリ』ではアプリで使用する画像のサイズを最適化するために、クラウド画像変換サービスの『ImageFlux』を使用しています。これはURLに画像変換用のパラメータを組み込むことで画像データの拡大・縮小やオーバレイ、フォーマット変換などが可能になるサービスです。

アプリ上で表示される画像をオンザフライでリサイズしたり、フォーマットをWebPに変換する、といった処理を『ImageFlux』によって実現しています。これにより、画像変換処理を自社のサーバーで行う必要もなくなるので開発工数も抑えられます。

8

『ImageFlux』はピクシブ株式会社とさくらインターネット株式会社が共同で開発・運用しているクラウド画像変換サービスだ。画像データをサーバや既存のクラウドから移すことなく、『ImageFlux』を中継して呼び出すだけで最適化された画像を配信してくれる。

──他の種類の画像フォーマットと比べて、WebPはどんな点が優れていますか?

久保 WebPは画質の劣化を極力抑えつつ、ファイルサイズを大幅に削減できるメリットがあります。

実際に『メルカリ』のタイムライン、検索結果に表示される商品画像のサムネイルに対して『ImageFlux』によるリサイズやWebPへの変換を行い、1画像あたり最大で40~50%ほどサイズを削減できました。タイムラインや検索結果に表示される画像のトラフィックはかなり多いので、これは非常に効果的でした。

画面描画も速くなりますし、アプリのデータ通信量を減らすことで、いわゆる“ギガが減る”ことも軽減できます。

──40~50%とはすごい! 『メルカリ』のように画像が一面に並ぶようなUIでは、画像の通信容量が減るメリットは本当に大きいですね。

【Tips2】データセンター間通信のレイテンシを抑える

──『メルカリ』のバックエンドでは複数のクラウドサービスを活用しているそうですね。そこにもアプリを高速に動かすための工夫はありますか?

久保 はい。メルカリのインフラはマルチクラウド構成になっているため、異なるクラウドやデータセンター間での通信がたびたび発生します。

その際のレイテンシを最小限に抑えるために、別のクラウドやデータセンター側との接続を維持したままにするプロキシサーバをGoで開発して投入しています。

9

プリンシパルエンジニア 久保達彦さん

──複数のクラウドサービスは、どのように使い分けているのでしょうか?

久保 メルカリのコアとなるシステムの多くはさくらの専用サーバ上で稼働していますが、一方で、ストレージにはAmazon S3Google Cloud Storageを、マシンラーニングやマイクロサービスの基盤にはGKE(Google Kubernetes Engine)を採用していたりと、用途や要件に応じて使い分けています。例えば「感動出品<1」という機能はGCPにあるマシンラーニングの基盤上で稼働していますが、利用している画像データがAmazon S3にあるので、AWSのサービスも一部利用しています。

「感動出品」のシステムアーキテクチャ。

【Tips3】アプリのありとあらゆる挙動を常にモニタリングする

久保 サービスの可用性やパフォーマンスをチェックするのにモニタリングも重視しています。

──モニタリングでは何をチェックしていますか?

久保 例えば、API等のアプリケーションのレスポンスタイムです。平均値のほかに95(99)パーセンタイル2の値もチェックしています。

──モニタリングツールは何を導入しているのでしょうか?

久保 複数のツールを導入していて、『Mackerel』や『Datadog』、『New Relic』などを主に用いています。

──それぞれを、どう使い分けていますか?

久保 『Mackerel』では各ホストの死活監視やアプリケーションの稼働状況の監視、さらにURL外形監視や、出品機能をはじめとした各種機能が正常に動いているかの監視をしています。例えば、「平常時と比べて出品の数が極端に少ない」「一定時間あたりのエラーの数が極端に多い」などをトリガーにしてアラートを飛ばし、異常を検知しています。

『Datadog』は主にマイクロサービス関連コンポーネントのモニタリングに利用しています。

さらに、『New Relic』ではアプリのパフォーマンスの細部をモニタリングしています。例えば、Webサーバー内でのPHPの処理に何ミリ秒、MySQLからのデータ取得に何ミリ秒、memchachedの処理で何ミリ秒かかっている、というように各レイヤーの詳細な応答情報を解析できるのが『New Relic』の大きな特徴です。

──アプリケーションの処理が遅くなっていることが判明したら、次は何をしていきますか?

久保 これまでに挙げたようなツールやサービスを駆使して関係がありそうな箇所やメトリクスを調査したり、プロファイリングを行って原因を調べます。原因が判明したら、そのままコードを修正することもあります。

iOSアプリの高速化を支える技術

【Tips4】Objective-CからSwiftへの移行 & アーキテクチャの刷新

──次に、iOSアプリについての話を聞かせてください。現在、『メルカリ』ではObjective-CからSwiftへの移行を進めているそうですね。

ティム iOS版『メルカリ』の開発は2013年に始まりました。Swiftが発表されたのは2014年ですから、当然ながらアプリはObjective-Cによって作られています。

今後は、iOSアプリの全コードをSwiftに移行していく予定です。新しい機能は最初からすべてSwiftで開発し、古いObjective-Cのコードも徐々にSwiftに変更していきます。

10

ソフトウェアエンジニア ティム・オリバーさん

ティム また、Objective-CからSwiftへの移行と同時期に、iOSアプリのリアーキテクチャ(アーキテクチャの変更・再構築)を行いました。既存のアーキテクチャをどのように変更すれば、開発効率性が向上するかを考えたんです。

──旧アーキテクチャの問題点とは何だったのですか?

ティム かつて、iOS版の『メルカリ』ではMVCモデルを採用していました。iOSアプリのMVCモデルでは、ViewControllerがModelとViewを持つような構成になっており、ロジック部分は基本的にViewControllerに記載されます。

そのため、MVCモデルではアプリが大きくなるにつれて、ViewControllerがどんどん肥大化してしまう傾向にあります。iOSエンジニアはよくジョークで「MVCモデルとはMassive(大規模な)ViewControllerの略だ」と言ったりします(笑)。

『メルカリ』でも、特定の画面のViewControllerが数千行もの行数になってしまうという状態でした。その状態ではコードがとにかく読みづらいですし、テストコードを書くことも困難です。

リアーキテクチャのプロジェクトにおいては、それを解消するためMVCモデルからMVVMモデルへの移行を行いました。

肥大化したViewControllerを別々のClassに分割し、一つひとつが適切な粒度になるよう小さくしていきました。これにより、各Classの役割が分かりやすくなり、新しい機能を追加することも、テストコードを書くことも容易になったんです。

──iOSアプリ開発において、MVCモデルとMVVMモデルはどのような基準で使い分けるべきだと思いますか?

ティム ロジックが限られている小規模なアプリであれば、MVCモデルでも全く問題はありません。むしろ、モジュールを細かく分割する必要がなければ、特定のViewControllerにロジックをすべて記載できるMVCモデルの方が、実装がシンプルになる場合もあるでしょう。

ですが、アプリの規模が一定以上大きくなるならば、MVVMモデルの方がより適していると思います。機能ごとにモジュールを適切な粒度に分けやすいですし、データの流れも整理しやすくなるからです。

11

MVCアーキテクチャのモデル図。

12

MVVMアーキテクチャのモデル図。

【Tips5】『UIStackView』を活用し、UIの描画をより滑らかにする

──他に、iOSアプリの「画面描画を滑らかにする」という観点で実施したことはありますか?

ティム 『UITableView』から『UIStackView』への変更です。

かつて、iOS版の『メルカリ』では情報をリスト表示する際などにAppleが提供している『UITableView』という機能を使用していました。これはiOSのバージョン2からある機能で一般的にもよく使われていますが、技術的な問題をいくつか抱えています。

例えば、メモリ消費が多く処理が重くなりやすい、ユーザーにとって違和感のある挙動(ユーザーが何か操作をすると、画面に表示されていたキーボードが消えるなど)が起こりやすい、などです。

そこで、リアーキテクチャに伴い、『UITableView』ではなくAppleが提供する新しい機能である『UIStackView』を用いてUIを描画するように刷新しました。

これは、Micro ViewControllerという設計思想を導入した機能です。画面内にある各要素を、非常に小さな単位のViewControllerによってコントロールします。例えば、画面内にある1つのボタンに対し、1つのViewControllerが対応するようなイメージです。

各要素を別々のViewControllerによって操作するため、ユーザーが画面の要素に対して特定の操作をした際、別の要素に対して影響が出にくいという長所があります。また、ViewControllerが行う仕事もシンプルになるため、設計も分かりやすくなります。

読者のなかには、「ViewControllerのClass数が増えることで、パフォーマンスが悪化するのでは」と気になる方もいるかもしれませんが、たくさんの要素を画面に表示しても動作は全く遅くなりません。画面の要素数が多いアプリを開発する上では、かなり役に立つ技術だと思います。

高山 さらに言えば、Micro ViewControllerの設計を導入することで1つの画面を複数のエンジニアで並行開発しやすくなるというメリットもあります。各要素のコンポーネント化が進み、分業が容易になるからです。

──まさに、メンバーの数が右肩上がりで増えているメルカリに適した設計というわけですね!

Androidアプリの高速化を見据えた技術

【Tips6】 よりスケール可能でスピーディーな開発を実現するため、アーキテクチャを刷新

──Androidアプリにおいても、リアーキテクチャのプロジェクトが実施されていると聞きました。具体的にはどのような変更がなされているのでしょうか?

イスラエル 1つのアプリケーションを複数人で同時並行して開発できるようにするべく、アプリケーションを細分化するコンポーネント化に取り組んでいます。

その前段階として、各画面をリファクタリングして一貫したデザインパターンで実装し、今後の拡張を容易にする取り組みを行っています。

設計は MVPパターンに近いものになっていますが、重要なのはテスト可能な設計であること、一貫性があることと考えています。そのために

  • 依存性注入
  • 3層レイヤーを持つこと
  • 単一責任原則

という3つの原則に従うことを重要視しています。デザインパターンは時代によって移り変わりがありますが、原則はそれほど大きく変わることはないからです。

上記の内容はイスラエルさんの発表資料にも詳しい。

──Androidのリアーキテクチャは高速化にどのように寄与するのでしょうか。

イスラエル Androidのリアーキテクチャはリファクタリングで進めています。不要なコードや無駄な処理が減るため高速化に貢献すると言えます。不要なネットワークリクエストを削減することで、画面描画までのレイテンシも下がり、お客さまの使い勝手の向上につながります。

13

ソフトウェアエンジニア イスラエル・フェラー・カマチョさん

高山 iOSのリアーキテクチャとAndroidのリアーキテクチャは、実施する内容は異なるもののゴールは一緒です。今後エンジニアの人数が増えていっても、開発効率を落とさずにスピーディーな開発ができる体制を構築するというのが共通の目的になります。

──マイクロサービス的な設計をし、細かいコンポーネントを複数組み合わせることでサービスを作るという考え方は近年主流になっていると感じます。これまでメルカリでそれをやっていなかったのは、どうしてなのでしょうか?

イスラエル 大きく分けて、技術的な理由と組織体制的な理由の2つがあると思います。

技術的な理由としては、これは私の考えですが、Androidのバーチャルマシン(以下、VM)に仕様上の制約があったことが大きいです。

かつて、Androidでは『Dalvik』というVMが用いられていました。このVMではアプリの情報をdexというファイルに格納するのですが、1つのdex内に格納できるメソッド数には65k(正確には65,536)という上限がありました。そのため開発者はなるべくメソッドを増やしすぎないように設計・実装する必要があったんです。

その後、1つのapkにdexファイルを複数持たせられる『Multi-dex Support』という仕組みが登場しましたが、これもdexの個数の上限が100までという制約があり、いつかは限界に達してしまいます。

ですが、近年登場したARTというVMでは機能がかなり拡張され、制約が取り払われたんです。その技術革新があったため、粒度の細かいClassをたくさん作るような設計が可能になったと、私は考えています。

──それに伴い、Androidアプリの設計手法も今後は変化してきそうですね。組織体制的な理由としては?

高山 社内にいるエンジニアの人数が急激に増えているためです。かつては少人数で開発をしていたため、多くのメンバーはアプリの全体像を把握していました。どのモジュールに何が書かれているかを理解していたため、粒度の大きなClassを使ってもそれほど問題は起きなかったんです。

けれど、人数が増えてきた現在では「途中から参画したメンバーにとって、アプリの全体像を理解する難易度は高い」ということを前提に設計を見直さなければいけません。そう考えたとき、各コンポーネントを細分化し、より分業による開発がやりやすいようにモデルチェンジすることがベストだと考えました。

──開発体制の変更に伴い、最適な設計も変化していくわけですね。

高山 そうですね。もしも少人数の開発メンバーで小規模なアプリを開発するならば、やみくもにコンポーネント分割をしてもかえって工数が膨らんでしまいあまりメリットがありません。

これまではとにかくスピーディに機能実装し、『メルカリ』のサービスとしての成長を促してきました。そうして生み出されたソースコードを、今リファクタリングし、今後何年も戦っていけるように整えているところです。非常にエキサイティングなタイミングですね。

イスラエル 今後も『メルカリ』に関わるAndroidエンジニアの人数が増えていくことを考えると、開発のスケーラビリティを考えなければいけません。今後もスピード感を落とさずサービスを改善していけるように、アーキテクチャを最適化し続けているんです。

付録~UX改善を支える技術

【Tips7】ロギングとA/Bテストを徹底し、リリースすべき機能を判断する

──画面表示の高速化以外に、“UX改善”という観点で実施していることがあれば、ぜひ教えてください。

ティム ロギングとA/Bテストですかね。

『メルカリ』では、アプリ上でユーザーが行った操作をすべてロギングしています。どの商品を閲覧したか、どれくらいページに滞在したか、どんなボタンを押したかなど、とにかくすべての操作のログを取得しているんです。

また、新機能をリリースする場合には、必ずA/Bテストをして改善前と改善後を比較します。結果を検証したうえで正式にリリースされるフローになっているんです。

──ログの解析結果をもとにリリースの「OK」「NG」の判断をしているかと思いますが、例えば何の数字を見ることによって「良くなった」とするのでしょうか?

14

エンジニアリング・マネージャ 高山征大さん

高山 社内にBI(Business Intelligence)や分析の専門のチームがあり、彼らが検証対象となる新機能を使った人の購入率や出品率、リテンションレート、回遊率といった値の推移をチェックしています。数十個ものA/Bテストが並行して実施されており、なかには半年~1年くらいの長期スパンで検証されるようなものもあります。

【Tips8】とにかくユーザーの声を聞き、本質的な課題は何かを考える

──カスタマーサポートを充実させるなど、ユーザーの声を徹底的に聞くことは『メルカリ』の大きな特徴の1つかと思います。声を拾い上げ、UX改善に結びつける上で工夫していることはありますか?

高山 まず、ユーザーの声を聞く手法としては大きく分けて2つを用いています。

1つ目は、お客さまからカスタマーサポートに届く問い合わせの内容を分析するという方法です。これは、昔からずっと続けているベーシックなものですね。

2つ目は、ユーザビリティテストという手法です。これは1週間に1回くらいのペースで実施しているもので、新機能のリリースや施策の実施後に、ユーザーのペインポイントがどれほど解消されているかをインタビューしています。

どちらの場合も重要なのは、ユーザーから挙がってきた意見をそのまま機能に反映“させない”ことです。その裏にある「本質的に解決すべき課題」は何かを考え、ブレークダウンした内容を機能に落とし込んでいきます。

──ユーザーの意見から本質的な課題を抽出して、機能に結びつけた事例を挙げてもらえますか?

高山 最近、一部のカテゴリでリリースした「オファー機能」が良い例だと思います。これは、出品者との価格交渉を、他のお客さまが閲覧できない状態で行なえるというものです。

15

多くのお客さまから、「コメント欄で値下げ交渉などをされるのがつらい。返信が非常に億劫だ」という意見が挙がっていました。なかには、それが原因で『メルカリ』そのものが嫌になってしまったという方もいました。

なぜそれほどコメント欄での値下げ交渉が嫌なのかを深堀りしてみると、他のお客さまから「コメントにきちんと返事をしない出品者だ」と思われてしまうことがネガティブ要因の1つと考えられます。

そこで、出品者さまと購入(検討)者さまとのやりとりがクローズドな環境で行われれば、心理的な負担がかなり減るだろう、という仮説を立てました。仮にオファーに対して返事をしなかったとしても、他のお客さまには見えず、「出品者さまが傲慢な人だ」という勘違いを避けられます。

これはあくまで一例ですが、『メルカリ』ではこのようなフローで実装すべき機能を考えていくことが多いですね。

16

機能追加・変更のフロー。

「身近な人たちが使うサービスを作る」という醍醐味

──最後に、メルカリでエンジニアとして働くやりがいについて教えてください。

高山 僕は昔から「自分にとって身近な人たちが使うサービスを作りたい」とずっと考えてきました。かつて僕はテレビを作るエンジニアだった時代もあるんですが、当時も自分の親戚みんなにテレビを買ってもらい、日常的に使ってもらえていたことに喜びを感じていました。

『メルカリ』はまさに、そんな“誰もが使っているアプリ”になりつつあると思います。親戚も、配偶者も、電車でたまたま横に座った人もみんな使ってくれている。そういうところに、大きなモチベーションを感じます。

──メルカリは本当に、社会にとっての“インフラ”になりつつありますよね。イスラエルさんはどうでしょうか?

イスラエル メルカリでエンジニアとして働く醍醐味は、企業のバリューとして掲げられている「Go Bold - 大胆にやろう」というフレーズによく表れていると思います。

メルカリには「常にプロダクトを大胆に改善する」文化があります。誰かに指示を受けなくても、エンジニアたちが自分自身で考え、自ら改善していく。そしてそれが社内で受け入れられていく。その柔軟さが大きな魅力です。

それに、他でもない私自身、『メルカリ』が大好きなんです。私はまだ日本に来てから4か月(取材当時)しか経っていないですが、その間に約20個もの商品を購入しました(笑)。自分が追加した機能がアプリで実際に動いているのを目にすると、本当に幸せな気持ちになります。

──4か月で約20個とは! 本当にメルカリを愛しているんですね。ティムさんは?

ティム メルカリはカッティングエッジ(最先端)の技術を積極的に導入しているのが素晴らしいとよく思います。今回私はiOSアプリ開発におけるSwiftの話をメインでしましたが、世の中にはまだまだObjective-Cを使っている会社だって多いです。

すべての領域において技術的なチャレンジを続けていることが、サービスにとっても、働くエンジニアにとっても、プラスの影響を及ぼしていると思います。

──確かに今回のお話からは、『メルカリ』が持つ最新技術への探究心が伝わってきました。それでは、締めに久保さんお願いします!

久保 『メルカリ』はエンジニア個人に与えらえる裁量が非常に大きい会社です。誰かが「こういうことをやりたいです」という意見を出し、理にかなっているならば、「じゃあやろう」とスピーディーに意思決定がされます。それが大きな長所です。

それに、周りに優秀な人たちがたくさんいるので、彼らと一緒に働けることが何よりの醍醐味ですね。自分が強みを持つ技術領域と、他のメンバーが強みを持つ技術領域を組み合わせていくことで、一人では解決するのが難しい課題も解決できると考えています。

──メルカリが今後もより良いアプリになっていくのを楽しみにしています。どうもありがとうございました!

取材・執筆:中薗昴/写真:依央


  1. メルカリに商品を出品する際、画像を解析して商品のタイトルやカテゴリなどを自動で割り振ってくれる機能。

  2. 値の集合の中で小さい方から95(99)%に位置する値