グロースハックとディレクションとAndroid開発を経験した1年の振り返り

f:id:metal_president:20181217102801j:plain
BASE Advent Calendar 2018 17日目

この記事は「BASE Advent Calendar 2018」17日目の記事です。

devblog.thebase.in

はじめに

はじめまして。Native Application Group の木下です。主にAndroidアプリの開発を担当しています。 今年はアプリの開発に留まらず、プロジェクトのディレクションやグロースハックといった分野にも少し手を出してきましたので、1年を振り返りながら知見などを共有できればと思います。

最近のBASEの組織

最近のBASEでは「グループ」と「プロジェクト」の二つの組織体系で業務を行なっています。

「グループ」はデザイン・バックエンド・アプリ・SREなど、スキルや分野によって分類された組織で、私の所属する Native Application Group では、日常的にスマホアプリに関する次のような業務を行なっています。

  • 他部署からの要望にもとづく機能開発
  • 不具合やOSのアップデート対応
  • 新しい技術の組み込みや技術的負債の解消
  • 開発環境の基盤づくり
  • 新バージョンのリリース

これに対して「プロジェクト」はクォータごとに目的・目標(KGI)と期限が設定され、目標を達成すべく、各「グループ」から選抜されたメンバーで構成される組織になります。同時に複数のプロジェクトに所属するケースもあります。

プロジェクトのイメージ

プロジェクト名 目的 KGI プロジェクト
マネージャ
ディレクター デザイン バックエンド アプリ
プロジェクトA
プロジェクトB
プロジェクトC

はじめてのグロースハック

2018年の各クォータで所属した「プロジェクト」では、ディレクターかAndroidアプリエンジニア、もしくは両方のポジションに就き、特に1Qと2Qでは数値改善を目的としたグロースハック系のプロジェクトを担当しました。 グロースハックはほぼ未経験でしたので、まずは基礎知識を身につけなければと思い関連する書籍を読みました。特に参考になった2つを紹介します。

「いちばんやさしいグロースハックの教本 人気講師が教える急成長マーケティング戦略」

タイトルのとおり、初心者向けでとてもわかり易い内容でした。

「データ・ドリブン・マーケティング―――最低限知っておくべき15の指標」

紹介文の “ジェフ・ベゾスが愛読! 世界最強のマーケティング企業 アマゾン社員の教科書” に惹かれて読んでみました。プロダクトの意思決定で重要となる15の指標についての説明が、実例を交えながら書かれています。

まずはデータ収集から

グロースハックでは仮説・検証を繰り返し行いますが、その前段として現状を捕らえるためにデータ集めを行いました。

ショッピングアプリ「BASE」では、Firebase Analytics でイベントログを収集して、BigQuery にインポートし、Redash を使ってモニタリングしています。社内には50インチ以上の大型ディスプレイが何枚もあり、さまざまな指標やサービスの状況をモニタリングできるようになっています。

Redashの導入・布教については過去の記事をご覧ください。

devblog.thebase.in

はじめの頃は個人的にRedashではなくData Studio(今のデータポータル)を利用していましたが、グラフのレイアウト調整などが地味に面倒だったり、社内的にRedashの布教が進んでいたこともあり、途中でRedashに切り替えました。

Data Studio はダッシュボードを Google Driveのファイルとして扱え、アカウントや権限の管理が簡単だったりと良い点もありますが、日々新たなダッシュボードを追加していくとなると、多機能すぎてちょっと扱いづらいかなと思いました。

KGIからKPI、施策から効果測定まで

前述のとおりプロジェクトごとにKGI(Key Goal Indicator : 重要目標達成指標)が設定されます。KGIには最終的なゴールとなる指標が設定されるため、直接KGIを上げようとしても具体的な施策を立てるのが困難でした。このため、まずKGIを構成するいくつかのKPI(Key Performance Indicator : 重要業績評価指標)に分解して、このKPIをあげるための施策(ユーザー体験や機能の改善)を検討して実施(開発・リリース)する流れとしました。

ダイエットに例えるとこんな感じです。

  • KGI : (3ヶ月で)体重マイナス10kg
    • KPI(1) : 1日の摂取カロリーを300kcal削減する
      • 施策(1-1) : 夕食のご飯の量を50%削減する
      • 施策(1-2) : 3時のおやつを廃止する
    • KPI(2) : 1日の消費カロリーを300kcal増加させる
      • 施策(2-1) : 通勤電車では椅子に座らない
      • 施策(2-2) : 毎日5kmジョギングする

施策を実施したら効果測定を行います。リリースと同時にRedashを使ってモニタリングを開始し、KPIとKGIの動向を追います。KPIが改善されてもKGIに影響しない(仮説が外れる)こともあるため必ず両方を見ます。

改善されない場合や不十分な場合は、施策の内容を改善したり、施策をキャンセルすることもあります。ダイエットの例であれば、1ヶ月経っても体重が減らない場合は「ジョギングの距離を10kmに変更する」といった感じになります。

プロジェクトのディレクション

続いてプロジェクトのディレクションについてです。 BASEにおけるディレクターの役割については次のように考えています。

メンバーの活動を最適化して、プロジェクトが成功する確率をできる限り高めること。

プロジェクトを成功させるのはあくまで各メンバーであって、環境づくりや交通整理をするのがディレクターの役割であると考えています。ディレクターが重要な意思決定を下したり、仕様を決めたりするのは適切でないと思います。特にBASEは数字やデータに基づきシンプルに意思決定する文化のため、この考えは適していると思います。

また、ディレクター要因でプロジェクトの進行やメンバーの活動を鈍らせることは絶対にあってはいけないと考えます。1Q=3ヶ月、という短い期間で目標を達成しなければいけないため、特にこの点は特に留意しました。

ディレクターとしてやったこと

ディレクターに就いた直後は、何を期待されているのか?何をやれば良いのか?よく分からず右往左往した時期もありましたが、いろいろと試行錯誤した結果、主に次のようなことをすることとしました。

プロジェクト開始前

  • プロダクトマネージャーからプロジェクトの目的についての背景や詳細、マストでやりたい施策についてのヒアリング
  • 施策ごとに作成するドキュメントのテンプレート作成
  • 主要KPIの設定

プロジェクトの立ち上げ

  • キックオフミーティング
    • プロジェクトの目的やKGI、プロダクトマネージャーの意向などを共有
    • 定例ミーティングの調整
  • メンバー全員で施策ブレスト
    • 施策案出し
    • 施策の規模感や実現性の確認
    • 優先順位付け
  • マスタスケジュール作成
    • BASEでは Asana を活用しています

プロジェクト中

  • ミーティングのファシリテーション
    • Dailyでスタンドアップミーティング
    • Weeklyでミーティング(進捗確認、施策の結果共有、追加施策の検討)
  • 進捗把握とフォロー
  • リリースや効果測定のサポート

プロジェクト終了後

  • KPTでの振り返り

納得感と温度感

プロジェクトはKGI/PKIを達成するために活動しますが、各施策についてメンバーが納得感を持つことが重要だと考えます。

なぜそれをやるのか?プロジェクトに貢献できる施策なのか?ユーザー体験は改善されるのか・悪化しないか?...などプロジェクトの目標は共通であったとしてもメンバーごとの視点は異なり、納得感が高ければ施策の質も高めることができ、より良い結果が期待できると思います。 この納得感を高めるため、ブレストで作成した施策案リストに次のような「いいね」欄を設けて、温度感を可視化することとしました。

ミーティング中に「この施策どう思いますか?」と聞いても、声の大きい人の意見で染まったり、分からないことがあっても今更聞きづらい空気ができてしまっている場合もあり、メンバーそれぞれの納得感を確認し高めることは難しいため、カジュアルに可視化できる仕組みとしてトライしてみました。

f:id:metal_president:20181217103531p:plain

この「いいね」で多数決することはしませんが、優先順位に多少は影響しました。中にはプロダクトマネージャーの挙げた施策でも、「いいね」数が少なく優先順位を下げることもありました。温度感の高い施策について重点的に議論を進めることができました。逆に効果が期待できそうなのに温度感の低い施策については、施策内容を掘り下げて納得感を高めにいくことができました。

測定不能

様々な施策を実施する中で、1つ大きくハマったことがありましたので紹介しておきます。

施策をリリースしたら効果測定するようにしていますが、測定できなくなる事態が度々発生しました。主な原因は2つあります。

  1. 同じKPIに影響する複数の施策を同時期にリリースしてしまった
  2. セールなどのキャンペーンやTVCMの放送と施策のリリース時期が重なった

一つ目の施策が重なる問題については、KPIが改善されてもどの施策が効いているのか特定するのが困難になります。プロジェクト内でやってしまうケースや他のプロジェクトの施策と重なるケースがあり、前者の場合はプロジェクト内で注意しながらリリースのスケジュールを策定していれば回避できるのですが、後者の場合は他プロジェクトとリリース時期を地道に調整することで回避するしかないかなと思います。

二つ目のキャンペーン等については、 KPI/KGIへの影響が非常に大きく期間も長いため、完全にお手上げとなります。社内にアンテナを張って、キャンペーンが始まる時期を早めに察知し、リリースや開発のスケジュールを調整することで防いでいくしかないかなと思っています。

Androidアプリの開発について

最後になりますが、この1年でAndroidアプリ開発もいろいろ変化しました。

CI環境の移行(Bitrise + Danger)

昨年までは Jenkins(社内のMac miniで稼働)でビルドしていましたが、今年に入ってから Bitriseへ移行しました。Bitrise を選んだのは Circle CI のようなメモリ制限(4GB)がないのと、モダンなUIでカジュアルに利用できそうで周囲でも流行っていた、という理由でした。最初の立ち上げは他のメンバーが対応していましたが、比較的スムーズに移行できたと思います。

そして、せっかくBitriseを導入したのだからもっと活用しようと思い、Dangerを導入しました。Danger を使うと、Pull Request などをトリガーとして、PRの内容をチェックしてワーニングやエラーなどのコメントを自動で表示することができます。エラーの場合はマージ不可とすることも可能です。

実際の Dangerfile は次のような内容となっていて、PR作成・更新時にチェックが走ります。

is_release = github.pr_labels.include? "[RELEASE]"

#  WIP
warn("PR is classed as Work in Progress") if github.pr_title.include? "WIP"

# PRが大きすぎる(リリース用のPRは除外)
warn("Big PR, over 1000 lines") if git.lines_of_code > 1000 && !is_release

# 誰もアサインされていない
has_assignee = github.pr_json["assignee"] != nil
warn("Please assign", sticky: false) unless has_assignee

# release以外からmasterへマージ
is_to_master = github.branch_for_base == "master"
is_from_release = github.branch_for_head.include?("release")
fail("You can only merge to the master branch from the release branch") if is_to_master && !is_from_release

# ファイルの変更検知
protected_files = ["build.gradle", "proguard-rules.pro", "version.properties", ".gitignore"]
protected_files.each do |file|
  next if git.modified_files.grep(/#{file}/).empty?
  message("Changes have been made to the #{file} file")
end

Androidチームでは、次のようなブランチ運用を行なっています。

  1. リリースの時期とスコープを決めてreleaseブランチを作成
  2. feature ブランチを作成して開発
  3. release ブランチへPull Request(WIPで早めに出していつでもレビュー可能に)
  4. レビューが完了したらマージ
  5. release ブランチでQAが完了したら masterブランチへPull Request
  6. master へマージすると同時に自動で本番ビルド開始
  7. リリース

このように develop ブランチが存在しないためシンプルな運用が可能です。しかし master をデフォルトブランチに設定していることで時々事故が起きていました。通常 Pull Request は release に向けて作成するべきですが、誤って master に向けて作成してしまうことがあり、レビューでも気づかれずそのままマージしてしまうことが何度か発生しました。本番ビルドが走ってしまったり(Publishは自動化していないのでセーフですが)、Revertする手間が発生したりと、地味に面倒な作業が発生します。これを防止するためDangerにチェック項目を追加してPR先が master の場合はマージ不可することで、このような事故は発生しなくなりました。

コードレビュー必須化

Androidチームのメンバーも増え、品質を維持したり技術的負債を増やさないためにも昨年末からコードレビューを必須とし、メンバー全員からapprovedされるまでマージできないルールとしました。

自分自身、前職くらいからコードレビューをやり始めてはいましたが、仕様を満たしているかのチェックがメインであまりコードレビューと言えるものではありませんでした。必須化した直後は要領よくレビューができずに、場合によってはほぼ「ノールックLGTM」していた時もありましたが、最近ではレビューの質もあがり主に次のような点を見るようにしています。

  • 将来負債になったり不具合の原因となりそうな実装がされていないか
  • MVVMモデルに則した実装となっているか
  • Nonnull / Nullable の区別は適切か
  • スコープ関数を利用したkotlinらしいコードになっているか
  • kotlinで Utilsクラスや Stream を利用していないか

また若いエンジニアからも鋭い指摘をもらうことがあり本当にありがたい限りです。Kotlinだとこんな書き方もできますよ、といった感じで知識を共有する場にもなったり、チーム開発&コードレビューって素晴らしいな〜と感じるようになりました。

ちなみにレビューの負荷軽減・レビューによる手戻り削減のため、作業を始めたらなるべく早く WIPで Pull Requestを出し、余裕のあるときにレビューするようにしています。突然「急ぎでレビューお願いします」と言われても、すぐに時間が取れず雑にLGTMしたり、ほんとは指摘したいけど修正しているとリリースに間に合わないから今回は指摘しないでおこう、など良くない状況が起こり得るため早めにレビューできる運用を心がけています。

TLS1.2対応とAndroid4.xサポート終了

BASEではセキュリティ対策の一環として、今年の6月にサーバーをTLS1.2へ移行する計画があり、これに合わせて Android4.x のサポートを終了することとなりました。

1ヶ月前からアプリ内のお知らせやGoogle Play のアプリページに告知を表示して、Android4.x の端末からは(TLS1.2に対応している)ChromeブラウザのWebページからご利用いただくようお願いしていました。(BASEの場合、アプリだけでなくWebページからも商品が購入できる点は強みだと感じました。)

また、移行したタイミングで4.x端末でアプリを起動すると、サポートを終了した旨のメッセージを表示して起動を中断する仕組みを、早い段階で仕込んでいました。

普通であれば要求を受けた何かしらのAPIがOSのバージョンをチェックして4.xならエラーを返す、という設計を考えると思いますが、TLS1.2未対応のクライアントからはAPIに一切接続することができなくなるため、アプリ起動後最初のAPI接続の前に上記のような仕組みを入れることで、アプリがクラッシュしたり「ネットワークエラー」のような意味不明なメッセージを表示することがないようにしました。この仕組みはFirebase RemoteConfg を利用して実現しています。 結果として、一部のユーザー様にはご迷惑をおかけしましたが、大きなトラブルもなくスムーズに移行することができました。

Kotlin化

BASEアプリのKotlin化進捗状況です。

f:id:metal_president:20181217103930p:plain

もともとオールJavaでしたが、2017年のGoogle I/OでKotlinの正式サポートが発表されたのをきっかけにKotlinの導入をはじめました。 ひとまず、

  • 新機能/クラスはKotlinで実装しよう
  • (あとは余裕あるときに徐々にやっていこう...)

なノリで移行を続けて1年半が経ちましたが、思ったほどKotlin化が進まず、2020年になってもJavaを書いてるのは嫌だなー(バージョン1.1のころからJavaに触れている身としては切実です)と思い、

  • 少しでも修正するJavaファイルはKotlinにコンバートする

というルールを最近になって追加しました。

f:id:metal_president:20181217103606p:plain

来年中にKotlin 100%を達成できるよう頑張りたいと思います。

AndroidX移行

AndroidXの移行については、このスライド を見て詳細を把握し、直後にIssueを立てAndroid Studio3.2(正式版)がリリースされたタイミングで対応する予定でした。今後公開されるドキュメントはAndroidX前提で書かれ、AndroidXでしか利用できない機能・クラスも増えてくるだろうと考えて、放置していても負債にしかならいと判断したためです。

AndroidXは皆さんお馴染み Support Library の改良版です。Support Library は9月にリリースされた Revision 28.0.0 で終了しており、今後は AndroidX へ移行する必要があります。

Android Studio 3.2 以降では移行ツールが用意されドキュメントも整備されていますので、まだ対応されていない皆さんには早めの対応をお勧めします。

実際に対応したのは他のメンバー(Android歴1年未満の若手エンジニア)で、QA含めて2週間くらいで完了し10月上旬にリリースしましたが、リリース後も特に問題はなくスムーズに移行できたと思います。もちろんコードレビューもしっかりやりました。

まとめ

2018年は、Androidアプリの開発だけでなくプロダクトやチームの成長にも熱中でき、SIer・受託開発歴の長い自分にとっては大変実りのある一年となりました。スタートアップだからこそできる貴重な経験だと思います。

来年もたくさん新しいことにチャレンジしていきたいと思います!

明日はビール部部長の氏原さんです!