こんにちは。検索エンジンチームの宮崎です。 皆さんご存じの通り、LIFULL HOME'Sのメイン機能は 物件の検索 です。 LIFULL HOME'Sでは、 検索機能の大部分 を全文検索エンジンSolrで賄っています。 以下のような機能を検索エンジンで実現しています。 こだわり条件検索(ガスコンロ3口、2階以上、など詳細な条件での検索) 駅・エリアでの絞り込み 地図検索 タグによる物件検索 検索結果の件数 並び順 建物や戸ごとのグルーピング これらの機能を実現している検索エンジンは、 アプリケーション実行基盤やDBに並んでサービス継続のために必要な重要コンポーネント です。 しかし検索エンジンはその特性上、ステートフルなソフトウェアです。 HDFSやその他ストレージと組み合わせることでステートレスにすることもできるかもしれませんが、多くの場合ステートフルなアプリケーションとして運用していることが多いと思います。 今回はステートフルなアプリケーションである検索エンジンを一部スポットインスタンス化することで ランニングコストを削減 したので、構成や進め方について紹介しようと思います。 🔎 全文検索エンジンをスポットインスタンス化??? 全文検索エンジンとは そもそも全文検索エンジンとは何でしょうか? Wikipediaにはこうあります。 全文検索とは、コンピュータにおいて、複数の文書(ファイル)から特定の文字列を検索すること。 「ファイル名検索」や「単一ファイル内の文字列検索」と異なり、 「複数文書にまたがって、文書に含まれる全文を対象とした検索」という意味で使用される。 もともとは多数の文書の中から特定の文字を含む文書を検索するために作られたもののようです。 LIFULL HOME'Sでは文書の代わりに物件情報を検索エンジンに入れて物件の検索を実現しています。 スポットインスタンスとは 次にスポットインスタンスとは何でしょうか? これは、AWS(Amazon Web Services)において、条件付きでマシンを安く使用できるしくみのことです。 その条件というのが、「スポットで起動されたインスタンスはAWS側の都合により、事前の予告なく※1停止されることがある」というものです。 ※: インスタンス停止の2分前に通知されます。 これは、スポットインスタンスのしくみによりそのような条件になっています。 スポットインスタンスは、AWSのクラウド内で使用されていないEC2を安く使えるというしくみです。 誰にも使われてないのはもったいないから、安くてもよいので使ってもらおうということですね。 ステートフルなソフトウェアとスポットインスタンス スポットインスタンスはその特徴から、 公式の説明「ステートレス、耐障害性、または柔軟性を備えたさまざまなアプリケーションでご利用いただけます」にある通り、 ステートレスなアプリケーションで主に利用されます。 任意のタイミングでインスタンスを停止できることと、ステートレスであることは相性がよいからです。 ステートレスであれば、インスタンスを停止したい場合はそのままインスタンスを停止すればよいのです。 (実際には停止時に行いたい処理があることのほうがほとんどだとは思います) さて、検索エンジンはステートフルなソフトウェアでした。 しかしタイトルの通り、 ステートフルでも安くしたい! のです。 そんな検索エンジンをスポットインスタンス化してコスト削減した構成が以下です。 🔗 検索エンジンの構成 検索エンジンは以下のような構成になっています。 Solrクラスタの構成図 一部省略していますが、概略としてはこんな感じです。 Lambdaは、Solrのリーダーにデータを書き込みます。 実際に検索用のクエリを受け取るインスタンスはAutoScalingGroupで管理しています。 AutoScalingGroupを使用しているので、MixedInstancesPolicyを設定することでスポットインスタンスを適用できます。 🤔 工夫点 インスタンス起動時に、systemdでクラスタに自動で参加するようにしている インスタンス停止時に、systemdでクラスタから自動で抜けるようにしている スポットインスタンスの終了通知をEventBridgeで受け取って、ALBから自動で切り離すようにしている 書き込みと読み込みでエンドポイントを分けている クラスタはデプロイ時に全インデックスを再構築できる マスタ/スレーブ構成にすることで参照用Solrはリードオンリーに動作する 「クラスタはデプロイ時に全インデックスを再構築できる」、「マスタ/スレーブ構成にすることで参照用Solrはリードオンリーに動作する」の 2点のおかげで、ステートレスなSolrを実現しています。 ステートレスなSolrを実現するとAutoScalingGroupで管理できるようになり、負荷増に耐えたり柔軟性が上がり、スポットインスタンスで動作させることができています。 またマスタ/スレーブのような構成にすることで、検索クエリの負荷や書き込みの負荷をお互い影響させないようにしています。 📖 結果 EC2インスタンスの支払いの内訳 コストエクスプローラーの数値が見えない状態で切り取ったものです。 オレンジの部分がスポットでかかっている金額です。緑色のオンデマンドの金額がかなり小さくなっているのがわかると思います。 スポットインスタンスが、だいたい正規の値段の1/3程度だったので概算で、1日あたり約20%強のコスト削減を実現しました。 別のプロジェクトで行っていた SavingsPlansによるコスト削減 と含めると、 ほぼオンデマンドで動いているインスタンスがいない状態です。 社員の数が少なければボーナスで焼き肉を食べに行けるくらいにはなったでしょう。 最後に Solrの特徴とAWSをうまく組み合わせることで、耐障害性を確保しつつ、コスト削減を実現しました。 ステートフルなアプリケーションの中の、ステートレスな部分のみスポットインスタンスを適用したという話でした。 もともとイミュータブルに作っていたことや、更新と検索でエンドポイントを分けた構成にしていたことで、 簡単にスポットインスタンスによるコスト削減を実現できました。 アーキテクチャは大事ですね。 カジュアル面談もやっていますので、一緒に「 感動を届ける検索エンジンを実現する 」、ひいてはLIFULLが目指している「 あらゆるLIFEを、FULLに。 」することに興味がある方はぜひお話しましょう!
LIFULLで売却査定サイトの開発をしています、北島です。 このたびTestCafeというE2Eテストを、awsのリソースを使ってクラウド移行しましたので、簡単に振り返りたいと思います。 前提 売却査定のサービスは本番を含めて4つの環境が用意されています。 prod環境(本番) pool環境(開発環境) dev環境(開発環境) unit環境(開発者各々の環境) これらのうちunit環境以外の3環境に関して、デプロイをトリガーにE2Eテストを行うような仕組みを実現しました。 構成図 CodeBuild上でTestCafeを実行することで実現を試みました。 テストに関する構成図を下に示します。 構成図 CodeDeploy(既存)のデプロイ成功時にSNSメッセージを発行し、LambdaFunctionからCodeBuildを実行します。 CodeBuildでのテスト実行終了時に、テスト結果を含むSNSメッセージを発行し、notificationで実行結果を通知します。 構成図内の"env"は、実際にはdev/pool/prodと環境ごとに別々のリソースに分かれています。 awsリソースのメインとなるのはtestcafe_kickerのリポジトリで、テストに関するawsリソース全般に関して扱っています。 実際に使用されるテストコードに関してはcodebuild-testcafeのリポジトリで管理しています。 testcafe_kickerリポジトリ このリポジトリの役割は、CodeBuildを実行するlambdaを管理することです。 今回使用した serverless というフレームワークでは、 CloudFormation テンプレートを使用することで、awsリソースをデプロイすることができます。 lambdaを管理するリポジトリながら、CodeBuildプロジェクトやsnsトピック、及びそれらの間の通知ルールの一括管理が可能となっています。 CodeBuild projectについて メインとなるCodeBuild projectの実装について書いていきます。 serverless.yml templates: # anchor用template定義用 dev_topicName: &testcafe_dev_topic_name testcafe_kicker_dev pool_topicName: &testcafe_pool_topic_name testcafe_kicker_pool prod_topicName: &testcafe_prod_topic_name testcafe_kicker_prod project_name: &testcafe_project_name CodeBuild-TestCafe build_project_properties: &testcafe_build_project_properties Artifacts: Type: NO_ARTIFACTS BadgeEnabled: true BuildBatchConfig: ServiceRole: !GetAtt TestcafeBuildRole.Arn ServiceRole: !GetAtt TestcafeBuildRole.Arn VpcConfig: VpcId: vpc-****** Subnets: - subnet-****** SecurityGroupIds: - sg-****** Source: Auth: Type: OAUTH Location: https://github.com/{#testcafeリポジトリのurl} GitCloneDepth: 1 Type: GITHUB SourceVersion: refs/heads/master ~中略~ Resources: TestcafeBuildProjectDev: DependsOn: - TestcafeBuildPolicies Type: AWS::CodeBuild::Project Properties: <<: *testcafe_build_project_properties Name: !Join - '-' - - *testcafe_project_name - Dev Environment: ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0 Type: LINUX_CONTAINER PrivilegedMode: true EnvironmentVariables: - Name: TESTCAFE_DOMAIN Type: PLAINTEXT Value: https://www-test-~~(テスト対象のドメイン) - Name: ECR_REGION Type: PLAINTEXT Value: !Ref AWS::Region - Name: ECR_URI_LATEST Type: PLAINTEXT Value: !Join - '' - - !Ref AWS::AccountId - '.dkr.ecr.' - !Ref AWS::Region - '.amazonaws.com/' - !Ref TestcafeEcrRepository - ':latest' ロールやセキュリティグループなどをしっかりと定義する必要があります。 またgithub上のテストコードをcloneして実行するので、リポジトリのurlも設定します。 privateリポジトリの場合、認証情報もあらかじめawsコンソール上で登録しておき、cloneに成功するようにしておく必要があります。 テスト実施時のコマンドは、このプロジェクト自体に定義するほか、cloneしたリポジトリ内で定義されたものを使うようにも設定できます。 実際のテスト実施時のコマンドはテストコード毎に異なってくるので、このリポジトリではなくTestCafeリポジトリで定義されたものを使うようにしています。 buildspecに書けないテスト対象のドメインなどは、プロジェクトの環境変数としてテンプレートに定義しておきます。 TestCafeリポジトリ このリポジトリの役割は、TestCafeのテストコードを管理することです。 ローカル実行できるようなテストコードを作成しています。 これをDocker内でも実行できるように調整したうえで、CodeBuild上で行いたいコマンドをbuildspec.ymlに記述することで、CodeBuild プロジェクトでも実行できるようになります。 buildspec.ymlを見ていきます。 version: 0.2 batch: build-list: - identifier: pc_page env: variables: UA: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/604.1.38 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/604.1' testcase: "'chromium:headless' tests/page/" - identifier: pc_inquire env: variables: UA: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/604.1.38 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/604.1' testcase: "'chromium:headless' tests/pc/inquire" OVERWRITE_COOKIE: 'abtest_AB=a;' - identifier: sp_page env: variables: UA: 'Mozilla/5.0(iPad;CPUOS11_0likeMacOSX)AppleWebKit/604.1.34(KHTML,likeGecko)Version/11.0Mobile/15A5341fSafari/604.1' testcase: "'chromium:headless:emulation:device=iphoneX' tests/page/" - identifier: sp_inquire env: variables: UA: 'Mozilla/5.0(iPad;CPUOS11_0likeMacOSX)AppleWebKit/604.1.34(KHTML,likeGecko)Version/11.0Mobile/15A5341fSafari/604.1' testcase: "'chromium:headless:emulation:device=iphoneX' tests/sp/inquire/" - identifier: bot_page env: variables: UA: 'Googlebot/2.1 (+http://www.google.com/bot.html)' testcase: "'chromium:headless:emulation:userAgent=Googlebot/2.1(+http://www.google.com/bot.html)' tests/page/" phases: install: commands: - yum update -y - yum install -y bind-utils pre_build: commands: - aws ecr get-login --no-include-email --region ${ECR_REGION} - docker pull ${ECR_URI_LATEST} || true # cache利用目的のpullなのでエラーでもビルドを続ける - docker build --cache-from ${ECR_URI_LATEST} --tag ${ECR_URI_LATEST} . build: commands: - export POOL_IP=`dig +short (pool環境のCDN) | tail -n1` - docker run --env TESTCAFE_DOMAIN --env UA --env OVERWRITE_COOKIE --add-host (poolのドメイン):${POOL_IP} ${ECR_URI_LATEST} /usr/bin/npx testcafe ${testcase} --disable-multiple-windows -q post_build: commands: - aws ecr get-login-password --region ${ECR_REGION} | docker login --username AWS --password-stdin ${ECR_URI_LATEST} - docker push ${ECR_URI_LATEST} 大きく二つ、batchとphaseから構成されています。 phase phaseでは、ビルド内で実際に行いたいテストコマンドを書いていきます。 installやpre_buildなどの詳細なphaseの名前はあらかじめawsによって用意されているので、より細かく分けたい場合はどんなものが使えるのかを調べる必要があります。 ここに書くコマンドはどのビルドでも使用されるので、なるべく簡潔に汎用的に書くことを心掛けました。 docker imageはaws ecrを使用してキャッシュするようになっています。 どこかのphaseで一つのコマンドが正常終了しなかった時点でそのビルドは停止してしまいます。 複数テストコマンドを記述しても途中で終わってしまっては後のテストが実施されないので、テストを行う(正常終了しない可能性のある)コマンドは、一つのビルドにつき1つが望ましいと考えました。 一つのプロジェクトで複数のテストを行いたかったので、今回はバッチビルドによって実現しています。 batch バッチビルドでは、一つのプロジェクトから複数のビルドを作成することが出来ます。 batchという項目ではそれぞれのビルドをどのように、どのような設定で作成するかを定義しています。 build-list は、リストの形で作成するということを意味しており、他にbuild-graphやbuild-matrixという方法が用意されています。 build-listは配列で定義しており、各項目が一つのビルドの設定になっています。なので今回の設定では5つのビルドが作成されるわけです。 identifierはユニークな文字列で設定し、各ビルドの名前になります。わかりやすい文字列が良いでしょう。 envの中ではビルドごとに変えたいパラメータを設定でき、variables内では環境変数を設定できます。 ここでは以下の3つを環境変数として定義しています。 テストを行うUA テストコード(testcase) 特に指定したいcookie(OVERWRITE_COOKIE) これらを設定することで、色々な条件でテストを行うことが出来るようになりました。 検討事項 今回はbuild-listを使用しましたが、build-graphとbuild-matrixの使用も検討しました。 それぞれの性質について、簡単にご紹介します。 build-matrix 最初に検討したのは build-matrix で、これはmatrixとあるように、色々な変数に関して、全組み合わせでビルドを作成します。 例えば、今回は3つの環境変数を使っていますが、 UA2種 testcase3種 OVERWRITE_COOKIE2種 の様に設定した場合、build-matrixでは2*3*2の全組み合わせ、つまり全12個のビルドを作成します。 これはいろいろな環境でビルドを行いたい場合に非常に便利で、当初はこちらを使用していました。 デメリットとしては、例外パターンを作れないことです。全組み合わせに近い11のビルドだけ作成、が出来ない点がデメリットだと思います。 今回私が実現したかったテストは、UAによって行いたいテストケースが異なっており、特にbotではステータスチェックのみを行いたいテストでした。 matrixでは不要なビルドが出来てしまい、matrixの恩恵を受けられないと感じました build-graph build-graph は各ビルドの依存関係を作ることが出来、このビルドが終わったら次のこのビルドを作成、のような設定が作れます。 これも便利な機能で、より詳細にテストを計画することが出来ます。 デメリットは並列実行よりも実行時間が長くなるという点で、より早く行いたい場合はlistやmatrixの方が良いですね。 今回はテスト間に依存関係が無かったので、時間を優先してlistとしました。 しかし特に本番以外の環境に対してテストを行う場合、並列実行数によってはサーバー負荷が問題になってきます。 もしもビルドが増えてきて並列実行が難しくなった場合は、開発用環境のスペックを上げる選択肢だけでなく、build-graphに変更して負荷を減らす選択肢も考えたいと思います。 苦労したこと ネットワーク関連の設定や検証に苦労しました。 CodeBuild プロジェクト自体は開発用の環境に構築したのですが、poolやprod環境は別のawsアカウントを使用しているため、vpcが異なります。 pool環境は通常売却査定のVPC外からアクセスするため、通常の方法では疎通ができませんでした。 最終的に今回は、TestCafeの項のyamlにもあるように、自VPCからでもアクセス可能であったCDNのIPを動的に取得し、それをdockerコマンドのadd-hostオプションとして渡して実行する方法で解決しました。 まとめ 今回は、デプロイ後にE2Eテストを行う工程をCodeBuildを使いクラウド移行しました。 ローカルで行っていたテストが自動化できたので、開発者の時短や、アプリケーションの品質担保に貢献できたと思います。 今後もローカルで行っているフローをクラウド移行していければ良いなと考えています。 ここまで読んでいただき、ありがとうございました。
こんにちは。プロダクトエンジニアリング部の渡邉です。 今回は先日私が所属するプロダクトエンジニアリング部にてオンラインで実施でき、チーム形成とエンジニアが楽しむことができるチームビルディングを開催しましたので、そちらの内容について紹介させていただきたいと思います。 チームビルディングとは チームビルディングとは、組織を単なる「グループ(人の集まり)」で終わらせずに、成果を上げる『チーム』に組成するための一連の手法です。 新しいチームを組成する際には、チームのビジョンや戦略を共有し、所属メンバー一人一人がそれらを自分のものにしなければなりません。 LIFULLでは、期初に各グループに対してチームビルディング予算が割り当てられ、メンバーが自分達で考えたさまざまなチームビルディングが行われています。 そして今回は私たちプロダクトエンジニアリング部2ユニット(※以下ユニット)で行われたチームビルディングについて紹介します。 参加者の構成 LIFULL HOME'S事業本部では現在職種別組織の体制を取っており、私たちのユニットは全員がエンジニアで構成されています。 またユニットの中で3つのグループに分かれており、普段は異なるサービスを開発しています。 今回はその3つのグループが集まり、フロントエンド・バックエンド・マネジメント層など、あらゆる領域を専門とするエンジニアたちでチームビルディングを行いました。 目的 チームビルディングで達成したいゴール 今回チームビルディングを行うにあたって達成したい目的がありました。 それは隣のグループとのコミュニケーションの活性化です。 もともとエンジニアではありながら別サービスに対してコミットをしてきたグループが一つの集団となったこともあり、 お互いのことを知る機会が少ないことが課題でした。 チームビルディングのフレームワークであるタックマンモデルにおいて、チーム形成のプロセスには5段階あると言われています。 現在のユニットはその最初の段階の「形成期」にあてはまるので、お互いに意見をぶつけ合うことができる「混乱期」にステージを進めることをゴールとしました。 ビジョンを交えて実施したい 目的に記載した内容を元にチームビルディングを行うということだけであればみんなで一体感を感じることができるようなアクティビティであったり、 比較的心理的ハードルの低い内容を元に議論を行うといった方法でチームビルディングを行うことも可能ですが、 今回は『エンジニアらしさ』というものにフォーカスを当ててコンテンツを準備しました。 なぜエンジニアらしさにこだわったのか 一つは普段のチームビルディングが企画やデザイナーなどの職種を横断したものであることが多かったのに対し、今回の参加者はエンジニアのみでした。 もう一つはチームのビジョンによるものです。 私たちのチームは”プロダクトエンジニアリング部”という部署であり、プロダクト開発を行うエンジニア組織です。 その部署の達成したいビジョンは"強い個人・最高のチームになることで、価値創造を加速させ続ける"というものになります。 一人一人が強い個人を達成することで最高のチームが形成され価値創造は加速するということを意味しているのですが、 強い個人を達成する一つの指標に"技術力の向上"というものも含まれています。 ですので、今回のチームビルディングでは、ただチームの風通りをよくしたいというだけでなく強い個人の達成というものも意識して強化したいということも含めて『エンジニアらしさ』にこだわって実施することにしました。 どんな内容にしたのか 今回私たちが上述した目的を達成するために選んだ手法は 自作のエンジニア謎解き を開催するというものでした。 どんな風に実施したのか 形式はGitHubにエンジニアらしい分野ごとのクイズを用意し、解答をスプレッドシート上で解答する方式を取りました。 GitHubに用意した問題 クイズはチームビルディング運営メンバーで分担して考え、LIFULLらしさを活かした問題など、さまざまな問題を用意しました。 エンジニアなら答えられて当然!?な問題や 暗号を解読する問題 今回の問題のために準備されたデータベースから答えを導く、エンジニアの腕がなるような問題もあります。 中には、アルゴリズムを考えるような問題も!( PKU JudgeOnline『Expedition』 改題 ) という具合に、知らないと解けないような問題から頭を使って解く問題、専門性を活かした問題と非常に多岐に渡る領域から問題を作成しました。 問題を作成するにあたって工夫した点 エンジニアそれぞれで得意な領域が違うので、まったく手が付かないことがないように各領域で難易度を考えながら用意しました。 参加者に公開せずに各問題で難易度に応じて配点を設けて、「これは難しいから配点が高いのではないか」「まずは簡単そうなやつから解いて着実に稼ごう」などゲーム性を持たせて少しでも参加者のみんなが楽しめるように運営メンバーで考えました。 当日の様子 実際に解き始めると各チーム取り組み方が違いました。全問題を一つずつみんなで解答していてくチームもあれば、得意分野ごとに各自別れて解答していくチームもありました。 実際に問題に取り組んでいる時の様子です。基本的にzoomで画面共有しながら解いていました。 みんなで解いているチームは会話量も多かったですが、各自で分かれて解いていたチームは会話量も少なくなりがちでした。 このようなクイズでも、ちゃんと最初に作戦を練るチームがやはり強かったです。見積もることはどんな場面でも大事ですね。 振り返り チームビルディング終了後に参加者へのアンケートを実施したところ、以下のようなコメントが集まりました。 「問題の難易度がバラけていたのでとっつきやすさ/やりがいの両面がありつつ、戦略も考えられる内容だったので良かったです」 「エンジニア歴の浅い私でも解けるようなスプレッドシートやGitの問題など、幅広い問題が考えられていて楽しかったです!」 これらをもとに運営メンバーで振り返ったところ、良かったところと改善できるところが見えてきました。 良かったところ オンラインならではのコンテンツ オンラインでの実施にあたって、全身を使うアクティビティや共通の道具を使ったゲームなどは難しく、 今までのチームビルディングとは違ったやり方を試みる必要がありました。 オンラインでのチームビルディングを成功させるには、ビデオコミュニケーションのために全員の手元にあるPCを十分に活用する必要がありますが、ITエンジニアにPCを持たせたらまさに水を得た魚・鬼に金棒・虎に翼です。 GitHubなどの普段から用いているサービスや、それぞれが得意とする技術を使用することで、スムーズな実施ができました。 置いてけぼりがいない、全員が楽しめる設計 エンジニアとしての基礎知識から、フロントエンジニアが活躍できる問題、論理的思考力で勝負できる問題、ひらめきが重要になる問題、データベース等の知識が問われる問題など専門性の高い問題まで幅広く問題を用意しました。 その結果、問題の取り組みやすさとやりがいが両立され、最後まで全員が楽しめました。 今まで業務で関わらなかったチームメンバーのかっこいい一面を見ることができ、お互いの強みの理解へとつながっているようです。 改善できるところ 運営メンバーと参加者とのコミュニケーション不足 運営メンバーは作問をした立場ですので、必然的に謎解きへの参加はできなくなります。 そのため、今回のチームビルディングを通して運営メンバーと参加者のコミュニケーションはあまり十分ではなかったように感じられました。 事前に 何回か、チームの出した答えが正しいかを聞ける 何回か、他チームの解答状況を確認できる といったような、『クイズ$ミリオネア』の"ライフライン"さながらのルールをうまく作っておくことで、運営メンバーと参加者のコミュニケーションも活性化したかもしれません。 企画者が参加者と同じ立場でゲームに参加できないというケースはよくありますが、どうやってコミュニケーションロスをカバーするかを事前に考えておく必要があると感じました。 チームによるコミュニケーションの差 普段の業務にも通じる部分ですが、チームでたくさんの問題を解くという性質上、チーム内で各々の強みを把握することで有利に進めることができます。 競技として戦略の組み立てがうまいチームが勝つことは望ましいのですが、お互い初対面の場合もあるチームビルディングで戦略的なコミュニケーションをとることが容易でないことは明らかです。 そこで、 お互いがどんなスキルを持っているか どのような方針で問題に取り組むか どのように報告しあうか といった観点を事前に提示したうえで、作戦会議をする時間を設けることで、より円滑なコミュニケーションができたかもしれません。 チームビルディングに限らず言えることですが、明確な話題や流れの設定があると、即席のチームでも短い時間に密度の高いコミュニケーションをできると考えられます。 まとめ エンジニアとしての矜持のもとに個々の持つ強みを発揮し、協力して壁を打ち破るという今回のエンジニア謎解き。 「コードで語れ 頭を使って 謎を解け」と言えるような今回のチームビルディングでは、チームで協力して謎に挑戦することで、お互いの理解と技術的な気付きを得ることができました。 風通しの良さとエンジニアとしての能力を高めてもらうためのいいコンテンツとなったと思います。 完全オンラインでのチームビルディングの一例として、参考になれば幸いです。
こんにちは。テクノロジー本部のyoshikawaです。好きなLinux DistributionはManjaro Linuxです。 今回はレガシー化が進むLIFULLのメインサービスの開発効率の向上とコードベースの健全性の確保をすべく、Clean Architectureを採用しバックエンドを刷新している取り組みについて紹介させていただきます。 なお、Clean Architecture自体の説明および解説は本記事では行いません。 背景:歴史あるバックエンドの刷新 アプローチ:新たなアーキテクチャと共創 採用したアーキテクチャ・技術 Clean Architectureを採用した理由 TypeScriptを採用した理由 LoopBackを採用した理由 Clean Architectureの実践 レイヤー分け:例の図と新BFFアーキテクチャのレイヤーとのマッピング レイヤー内・レイヤー間:独自の規約を導入する 規約違反の検知を自動化する コンポーネントレベルでの規約:物理的なリポジトリ分割 組織構造に追従したリポジトリ分割 Clean Architectureを実践した所感 開発効率の向上とコードベースの健全性の確保は達成できたか? BFFにClean Architectureの規約は複雑すぎないか? 規約の遵守と開発効率の最適化 ドメインモデリングが不足していないか? Clean Architectureを採用したのは正しいかった? 今後導入したいこと 実装効率を向上させるために おわりに:銀の弾丸はない 背景:歴史あるバックエンドの刷新 LIFULLのメインサービスであるLIFULL HOME'Sのバックエンドはその大部分がSymfony(PHP)ベースのモノリスと、ともにSinatra(Ruby)ベースのBFFとAPIサーバーの3層構造で構成されています。 このうち、Symfonyベースのモノリスは9年以上開発されており歴史のあるアプリケーションになっています。 長年の間多くのエンジニアによる開発が行われ、レガシー特有の問題が発生しています。 例えば、以下のような問題が発生しています。 ビジネスロジックの複雑化、およびテンプレートエンジン(Twig)内のロジックとの混在化・密結合化 APIおよびシステム内部のドキュメントが充実しておらず、I/Oがわかりにくい 異なるユースケース・開発組織(アクター)が利用しているなど、責務の不明瞭なモジュールが偏在している このような問題の結果、開発効率の観点で以下の課題が生じています。 一度の変更が予期せぬ影響を与え得るため、新機能追加のための調査・設計・実装に時間がかかる 一度の変更による影響範囲が広く、機能改修のための影響範囲分析に時間がかかる 品質維持のための工数効率が悪い、バージョンアップがしづらい こうした課題を解決すべく、バックエンドを刷新するプロジェクトが発足しました。 アプローチ:新たなアーキテクチャと共創 LIFULL HOME'Sの大部分のバックエンドは先述のSymfonyベースのモノリスに加え、ともにSinatra(Ruby)ベースの既存BFFとAPIサーバーの3層構造で構成されています。 この既存BFFにリファクタリングを行い、モノリスからビジネスロジックを移植することで開発効率の向上と健全性の確保を行うアプローチも考えられました。 検証の結果、モノリス上のビジネスロジックの移植対象をこの既存BFFではなく新しいBackend For Frontend(以降、 新BFF と呼びます)に移植する、というアプローチによってバックエンドの複雑度を下げ開発効率を向上と健全性の確保を行うことになりました。 いわゆるストラングラーパターン(Strangler Fig Application)のアプローチに相当します。 martinfowler.com 現在は筆者を含めた数人のバックエンド刷新プロジェクトのチームメンバーが主体となって実装を進めていますが、今後は LIFULL HOME'Sに関わる多くのエンジニア と共に移植作業を行い、 共創 して刷新を遂行していく予定です。 採用したアーキテクチャ・技術 新BFFの技術スタック; Clean Architectueベース、言語はTypeScriptを採用 新BFFのアーキテクチャは「 Clean Architecture 」、言語は「 TypeScript 」、フレームワークは「 LoopBack 」を採用しています。 blog.cleancoder.com loopback.io この3つの技術が選定された理由を紹介していきます。 Clean Architectureを採用した理由 採用した理由は複数あります。いくつか列挙すると、 著名かつ制約の厳しいアーキテクチャであり、実装の方言が生まれにくい。そのため多数のエンジニアが開発しても共通認識が持ちやすく。アーキテクチャの遵守が期待される DDDのパターン(レイヤードアーキテクチャ)の実装表現の一つであり、自己文書化をはじめとしたDDDの恩恵を受けることができる 実装の「詳細」を「抽象」に依存させることで、フレームワークやライブラリとの依存を減らし、バージョンアップを行いやすくすることが可能 物理的・概念的なレイヤー間の責務を明確にしやすく、 オニオンアーキテクチャやヘキサゴナルアーキテクチャと比較すると書籍などの学習資料が充実している などが挙げられます。 決め手となっていることは、最初に挙げたように 「アーキテクチャレベルで明確な共通言語があること」 です。 新BFFは長年に渡って多数のエンジニアによって開発されることが見込まれるため、健全性を保ったコンポーネントにするためにはアーキテクチャの共通言語を用意することは重要な観点でした。 一方で、Clean Architectureは学習コストが高く、その性質上Dto(Data Transfer Object)やInterfaceの実装量が増えたり冗長な実装が増えたりするというデメリットも存在し、開発効率向上には貢献しない可能性も考えられました。 この辺りの対処については後述します。 TypeScriptを採用した理由 言語のその他候補にはGolangやKotlinがありましたが、以下の理由からTypeScriptが採用されました。 漸進型付き/静的型付き言語により、これまでの開発環境にはなかった以下の強力な恩恵が受けられること データ構造が明確になることで、設計、実装およびIDEに頼ったリファクタリングのコストが下がる 型付けによって、APIドキュメンテーションの自動化が可能になること 多くのエンジニアが実装する(共創する)以上、学習コストの低い言語が望ましいこと フロントエンドと言語を一致させることで、学習コストの発生確率を下げて実装可能なエンジニアを増やせるといったシナジーが期待できること 決め手になっていることは「 型による恩恵と学習コストの低さ 」です。 これまでのLIFULL HOME'Sのバックエンドの言語はPHPとRubyであったこともあり、型付き言語の導入は開発効率向上に大きく貢献することが見込まれました。 また、Clean Architectureを採用している時点で一定の学習コストを計上しているため、JavaScriptのスーパーセットであるTypeScriptを採用することで学習コストを下げることは重要な観点でした。 LoopBackを採用した理由 LTSバージョンの期間、学習コスト、OpenAPIとの親和性、そしてClean Architectureとの親和性といった観点を考慮した上でLoopbackが選ばれました。特筆すべき点は以下です。 OpenAPIのドキュメントが容易にホスティングできる(swagger)など、OpenAPIのドキュメンテーションのための機構が整っていること アノテーションだけで(View)ModelからJSON Schemaへの変換が容易にできること DI(Dependency Injection)が備わっていること 2つ目に挙げたJSON Schemaへの変換を取り入れた場合、UI層のViewModelがフレームワークに依存することを許してしまうことになるので、厳密にはClean Architectureの規約違反になります。 ただ、アノテーションのみの軽微な依存であるため許容するという判断になりました。 Clean Architectureの実践 Clean Architectureは設計の原則を提供しているものの、抽象度が高くそのままでは実装の自由度は高いままです。 具体的な新BFFでのレイヤー分け(=ディレクトリ構成)と、レイヤー内・レイヤー間の実装規約について紹介します。 レイヤー分け:例の図と新BFFアーキテクチャのレイヤーとのマッピング The Clean Code Blog( https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html )より引用 こちらはRobert C.Martin氏が提唱したClean Architectureの図です。Clean Architectureを調べると一度は目にする有名な同心円ですね。 一方、以下が新BFFのアーキテクチャです。図中の色はClean Architectureの同心円の色と対応させてあります。 新BFFとClean Architectureのマッピング; 一部は独自規約を導入して最適化している おおむね同心円の通りに各レイヤーと依存の方向を定義しています。 大まかなディレクトリ構成は以下のようになっています。 . ├── adapters // Interface Adapters │ ├── gateways // 外部DB等、内外のデータ形式変換レイヤー │ │ ├── datasources // Cacheや, Backend API接続用 │ │ └── impl // Data Access Interfaceの実装 │ └── ui // Controller, View, Presenter ├── application // UseCase/Application Business Rules │ ├── repositories // Data Access Interface │ └── usecases // Controllerと一対一に対応するUseCase ├── domain // Entity. Value Object, Domain Serviceも含まれる └── framework // フレームワークを拡張したもの レイヤー内・レイヤー間:独自の規約を導入する レイヤー間のBoundaryはどう実装するのか、フレームワークとの結合はどのように表現するのかなどレイヤー内・レイヤー間での規約も独自に導入しています。 その規約の中からいくつかの特徴的なものを列挙すると、 RepositoryのInterface(Data Access Interface)をapplicationレイヤーに配置する 各レイヤーの境界を渡るデータ通信ではDto(Data Transfer Object)を利用する DtoはplainなTypeScriptのinterface UseCaseとControllerは原則一対一にする(アクターが混在する汎用的なUseCaseは避ける) これを実現するために、Controllerを細分化する ViewやControllerでOpenAPISpecification用の機構を利用し、フレームワークへの依存を一部許容している UseCaseではInputPortのみ実装するなど、冗長と思われるInput/OutputBoundaryは実装しない といった点が挙げられます。Clean Architectureに準拠し守るべき原則は守りつつ、実装コストを下げるためにも適宜設計を変更しています。 規約違反の検知を自動化する Clean Architectureの重要な規約の一つに、上位の方針が詳細に依存してはならない(=同心円の図における内側のレイヤーは外側レイヤーに依存してはならない)という規約があります。 この規約を守るようために紳士協定的にチェックリストを作成したり、人力のレビューで規約違反を防止のではなく、dependency-cruiserというライブラリを利用してCIに組み入れることで規約違反を自動で検知しています。 github.com コンポーネントレベルでの規約:物理的なリポジトリ分割 新BFFは単一のGitリポジトリから構成されるような巨大なコンポーネントではありません。 以下の図のように、単一リポジトリ内でnamespaceを物理的にGitリポジトリを分割しmicroservice的に分割統治することで、一度に開発する開発者を限定することで開発効率の向上を図っています。 それぞれのGitリポジトリで前項までに紹介したClean Architectureベースのアーキテクチャが採用されています。 Gitリポジトリ分割図; 開発組織ごとに分けている 組織構造に追従したリポジトリ分割 Gitリポジトリは、新BFFが取り扱うドメインの違いによって分割しています。ドメインには賃貸、流通、分譲などの マーケット固有 のものと、横断的な関心がありマーケットで分断することが難しい マーケット非固有 のものがあります。 LIFULLでは取り扱うドメイン=マーケットをベースにして開発組織が構成されています。 つまりマーケット=組織構造に基づきGitリポジトリ=コンポーネントを分割することは、書籍『Clean Architecture』で述べられているようなコンウェイの法則の体現でもありますね。 前項までに述べたような、一つのコンポーネント内でClean Architectureを実践することによりモジュールレベルでの開発効率の向上と健全性の確保を図ることに加え、Gitリポジトリを物理分割することでそれぞれの組織が独立して開発可能になるようにコンポーネントレベルでも開発効率の向上と健全性の確保を図っています。 Clean Architectureを実践した所感 約1年前からバックエンド刷新プロジェクトが発足し、筆者は昨年5月末にプロジェクトにジョイン、そして昨年の8月ごろから新BFFの実装・設計に携わってきました。 それから今日までに得られたClean Architecture的な知見を書いていきます。 開発効率の向上とコードベースの健全性の確保は達成できたか? これまでのモノリスと比較すると、設計、調査のためのコストは減少しており開発効率は向上していると思います。 これはClean Architectureを採用したからというより、PHPから型付き言語であるTypeScriptに移行したことにより、内部データ構造が明確になったこと、IDE(VSCode)を活用したリファクタリングがによる恩恵が大きいと感じています。 Clean Architectureを採用した影響についてですが、習熟度が低いうちは規約が複雑でレイヤーの責務がわかりにくく思えてしまいどのレイヤーにどの処理を書くべきか判断を誤ることもあり、かえって実装時間やレビュー時間の増加につながることもあります。 しかし、習熟度が高まれば解決可能な問題であるのでClean Architecture自体の性質に問題があるというよりは、それを継承している新BFFのアーキテクチャの啓蒙を進める必要があると考えています。 ただ単にモノリスからClean Architectureへの書き換えを行うだけでなく、実装可能なエンジニアを増やすことあるいはレビュー可能なエンジニアを育てることも当初の目的を達成するには必須と考えています。 BFFにClean Architectureの規約は複雑すぎないか? 前述した通り、少なくともClean Architectureを熟知したバックエンド刷新プロジェクトチームが制御できないような複雑さではないです。 設計・実装に悩んだ時はClean ArchitectureのルールとSOLID原則に立ち返って考えれば良いという根拠(=共通言語)が常にあるのは大きいと考えています。 レビューの根拠としての役割も大きいです。 とはいえ、現状の新BFFはクライアントからのクエリをバックエンドAPIに送信し、その結果にビジネスロジックを適用して返却するという参照系の処理が中心です。 そのため、単一のクライアントから単一のバックエンドAPIを呼び出すという処理を実現したい場合はPort、Adapter系をはじめとした抽象度の高い概念は、実現したい要件に対して実装の抽象度が高すぎるように思えてしまうなど、要件によっては規約が厳しいと思われるケースも存在します。 規約の遵守と開発効率の最適化 Clean Architectureを採用している以上、新BFFにおいてコードベースの健全性の確保のために規約を遵守すればするほど開発効率が落ち、開発効率を重視するほど健全性が落ちるというトレードオフと常に隣り合わせです。 冒頭で「共創」というアプローチをとっている、と述べた通り現在の数人のプロジェクトメンバーだけが新BFFの設計・実装を担うのではなく、LIFULL HOME'Sに関わる多くのエンジニアが新BFFの設計・実装を担う予定です。 将来的には累計で100人以上のエンジニアが開発に参加すると予想されるので、現状では冗長に思える実装があってもアーキテクチャを健全に保つ先行投資として規約の遵守を重視しています。 とはいえ、プロジェクト外のエンジニアの方から設計・実装面でのご相談・提案が発生していることもあり、規約の改善であったりアーキテクチャ自体を啓蒙し浸透させていく必要性も存在しています。 まとめると、 バックエンド刷新のプロジェクトメンバーだけが遵守・理解可能な複雑すぎるアーキテクチャ・規約になること あるいは、 実装の選択肢が多数考えられるような緩すぎるアーキテクチャ・規約になること これらの両極端な結果になることで、Clean Architectureの設計原則が守られないアーキテクチャになることは避けたいところです。 ドメインモデリングが不足していないか? Clean ArchitectureはDDDにおけるレイヤードアーキテクチャの実践パターンの一つであり、(Clean Architectureの)Entityを実装するにあたってはドメイン知識が整理されていることが必要となります。 しかしLIFULL HOME'Sのドメイン知識は整理されているとは言いづらく、ドメイン知識がドキュメントや実装に散在しているという状態です。 そのため、数値系のValue Objectを実装するにあたって、取りうる値の範囲を調べるためにDB仕様書や別のコンポーネントの実装を見なければならないというような事態が往々にして起こります。 そうした事態を防ぐためにもアーキテクチャのパターンとしてClean Architectureを採用する(いわゆる軽量DDDに陥る)だけでなく、DDDにおける戦略的設計を通じてドメインモデルを定義し集約し正しくDDDを実践していくことが重要だと認識しています。 現在は、DDDの思想の通りに改めてユビキタス言語を策定し実装各所に散らばったドメイン知識を集約・充実化するの取り組みが進行中です。 Clean Architectureを採用したのは正しいかった? バックエンド刷新プロジェクトが発足してから1年が経過し、本番で稼働している新BFFも増えてきており新BFFのアーキテクチャも徐々に成熟してきました。 Clean Architectureを採用したのは正しいかった?という問いがあるとすれば、 開発者が増えた数年後に答えがわかる という回答になると考えています。 バックエンド刷新プロジェクトのメンバーのアーキテクチャへの習熟度は高いですが、将来プロジェクト外のエンジニアが実装するようになった時にこそ目的が達成できたかわかるるためですね。 その時に正しかったと言えるように現在鋭意開発を行っています。 今後導入したいこと これまでに新BFFへと移植・リリースしてきたビジネスロジックはすべて参照系の処理でした。DBへのWrite処理が発生するような更新系処理の実装はありません。 そもそもLIFULL HOME'Sのほとんどの処理が参照系の処理であるためです。 単にソフトウェアエンジニアとしての興味もありますが、更新系の処理DDDにおける集約やトランザクションなどの観点でのプラクティスも確立していきたいところです。 例えば、現状はApplication層のみにあるData Access Interface(Repository)に対し、CQRS取り入れて参照系Data Access Interface(Query)と更新系Data Access Interface(Command)を作成することでDomainを洗練させていくといったアプローチがあるかもしれません。 実装効率を向上させるために Clean Architectureの特性およびGitリポジトリを分割したことが起因して、新BFF全体で見ると冗長な実装が増えてしまっている箇所もあります。 例えば 大量のData Transfer Objectを作成する必要がある Dependency Injectionなどの定型実装が頻発する 同じようなValue Objectを複数Gitリポジトリ作成する必要がある などが挙げられます。 前者2つはScaffolding Toolの作成・導入で解決できると想定しており、最後の1つはPackage(Github Packages)化することで解決できると想定しています。 しかし、どちらの解決策もある程度実装上のプラクティスが確立されることを前提としています。 Clean Architecture自体が抽象度の高いものでありそれゆえに実装の選択肢が多く、新BFFでの実装プラクティスも完全には確立できていません。 プロジェクト外のエンジニアの方々と円滑に共創していくためにも実装効率を向上させる取り組みは継続的に行っていきたいところです。 おわりに:銀の弾丸はない 開発効率の向上と健全性の確保を目指したバックエンド刷新プロジェクトはまだまだ進行中です。 Clean Architectureのわかりやすい解説や実装例を紹介した記事などの情報は存在しますが、実在するサービスで採用した事例や開発者の経験についてはあまり存在せず、投稿すれば有益な情報になるのではと思いこの記事を書かせていただきました。 銀の弾丸はない 、という言葉はアーキテクチャ選定にも当てはまると思います。そのため、この記事をそのまま流用できるようなケースはあまり存在しないと思います。 今回紹介させていただいた中から転用可能なエッセンスを抽出して、技術的負債の解消や何年も続くことを見越した新規サービスの技術選定の際に役立てていただけると幸いです。
はじめまして テクノロジー本部 基盤運用ユニット 基盤グループの久保田です。 より良いサービスを提供していくために必要なことは色々あり、また答えがあるものではないと思っていますが どういったアプローチを行うにせよ、それを検討していくためにはまずは 「自分たちが置かれている状況を把握すること」 が必要と考えています。 そこで以前、自社サービスであるLIFULL HOME'Sを検証のためサイト運営で利用しているツール以外で計測し可視化したときの話をしようと思います。 なにを使って計測するか Googleが提供しているLighthosueを使って計測することにしました。 理由としては SpeedIndex、SEO、Accessibilityが計測できる。 お金が掛からなければ良かった。 各メトリクスは内容やツールなど色々ご意見があると思いますが 今回は一定の基準で比較検討すること 複数のツールを使わなくても良いことからLighthouseを使うことにしました。 SpeedIndex:ページ内のコンテンツが視覚的に認識できるようになるまでの時間 SEO:Search Engine Optimization(検索エンジン最適化)の略称で、このスコアが高いとGoogleなどの検索エンジンでキーワードが検索された際、上位に表示されやすくなる。 Accssibility:誰でも使用することが出来るかという点をスコアとして表したもの なにを使って可視化するか DatadogにLighthouseで計測したメトリクスを収集し可視化することにしました。 理由としては 使ってみたかった 当時、社内でDatadogを使っていこうという流れがあった 技術的な理由などは特になかったです。 自分の必要と考えていたことは 「自分たちが置かれている状況を把握すること」 なのでこだわりはありませんでした。 なにを計測するか 自社サービスであるLIFULL HOME'S ついでにトップページや物件一覧ページなどをカテゴライズして今回の計測用のサイトマップを作成しました。 どう可視化されたのか このような感じでメトリクスごとに時系列でページ別に比較することが出来るようになりました。 カテゴライズした時の分類をメトリクス送信時に付与しダッシュボードで絞り込めることも出来ます。 HOME'S Quality Metrics Board グラフ内の赤帯について LIFULL HOME'Sに対しリリースが行われたタイミングをGithubから取得しグラフに表示するようにしています。 これでリリースによりLIFULL HOME'Sに対して変化が起きた際、気付くことが出来るようにしました。 可視化して得られたもの 自分たちのサービスがどの様な位置にいるのか確認することが出来た。 PDCAを回していくための道具を手に入れることが出来た。
こんにちは。Ltech運営チームの井上です。 今回は、2021年3月2日(火)に開催した『Ltech#14 「LIFULL HOME'S」のフロントエンドについて語り尽くします!』についてレポートします。 事前に共有させていただいていたウェビナーのURLに誤りがあり入室できないというトラブルもありましたが、参加者の方の温かいフォローもあり、最終的には120名を超える方にご参加いただき会は大盛況で閉会することができました。ご参加いただいた皆様本当にありがとうございました! lifull.connpass.com Ltechとは Ltech(エルテック)とは、LIFULLがお送りする、技術欲をFULLにするイベントです。特定の技術に偏らず、様々な技術の話を展開しています。 「LIFULL HOME'S」のフロントエンドについて語り尽くしました 今回の Ltech のテーマはLIFULL HOME'Sのフロントエンドについてです! 日本最大級の不動産・住宅情報サイト「LIFULL HOME'S(ライフル ホームズ)」の大部分は約10年前に開発を開始したアプリケーション上で構成されています。10年前から現在まで、周知の通り フロントエンド技術の進歩の勢いは速く、当初は素晴らしかった設計や技術スタックも今の技術情勢に照らし合わせるとレガシー化している現状がありました 。 そこで今回登壇したメンバーを中心に、開発を担当するフロントエンドエンジニアが、 数々の技術負債解消や、フロントエンドアーキテクチャの刷新、アクセシビリティ改善などの課題に対して、「いかに速く」「ユーザーに最高のユーザー体験をもたらすにはどうしたら良いか」という観点から行なった(そして、現在も行なっている)取り組みについて発表しました 。 新しい検索体験とデザインシステム 新しい検索体験とデザインシステム from LIFULL Co., Ltd. www.slideshare.net 最初は、 LIFULL HOME'S の新しい検索体験を提供するサービスの開発で採用したデザインシステムの話です 。 LIFULL HOME'S では昨年末にリリースした「 叶えたい条件から探す 」機能があります。 この新機能の開発にあたって、従来の巨大なアプリケーション基盤上に追加で開発するのではなく、Nuxt.js (TypeScript)で新規のアプリケーションを構築しました。この新サービスを開発する上で新規のデザインシステムを設計しています。 デザインシステムは非常にポピュラーである Atomic Design をベースに、デザイン仕様に合わせて少しカスタムした設計になっています。 基本的な Atomic Design のコンポーネント分類 カスタムした Atomic Design のコンポーネント分類 template は排除し、代わりに routes という分類を用意しています。 routes はページ依存の organisms であり、ビジネスロジック的制約が強く汎用化が難しいと判断したものがこの routes コンポーネントとして実装されています。この分類をしたことで、依存関係やデグレを意識せずに安心して開発できるようになりました。 また Atomic Design を採用したことのメリットは、 Storybook でのコンポーネントカタログの運用やコンポーネントの unit test の書きやすさがあることです 。初回実装だけではなく、追加改修時にコンポーネントの流用やテストを書くことでデグレの検知ができるため、これらのメリットをより実感しているとのことでした。 改善したいところとしては、 atoms / molecules / organisms の粒度の線引きが難しく、 molecules を小さく設計し過ぎたところ molecules / organisms を改修するときの利用先ごとの若干のデザインの差異の吸収 とのことでした。 発表者の海老澤はこの「叶えたい条件から探す」機能でのコンポーネント設計以外にも、 LIFULL HOME'Sの大部分を構成するアプリケーションの開発効率向上のために、Sass の Mixin や共通変数を制定したり、スタイルガイドを開発環境に立ち上げたりといった活動もしています 。過去に海老澤がこの件について執筆したブログ記事もありますのでぜひご覧ください。 www.lifull.blog LIFULL HOME'S におけるフロントエンド開発環境の刷新 LIFULL HOME'S における フロントエンド開発環境の刷新 from LIFULL Co., Ltd. www.slideshare.net 次は、冒頭に紹介した 約10年の歴史をもつメインのアプリケーション開発環境の刷新について の相馬からの発表です。 LIFULL HOME'SのほとんどはPHP(Symfony、Twig)の構成のアプリケーションで開発しています。 刷新前まではCSSとJSの bundle / minify はランタイムにPHPで実行しており、初回リクエスト時にはレスポンスの大幅遅延が避けられない致命的な問題を抱えていました 。 この問題をBabel、Rollupなどで事前のビルドプロセスを構築することで解決しました。これらについては相馬が執筆したブログ記事がありますので合わせてぜひご覧ください。 www.lifull.blog www.lifull.blog 刷新後の開発環境では、開発者がモダンな JavaScript でコードを書くことができるようになり、サポートブラウザに準じた Vendor Prefix が自動付与されるようになり、そして初回リクエストのランタイムでの bundle/minify 処理が無くなったことでユーザー体験の向上も図ることができました。 しかし、Rollup を導入したことで新たに見えてきた課題もありました。アプリケーションが巨大で、bundle 対象のファイルが多すぎる為、開発時の warmup に時間がかかりすぎてしまう問題です。(開発モードでビルドすると完了までに5分以上かかってしまう...) これについては ESBuild を使ったランタイムでの高速ビルドをするという方法で、現在改善を試みている最中ですので、詳細についてはリリース後に相馬が執筆する記事をお待ちください 。 ウェブアクセシビリティ推進活動はじめました ウェブアクセシビリティ推進活動はじめました from LIFULL Co., Ltd. www.slideshare.net LIFULL HOME'S だけに限らず、LIFULL におけるアクセシビリティ推進活動の旗振りをしている嶌田からの発表です。 サービスを開発していく中でビジネスやデザインの都合や開発者の知識不足などを理由に、アクセシビリティが十分ではない状態でリリースをしてしまうことが少なくありませんでした 。この由々しき現状変えるために数々の取り組みを行なっています。 まずは、 現状の社内のアクセシビリティへの取り組み状況の把握でした 。社内のナレッジベースを検索し、アクセシビリティに過去に関わっていた社員を調査し、ランチに誘って話を聞く+推進活動を行なうチームに誘うということを行いました。 次に、 推進活動を行なうチームを結成しました 。目標を別にするチームを2つ結成しました。 アクセシビリティの全社的な普及を目標にするウェブアクセシビリティ推進ワーキンググループ リリースフローの中に組み込むアクセシビリティのチェックリストの作成 アクセシビリティ観点でレビューし、該当サービス開発担当者に改善提案をする社内サービスを開始 主体的に普及活動までではないが、アクセシビリティについてゆるくキャッチアップしておきたいくらいの社員でも参加できるアクセシビリティ研究会 スクリーンリーダーの使い方ハンズオン開催 他社のアクセシビリティ・ガイドラインの輪読会 このように目標と活動内容が異なる2つのチームを用意したことで、推進活動に参加する心理的障壁を下げることにも成功しました。 これからの取り組みとしては、 アクセシビリティ・ガイドラインの整備と運用 アクセシビリティ専門職を創設 新卒研修などでアクセシビリティについて学ぶ時間をつくる など、数々の打ち手を並行して進めています。これらについても皆さんに後日ご報告できることがあると思います。 最後に、アクセシビリティ推進活動を通じて大切だと感じたことについても言及がありました。 書籍「FEARLESS CHANGE アイデアを組織に広めるための48のパターン」にアクセシビリティ推進活動が順調に進んでいる理由があった 情熱を持ち、絶やさない 社内に顔が利く人とつながる ひとりではなく、仲間を集める これらのことは、アクセシビリティ推進活動に限らず、新しい文化を組織に根付かせるためには必要なことですね。 LIFULL は「あらゆるLIFEを、FULLに。」というコーポレートメッセージを掲げています。あらゆる人々にアクセシブルな LIFULL HOME'S を目指してこれからも改善活動を続けていきます! 大きめレガシープロジェクトのフロント行く末 大きめレガシープロジェクトのフロント行く末 from LIFULL Co., Ltd. www.slideshare.net 最後は、 LIFULL HOME'S のフロントエンドの現状の課題と未来を見据えた技術選定について 中島からの発表でした。 HTML と JS の概念的距離の圧縮を主軸に、React / Vue のような Virtual DOM を取り扱うフレームワークにリプレイスしていくのではなく、Stimulus を採用した設計にシフトしていく構想 について語りました。 当日の発表資料に加えて、弊社クリエイターズブログにて関連記事を執筆していますので合わせてご覧ください。LIFULL HOME'S のフロントエンドの歩んでいく方向が見える記事になっています。 www.lifull.blog どんなに素晴らしい設計もイケてる技術も時間が経てば過去のものになってしまいます。より少ないコードでより多くの素晴らしい体験を届けられるエンジニアリングをしていきたいと強く決意させられる発表でした。 最後に 今回のLtech#14では、LIFULL HOME'Sを支えるフロントエンドエンジニアの取り組みについてフォーカスを当てました。 Ltechでは、LIFULLエンジニアが中心となって皆様の技術欲を満たすよう実例を交えた勉強会を開催しています。今後も Ltech を積極的に開催していきますので、ぜひ気になった方は、connpass で LIFULL のメンバー登録をよろしくお願いします! lifull.connpass.com
LIFULLの中島です。 近頃、LIFULL HOME'Sのフロントエンド(ここではJavaScriptのみを焦点とします)もようやく進む道を見出し、そろそろ設計方針を一新しようと試みています。 今回はそれについて話したいと思います。 現在の私たちの課題感 私たちの管理する多くのレガシーコードはDOM操作ライブラリとしてjQueryを、UI設計の格子としてBackbone.Viewのような設計方式を導入しています。 (もちろんそうでないマイクロサービスも多くありますが) 具体的なコード例を示すことこんな感じになります let Slider = Backbone.View( { events: { '.next click' : 'next' , '.prev click' : 'prev' } , next() { this .$(...).css( { left: '111px' } ); } , ... } ); let photoSlider = new Slider( { el: '#photo_slider1' } ); View間の連携を取りたい時はBackbone.Eventsをglobalに放出するpubsub実装パターン( like USA today )のようなものを用意し、コミュニケーションをとるように実装しています。 ファイル分割の単位が明確化され、またUIの振る舞いが統一的に規格化(@events)され、コードの追い易さは野良コードに比べると随分マシな状態になりました。 しかしながら、10年も運用していると(実際のところもっと早くから苦しんでいるが)、これらのコードに存在する、いくつかの腐りうる隙が目につくようになります。 DOM探索の害悪 数年コードを運用してわかることはDOM探索という行為は運用上、基本的にはコードを汚くする主要因であるということです。 セレクタでの要素探索は壊れやすく、探索した要素はNodeListやHTMLCollectionといった紛らわしい要素となり、それらのnormalizeに我々はまたコードを一つ書かなくてはなりません。 またせっかくView単位でファイル分割しても親ViewはDOM探索によって簡単に子Viewの要素にアクセスできてしまい(その逆もしかり)、Viewの境界線が曖昧になってしまいます。 その結果我々のコードは子Viewの責務を兼ねた再利用のきかない大きな親Viewが多く誕生し、その再利用性の低さから、「非常によく似た、しかし少し違う」コードが増え、無駄にプロジェクトを肥大化させることになりました。 これはbundlerやtranspilerのビルド時間を無駄に長引かせ、結果として開発効率を大きく落とす結果となります。 動的に追加されるコンテンツに対する振る舞いのアタッチ 動的(XHR等による)に追加されるコンテンツに振る舞いをアタッチする際に、そのDOMをelとしてViewをインスタンス化せねばなりません。 これはViewのインスタンス化を一元管理することが困難になることを意味します。 コードの統一性や、そのインスタンスがどのように扱われるかに注意を払わねばいけなくなるのはリードコストを増大させ、これまた開発効率を落とすことにつながりました。 グローバルイベント(pubsub)に依存した実装 グローバルイベントの採用は一定の成功を収めましたが、Viewの唯一のコミュニケーション手段としてしまったのは失敗でした。 左右間のViewの連携においては、グローバルイベントを用いたコミュニケーションは効果的ですが、親子間のコミュニケーションにはしばしば課題を伴います。 A1- |-B1 |-B2 |-B3 A2- |-B4 |-B5 |-B6 B2が自身の親のA1にだけ情報を伝えたい時、グローバルイベントをなげてしまっては、A2を除きA1だけが呼応するという実装を伴う必要がでてくるからです。 素直にCustomEventを投げ、バブルアップさせるべきでした。 結果としてこれもコード量を無意味に増やすことにつながりました。 見えてきた次の設計に必要な観点 これまでの反省を踏まえると次の設計では以下の点にこだわる必要があります。 DOM"探索"の排除 DOMの振る舞いの自動アタッチ (Bubble up eventで)親子間でコミュニケーションがとれる 3つ目は普通のことであるとして、前者の二つを兼ね備えるものはあるのでしょうか かのDHHはこの観点を「HTMLとJavaScriptの概念的距離」と表現しており、圧縮すべきだと主張しています。 HTMLとJavaScriptが離れたところにあるがゆえに探索は必要であり、探索した要素にイベントを自主的に割り当てる必要があると言えます。 もしHTMLとJavaScriptの境界がもっとぼやけていて、JavaScriptからDOMに変数やプロパティへのアクセスのようにアクセスでき、HTMLからJavaScriptの振る舞いを呼び出せればこの辺の複雑性はなくなると言えます。 モダンライブラリにおける「HTMLとJavaScriptの概念的距離」 あまりこういう言い方で流行りのライブラリを表現することはありませんが、かなりのシェアを集めているReact/Vueもこの概念的距離の圧縮によって成功を収めているライブラリに見えます。 new Vue( { el: '#app' , template: ` <button type= "button" @click= "notify" >click me</button> `, methods: { notify() { alert ( 'click button!' ); } } } ) このコードはDOM(button)に振る舞いを与えるものですがDOM探索は行われていません。 VueやReactはJavaScript側でHTMLを生成することで探索という工程を排することに成功しています。 もちろん他にもテンプレート側からみて振る舞いが宣言的であったり、データバインディング機構があったりと魅力的な点は多くありますが、私の観点ではここがもっとも重要に思います。 これらのモダンライブラリを採用するのか? 答えはNoです。 もちろん、新規でマイクロサービスを作ったり、もつべき状態がすこぶる多いのであれば採用を考えたかもしれません。(事実そういうマイクロサービスもあります) しかしながらLIFULL HOME'S本体のサイトはいくつか様子が違います。 多少の検索UIが状態を持つとはいえ、基本的には物件情報を取り扱うドキュメントサイトです。 そこでは振る舞いよりも文章の重要度が高く、且つ、これまで積み上げてきたSEO地位に対してのリスクは非常にシビアに評価する必要があります。 これらのモダンライブラリはJavaScript側からHTMLを生成することにより概念的距離を縮めたが、それゆえにHTMLの生成がJavaScriptによって"後から"生成されることとなり、クローラビリティやプログレッシブエンハンスメントの観点においていくつかの懸念を残します。 SSRも元々そこに存在しなかった問題に対する対処であり、害虫を狩るために猛獣を飼いならす必要がある状況のように感じます。 設定やビルドといった新しい複雑性を極力伴わず、HTMLはそこにあり、その上でHTMLとJavaScriptの概念的距離を圧縮するアプローチこそが我々の望んでいるものなのです。 採用した概念圧縮の方法 我々はBasecamp製の Stimulus に命を預けることにしました。 (もしかすると1年後にはそれとturboを組み合わせたhotwireに命を預けると言ってるかもしれません) Stimulusはなんなのか これはRails7にデフォルトで導入されるHotwireに組み込まれているライブラリなのでそのうち大きく広まるかもしれません。 React/Vue同様にHTMLとJavaScriptの概念的距離の圧縮に成功したライブラリと言えますが、大きく違う点はそれ自身がHTMLを生成しないところにあります。 MutationObserver でDOMの変更を監視し、変更されたDOMに振る舞いが必要であることがわかれば自動的に必要な振る舞いをアタッチするように動きます。 対象となるDOMにどのような振る舞いが必要か、その要素内のどの要素に参照が必要か、それをDOM自身に記述することでアタッチやDOMの参照を自動化するのです。 しかもビルドレスでなんならCDNをimportするだけで動きます。 テンプレートレイヤを侵すことはないため、既存のコードを式年遷宮する必要もありません。 具体的にコードを書きましょう。 ` <div data-controller= "counter" data-counter-num-value= "0" > <p data-counter-target= "view" >0</p> <button type= "button" data-action= "click->counter#increment" >+1</button> <button type= "button" data-action= "click->counter#decrement" >-1</button> </div> ` import { Application, Controller } from 'https://cdn.skypack.dev/stimulus' ; let app = Application.start(); // MutationObserverでDOM全体の監視を始める app.register( 'counter' , class extends Controller { static targets = [ 'view' ] ; static values = { num: Number } ; increment() { this .numValue++; } decrement() { this .numValue--; } numValueChanged() { this .viewTarget.textContent = this .numValue; } } ) codepen HTMLに注目してみましょう。 Stimulusはいくつかのdata属性を利用して動きます。 data-controllerが属性が付与された要素がmutation observerに引っかかれば、即時にその名前でregisterされたcontrollerをその要素に対して適応します。 data-action属性が付与された対象の要素で発生するイベントに対し、値部分に書かれた振る舞いが自動でアタッチされます。 さらにdata-[controller]-target属性が付与された要素がJavaScript側からthis.[controller]Targetとしてアクセスすることができるようになっています。(これは実際にはstimulusによってstatic targetsを元に自動で作られるgetter関数です) (残るdata-[controller]-xxx-value="{value}"はstimulus2で実装された、データ変更コールバックを伴う状態管理機能です) これらの機構によりDOM参照はプロパティアクセスで実現され、振る舞いのアタッチは自動でされる世界線が実現することになります。 HTMLに振る舞いと状態を記述しておけば勝手に振る舞いがアタッチされるので、XHR等で動的に追加されるHTMLも、ただ挿入するだけでよくなります。 我々は常にサーバからはHTMLを返せばいいのです。 それはとてもシンプルに感じます、 HTMLの組み立てロジックをサーバサイドに集約できるのはレガシーシステム観点で考えるととても痛みのない方法です。 もしSPAを実現するとなった時、Turbolinksはもう一度息を吹き返すかもしれません。 おそらくBasecampはそういう意図でTurbolinksに投資を続け、この度 turbo をリリースしたのでしょう 必然的にクライアントサイドで大きなデータ操作をするシーンは減ることになり、型やスキーマの必然性が下がることになります。 (これはもしかすると将来ビルドレスを推し進めた先のtranspilerと決別するシーンで役に立つかもしれません) さらにStimulusは興味深いことにコントローラを一つの要素に複数つけることを許容し、各コントローラを単一責任にせよと示すのです。 よくある機能を単一責任なcontrollerとして切り出す時の例をあげていきましょう disclosure disclosure(パカパカ)の機能 適切なaria-expand付与等 removal 要素削除機能 modal dialog roleやlabel系ariaの設定等 content-loader contentのxhrロード機能 combobox サジェストの機能 候補の表示と適切なrole,labelの設定など xhr-form form条件を元にxhrしコンテンツを部分リフレッシュする etc... 弊社のようなドキュメントメインのサイトだと、この辺が用意されていて再利用性が高いコントローラとして設計されていればわざわざページごとのロジックを精査する必要もないのかもしれません。 ただパズルのようにHTMLにcontrollerやactionを付与していけばそれだけでサイトの振る舞いが完成するのは私たちの次の理想です。 我々はStimulusを導入し、プリミティブなコントローラを揃え、コード量を1/20にすることを次の目標にしていきたいと思っています。
LIFULLでのアジャイル開発について LIFULLのプロダクトエンジニアリング部の野澤です。エンジニアリングマネージャーをやっています。LIFULLには2017年に中途入社しましたが、以前からアジャイル開発に興味があり、昨年スクラムマスターの資格を取得しました。LIFULLでもアジャイル開発がだいぶ普及してきていますが、本日はそんなLIFULLでのアジャイル開発について書きたいと思います。 LIFULL HOME'Sでのアジャイル開発 私自身、社内でのアジャイル開発の普及活動をしているのですが、その活動の一環として昨年の8月にLIFULL HOME'Sの開発に携わる部署に社内アンケートを実施してみました。 それによると、 LIFULL HOME'Sの開発に関わるエンジニア・デザイナー・サービス企画のスタッフのうち 7割がアジャイル経験者 半分のチームでアジャイル開発手法が採用されている アジャイル開発を採用した理由として、「生産性が上がるから」と答えた人は約7割。「チームの結束力やモチベーションが向上するから」と答えた人は6割 ということが分かりました。LIFULL HOME'S事業においてはアジャイル開発手法はかなりスタンダードになっていることが分かります。 アジャイル経験者である「1回以上アジャイル開発のPJに従事したことがある」、「1年以上アジャイル開発の経験がある」、「3年以上アジャイル開発の経験がある」を合計すると約7割になる 約半分のチームがアジャイルを採用しています さらに細かく見ていくと以下のようなことも分かりました。 ウォーターフォールを採用しているチームも含めて 全チームの8割で朝会や振り返り会が実施されている アジャイル開発が主体のチームでもガントチャートも併用しているケースがある ウォーターフォールを採用しているチームでもアジャイルのプラクティスを採用しているケースがある このようなことからも、開発手法はあくまで手段であり、目的やプロジェクトの特性に応じて開発手法を柔軟に組み合わせて使っているのが特徴と言えそうです。 教え合う文化 LIFULLでは 「利他主義」 を社是としており、お互いを助け合うことで、自分だけでなく周囲の人たちみんながHappyになっていくことを大事にする考え方が深く浸透しています。 それを体現している一つの取り組みが「LIFULL大学」です。LIFULL大学は個人のスキルアップ・キャリアアップのために、誰でもある分野の専門家として講義を開くことができ、社員の誰もが自由に参加できるしくみです。LIFULL大学で開講される講義は「ゼミ」と呼ばれ、ゼミには一定の教育研修予算が割り当てられています(2021年2月現在)。 私も長年アジャイル開発に取り組み、スクラムマスターの資格も取ったということで、「アジャイルゼミ」を開講しました。約4日間に渡ってアジャイル開発についての講義やワークショップ、社内メンバーによるパネルディスカッションを行いました。参加者は延べ154名で、参加者の9割の方に満足していただけました。 以前にもこうした勉強会は各所で実施されていて、従業員が自由に勉強会を開催・参加できるようなカルチャーがLIFULLにはあります。 「バッチサイズが大きいと何がいけないのか」など、アジャイル開発の基本的な概念についてワークショップも交えながら考えてもらいました サークル活動 また、LIFULLでは今年からサークル制度が導入されました。コロナ禍によってface to faceでのコミュニケーション機会が減っていくなか、今まで以上に社員どうしの交流を深めるのが目的で、やはり一定の予算が割り当てられています。スポーツや趣味のサークルもあれば、仕事に役立つようなことをテーマにしているサークルもあり、今では約70ものサークルが存在しています。 以前からLIFULLにはアジャイル開発に関わるコミュニティがありましたが、これを機にサークルになりました。私も参加させてもらっているのですが、月に一回、オンライン飲み会を開催して、LIFULLのいろんな部署のメンバーが集まってそれぞれのチームの悩みや成功事例を共有しています。またスクラムやアジャイルに関連するイベントがあったら参加者から情報を共有してもらったり、アジャイルに関する本が出るとその本について議論したりしています。 このようにLIFULLでは部署間の垣根が低く、業務以外で他部署の社員と交流する機会が頻繁にあることがLIFULLの魅力の一つかもしれません。 今後とまとめ このようにLIFULL HOME'Sでは時代や目的に合わせて開発手法を柔軟に取り入れて開発を進めています。最近ではウェブ業界でも「プロダクトマネジメント」が注目されていますが、社内でもプロダクトマネジメントについて議論する機会が増えてきました(詳細は弊社の花多山の 記事 をご覧ください)。 また大規模スクラムに挑戦しようとしている部署があったり、社内の開発プロセスのノウハウを共有する自主的な活動があったり、 開発生産性や技術的負債を可視化し、改善していくプロジェクト があったりと、各所で貪欲に業務改善が行われています。 昨年、 スクラムガイドがアップデート され、アジャイル開発宣言も 20周年 を迎えました。 アジャイル開発はまだまだ発展していくと思います。LIFULLでもより良いプロダクト開発をして、より多くの人々が心からの安心と喜びを得られるようにするためにも、自分たちなりに開発プロセスを改善させていければと思います。 アジャイル開発に挑戦したいと感じた方、ぜひLIFULLで一緒に働いてみませんか? hrmos.co hrmos.co
どうも エンジニアの「市場価値」を向上する をキーワードに活動している @サム です。今回は LIFULL HOME'S におけるLINEを活用した施策「 LINEで新着物件通知を受け取る 」を紹介したいと思います。 なぜやるのか 不動産は年末から3月末にかけて住み替えシーズンのため、毎日のように新しい物件が LIFULL HOME'S に公開され、選べる物件の数も増えています。 この時期は住まいを探す人も増え、この記事を読んでくれているあなたも同じ経験があったのではないでしょうか。 物件を探す方法はいくつもありますが、基本はエンドユーザが自ら LIFULL HOME'S などの検索サービスを利用する、いわゆる「能動的」なものになります。 住まいに希望する条件は変わらなくても、検索しないと新しい物件に関する情報は手に入りません。 そこで LIFULL HOME'S では新着物件をお届けする「 新着物件お知らせメール 」という機能があります。しかしこの機能を使うにはメールアドレスの登録が必要になるため、Webサイトでの登録が必要だったりといくつかの手順をおこなう必要があります。 とても便利な機能ですが、利用するまでに必要な煩わしさやメールアドレスを登録しなければならない敷居の高さがネックとなっております。 そこで LINEを活用することで次の利点があります 。 簡単に登録できる 使い慣れたLINEを利用できる スマートフォンに最適化されたデザイン LINEで新着物件通知を受け取るとは その名前のとおり、 毎日決まった時間に希望に沿った物件をLINEでお知らせしてくれる機能 になります。 LIFULL HOME'SのWebサイトを使って物件を探した際に、希望に沿った物件がその日に見つからなかったとき、次の考えに繋がることが多いと思います。 諦める 希望の条件を緩めて改めて検索する せっかく理想とする暮らしに沿った検索条件なのに、その日に 諦めてしまったり条件を緩和すると満足度は下がって しまいます。 しかしいつ理想とする物件が見つかるか分からないのに探し続けるのはそれなりの労力がかかります。 そこで本機能である「LINEで新着物件通知を受け取る」を使うことで、あなたの 希望する条件にマッチする物件が見つかれば「自動的にLINEに通知してくれる」 大変便利な機能になっております。 登録方法 1. 物件一覧ページの「LINEで受取るボタン」をタップ! 2. LINEで「LIFULL HOME'S」のアカウントを友だち追加! 3. トーク画面に通知が届いたら登録完了! どのような仕組みになっているのか この機能を実現するためにいくつかのアプリケーションを横断しています。 この機能の中心にあるのが「 EOS ( Elastic Omni-channel Service )」と呼んでいるオムニチャネル用のAPIアプリケーションです。 EOSはオムニチャネル戦略を実現するために作られたアプリケーション で、今回はLINEの機能にフォーカスしていますが、いずれはメールやSMS、CRMツールとの連携など、様々なサービスに成長していくものです。 LINEで新着物件通知を受け取るは、エンドユーザのお気に入りの検索条件を圧縮文字列にすることで、複雑になりがちな検索条件を共通で使えるように設計されました。 この設計にすることで、ログインが不要になり住み替えシーズンに間に合うようサービス提供するまでのコストも削減できました。 最後に 今後も LIFULL HOME'S はLINEを活用し、エンドユーザにより便利な機能をお届けしていきます。 もちろんオムニチャネル戦略としてLINEだけではなくSMSやメールなど様々なチャネルを利用し、エンドユーザ1人1人に沿ったサービスを開発していきます。 サービスを開発することでエンドユーザが理想の住まいに出会えるよう手助けできればと思います。 告知 LIFULL では Ltech という LIFULLエンジニアが中心となってエンジニアの技術欲を満たすような実例を交えた勉強会 を開催しています。 コロナ禍でもZOOMを使ったオンラインで開催するなど、今後もLtechを積極的に開催していきますのでぜひ気になった方は、connpassでメンバー登録をよろしくお願いします! lifull.connpass.com twitter.com
プロダクトエンジニアリング部の佐藤です。 今回はLIFULLの開発において実際に使われている技術スタックの一例としてLIFULL HOME’S 引越し手続きを紹介いたします。 LIFULL HOME'S 引越し手続きとは Nuxt.js TypeScript Context Nuxt Community 認証 Nuxt 3に向けて まとめ LIFULL HOME'S 引越し手続きとは 住み替えの際、各事業者(電気・ガス・水道)の住所変更手続きを一括で申請できるサービスです。 主なシステム構成はこちらです。 Nuxt.js GAE(Google App Engine) Firebase 今回はNuxt.jsについてどのように活用しているか見ていきます。 Nuxt.js LIFULLでは新規でのフロントエンドの開発においてNuxt.js(Vue)での開発事例が増えてきています。 serverMiddlwareプロパティにおいて各APIのBFFとしてexpressを使うこともあります。 nuxtjs.org serverMiddleware プロパティ - NuxtJS TypeScript TypeScriptを採用しています。 yarn dev での開発時に素早くフィードバックを受けられて便利です。 www.typescriptlang.org Vue 3以前のプロジェクトではクラススタイルでNuxt Property Decoratorを使い、TypeScriptでVueファイルやVuexを記述しています。 https://github.com/nuxt-community/nuxt-property-decorator Context Nuxt.jsのContextではこちらの図を参照することが多いです。 ja.nuxtjs.org Contextからstoreやredirectなどの便利なメソッドやパラメータを利用できます。 コンテキスト - NuxtJS Nuxt Community Nuxt Communityのpackageを積極的に使い、エコシステムの恩恵を受けています。 github.com 主に以下のpackageを採用しています。GTMやサイトマップなどの車輪の再発明をなくし、機能の作り込みに集中できると実感しています。 @nuxtjs/device @nuxtjs/gtm @nuxtjs/sitemap @nuxtjs/pwa 最新のNuxt.jsを使い始めれば、@nuxt/componentsや@nuxtjs/dotenvなども取り込まれており、Nuxt.jsのDX(Developer Experience)が良くなり続けていることを実感できます。 認証 認証周りでは以下のようなnpm packageを活用しています。 express-session openid-client passport 関連してOAuth 2.0やOpenID Connectについて知る機会もあります。 https://tools.ietf.org/html/rfc6749 https://openid.net/connect/ Cookieの管理ではSameSite属性を意識しています。 HTTP Cookie の使用 - HTTP | MDN Nuxt 3に向けて これからの開発では @nuxtjs/composition-apiを使用してvue 3のcomposition-apiでの開発を進めています。 github.com Composition APIのドキュメントを参照しながら、新しい記法にも慣れていきたいですね。 Composition API | Vue.js まとめ 今回は実際にWebサービスを開発していて、どんな技術を意識しているのか見てきました。 LIFULLのWebエンジニアは日々技術のキャッチアップを行い、UXやDXの高いアプリケーションを開発することで、エンドユーザーや開発者などすべてのステークホルダーに取って良いWebアプリケーションの構築を進めています。 カジュアル面談もやっていますので、プロダクトエンジニアリング部のビジョンである「 強い個人・最高のチームになることで、価値創造を加速させ続ける 」や、LIFULLが目指している「 あらゆるLIFEを、FULLに。 」に興味がある方は是非お話しましょう! hrmos.co
輪読会のテーマと題材 なぜ輪読会か 学習効率を高める工夫 3つのパート 1枚プレゼンテーション 振り返り(気付きと疑問点) 簡単なクイズ まとめ iOSアプリ開発チームの池田です。 iOSアプリチームでは週1回1時間という時間をとって定期的に輪読会を開催しています。こちらの輪読会の内容と、学びの効率を高めるために工夫していることについてご紹介できればと思います。 輪読会のテーマと題材 今回のチーム内での輪読会のテーマは「通信関連の基礎固めと一貫した知識の習得」です。 iOSアプリ開発の施策を進めている中でネイティブアプリのフロント側での開発が多くなっており、インフラ関連の知識に触れる機会が実務でかなり少なくなっていました。 こういった機会が少ないことでメンバーの中でのインフラ関連の知識について、なんとなく理解しているけど固まっていない、知識が断片化しているといった状況が生まれていました。 この状況を改善するためにインフラ関連の知識、その中でも土台となる通信関連の知識をつけようということで上記のテーマが採用されています。 また、このテーマに合う題材として「ネットワークはなぜ繋がるのか 第2版」を選んでいます。「ネットワークはなぜ繋がるのか 第2版」では通信に関して、ハードウェアの部分から、ソフトウェアの部分まで幅広く扱っており、基礎固め、一貫した知識の習得に合う題材です。 ネットワークはなぜつながるのか 第2版 知っておきたいTCP/IP、LAN、光ファイバの基礎知識 作者: 戸根 勤 発売日: 2007/04/12 メディア: 単行本(ソフトカバー) なぜ輪読会か 基礎固め、一貫した知識の習得という目的を考えると本を利用した学習が最適だと考えチーム内で話し合った結果、輪読会形式での開催を決定しています。 何かを題材にして実際に手を動かす、本以外の題材での学習なども検討していますが、実際に手を動かすことは動くものができることでなんとなく理解してしまうことが懸念され、本以外での学習は情報の断片化が懸念されます。 そういった懸念がなく、本を利用した輪読会形式がテーマには合っており採用になっています。 学習効率を高める工夫 学習効率を高める工夫として、復習を短サイクルで多くできるようにしています。その他としてただインプットするだけでなくアウトプットに繋げる、制約を作ることによって練度を高めるといったことを取り入れています。 それらを実現するために3つのパートで輪読会を構成しています。これらの中身について説明していきます。 3つのパート 1回の輪読会を構成している3つのパートは以下になっています。 1枚プレゼンテーション 振り返り(気付きと疑問点) 簡単なクイズ 1枚プレゼンテーション 1枚プレゼンテーションでは個々人で輪読会開催日までに対象になっている章を読んできて、その内容を何かしらの形式でA4用紙1枚にまとめてきます。 まとめ方は個々人の自由になっており、図示や手書きでまとめるメンバーもいればテキストベースで要点をまとめるメンバーもいます。 こうしてまとめたサマリを各々輪読会開催日にプレゼンします。 1枚のサマリにまとめることでただ読むだけではなく、考えてアウトプットすることに繋がります。また、制約として1枚にコンパクトにまとめなければいけないことで、何度も考え要点を絞る必要が出てくるため、自分の中での復習と情報の整理に繋がり、練度が上がってきます。 更にそれをプレゼンする必要があるので、人に説明できる形にするという部分でも練度が上がっていきます。 チーム内には3人のメンバーがおり三者三様のプレゼンをするため、自分がまとめている情報からの差異も生まれるためプレゼンを聞くことも復習に繋がります。 振り返り(気付きと疑問点) 振り返りの中では、各々がサマリをまとめる中で感じた気付きや疑問点の抽出を行いこれも輪読会内で発表します。 この振り返りの中では、断片化していた知識が繋がったことに対する気付きや、理解しきれなかった疑問点などが発表されます。 理解しきれなかった疑問点については会の中で議論され、疑問解消と腹落ちに繋がります。 気付きや疑問点を持ったメンバー以外も、自分になかった視点で改めて学んだ情報を見ることになるので、より深い理解に繋がります。 簡単なクイズ 簡単なクイズパートでは、前回の輪読会で学んだ範囲について独断と偏見による復習クイズが出題されます。 ここでは単純な復習もあれば、本の中身の情報だけではないより発展的な部分まで触れたものについても出題されます。 例えばDNSの説明がされている章では、「AWSが提供しているDNSサービスはなんでしょう?」のようなクイズです。 本の中ではクラウドサービスの情報は触れられていないため、本の内容から広げて知識習得に繋がるようこういったクイズ出題をしています。 このパートでは1週間で抜けかけている情報を再度復習することによる知識の血肉化、知識をただ得るだけではなくそこから更に広げるという部分に繋がってきます。 まとめ iOSアプリ開発チームで進めている輪読会で採用している学習効率を高める工夫、それを実践するパートについて紹介させて頂きました。 クイズパートをやる中で、パッと出てこないけどこんな話あったなという内容があったり、覚えている内容が本来の回答と微妙にずれていたり、1週間という期間でも復習が大切なことが痛感されました。 今後の輪読会やその他スキル向上に繋がる施策の中でも復習をうまく重ねられるような仕組みを取り入れながら、同じ時間の中でも学習効率を高められるように工夫して進めていければと思います。 輪読会や、スキル強化に繋がる取り組みをされる中で何かの参考になれば幸いです。
こんにちは。エンジニアの加藤です。 普段はLIFULL HOME'Sの注文住宅領域にてエンジニアグループのマネジメントを担当しております。 マネジメントに携わり3年目となりますが、エンジニア組織の成果を定量的に測る難しさを常に感じておりました。 そのような中、今期より全社的にKPIマネジメントが導入され、その考え方を元に自身の担当するエンジニアグループとして目指すべき指標が明確化されたため、今回はその内容を紹介したいと思います。 KPIマネジメントについて 弊社では中尾隆一郎さんが提唱するKPIマネジメント( 最高の結果を出すKPIマネジメント )を取り入れており、そちらには以下の4つのメインキャラクタ( 4MC )が定義されています。 Goal 最終的に目指すべき状態。 KGI Key Goal Indicator = 重要目標達成指標 最終的に期末に到達したい最も重要な目標数値。 CSF Critical Success Factor = 重要成功要因 最重要プロセス = 事業成功の鍵。 KGIを達成するためにいくつかあるプロセスの中から、最も重要なプロセス。 KPI Key Performance Indicator = 重要業績評価指標 KGIの先行指標であり、CSFの数値目標。 最も重要なプロセスであるCSFをどの程度実施すれば、期末にKGIを達成できるかを表した数値。 KPIマネジメントでは上記4MCの関係性を理解したうえで適切に設定し、運用・計測・改善することが重要となります。 グループ目標としての4MC KPIマネジメントを構成する4MCに対し、私たちのグループでは以下のように設定致しました。 Goal 開発生産性の向上 KGI 開発生産力 = 価値創出数(= Pull Requestマージ数) / 開発に関わるコスト(= 人件費 + 業務委託費 + システム利用料) CSF 1タスクにかかる開発速度の向上 KPI Pull Requestマージ数 これらの4MCを選定したプロセスを紹介していきたいと思います。 Goal・KGIの選定 まずGoalとKGIについてですが、弊社では各組織単位においてそれぞれ4MCを設定し、KPIマネジメントの運用を行っております。 そのため、私がマネジメントするグループの上記組織であるユニット・部においても同様に4MCの設定がなされております。 そこで、ユニット・部を含めた組織全体として同じ方向性を持ち意識を揃える意図として、最終的な目標であるGoalとKGIは上位組織を踏襲することと致しました。 ただし、目標を達成する上での課題や状況、最適なプロセスは組織ごとに異なると考えられるため、Goalに対しての手段(CSF、KPI)はグループとして検討を行います。 CSFの選定 中尾さんの提唱するKPIマネジメントではCSFを選定する上でのポイントは以下のように言われております。 現場でコントロールでき、努力で変化するプロセス(季節要因、外的要因などは排除) 実行していればGoalに繋がるプロセス 複数候補の中から一番弱いプロセス これらを踏まえCSFを選定するにあたり、まずはKGIを構成する要素を分解し以下の2つをCSFの候補として比較致しました。 価値創出数 開発に関わるコスト 開発に関わるコストは人件費やシステム利用料などであり、ある程度固定費としてかかるため、価値創出数に対し現場の努力により変動する幅の狭い要素であると判断しました。 そのため、この時点で開発に関わるコストはCSFの候補から除外し、 価値創出数を増加 させるプロセスを深堀りすることと致しました。 KGIの要素である価値創出数はPull Requestマージ数に置き換えているため、Pull Requestマージ数の増減に影響する要素を以下のように分解しました。 実開発時間(= 総業務時間 - 運用時間 - ミーティング時間 - 社内行事時間) / 1タスクあたりの開発時間 * 1タスクあたりのPull Request数 これらの要素に対し分析を行い、最終的なCSFの決定を行います。 総業務時間 総業務時間を増加することで価値創出数が増加 各メンバーの業務時間を単純に増やすことで総業務時間を増加できる ただし業務時間の増加 = 残業時間の増加となるため、 本質的でなくCSFには適さない 運用時間 運用時間を削減することで価値創出数が増加 運用業務の削減、効率化、自動化することで運用時間の短縮を図ることができる 体感として運用業務が発生することで意識が分散し、実時間以上に生産性の妨げになっている可能性がある しかし、日次採算システム上、全体に占める割合は約5% 改善すべきポイントではあるが、 最重要プロセスとはいい難い ミーティング時間 ミーティング時間(以降MTG)を削減することで価値創出数が増加 不要なMTGの廃止、必要なMTGのみへの参加、MTGの効率化などにより削減可能 ただし日次採算システム上、全体に占めるMTGの割合は13%ほど 在宅勤務により必要なコミュニケーションも存在するとの考え方もあるため、 一番弱いプロセスとしては考えづらい 社内行事時間 社内行事時間を削減することで価値創出数が増加 社内行事時間は全社的に設けられているイベントに対しての時間のためグループとしてコントロールしづらい そのため極めて定数に近い要素となるため、 CSFには適さない 1タスクあたりの開発時間 1タスクあたりの開発時間を削減することで価値創出数が増加 開発タスクに着手してから完了となるまでのリードタイムを削減する 実行するためには開発プロセスの改善やシステム基盤の整備(リファクタ、リプレイス、仕組み化、標準化など)など様々なアプローチが考えられる エンジニアに裁量があり、主体となって実行する部分であるためコントロールがしやすい 現状システムの複雑性や技術的負債が開発生産性を妨げている大きな要因となっている これらにより考えられるアプローチを実行したうえで開発時間を短縮することが、 最も重要なプロセスであると考える 1タスクあたりのPull Request数 1タスクあたりのPull Request数を増加することで価値創出数が増加 レビュアーの1回のレビューにかかる負担を減らすなど開発生産性の向上に対しての一定の効果が表れる可能性がある ただ1タスクあたりのPull Request数を上げることだけを最重要プロセスとして捉えると、小手先での調整でも可能となり、本質的な取り組みから離れてしまう懸念がある そのため、ここでは CSFの対象としては除外する 上記より、最終的に私たちのグループでは「 1タスクにかかる開発速度の向上 」が最重要プロセスであると捉え、CSFとして選定しました。 また、弊社では以前より日次採算システムを全社的に導入しており、一人ひとりが各業務ごとにどれだけ時間を費やしているかを計測しております。 体感では運用業務に多くの時間を費やしている印象もありましたが、実際に計測数値を確認してみると割合としては少ないと分かったことから、事実を元に分析をする上でKPIマネジメントと日次採算システムの組み合わせの有効性の高さを感じました。 KPIの選定 CSF同様、KPIにも選定する上でのポイントがあり、以下のように言われております。 シンプルで分かりやすい指標 CSFとの整合性が取れている指標 現場でコントロール可能な指標 即座に計測・入手できる指標 CSFは1タスクにかかる開発速度の向上であるため、それを計測する指標としては1タスクあたりの開発時間がKPIとして考えられます。 しかし、現状では各開発タスク毎にどれだけの時間がかかっているかを正確に計測する仕組みがなく、「即座に計測・入手できる指標」であるという部分にマッチしません。 また、計測に際しての運用も複雑になる懸念があるため、現状KPIとしては適さないと判断し、別の指標を検討致しました。 そこで、1タスクにかかる開発速度の向上を計測する指標を選定するため、改めて価値創出数を算出する要素を確認します。 価値創出数(Pull Requestマージ数) = 総業務時間 / 1タスクあたりの開発時間 * 1タスクあたりのPull Request数 ここで各要素に着目し、それぞれ定数と変数に分類しました。( 青:定数 、 赤:変数 ) 定数と変数に分類したことにより、1タスクあたりの開発時間の変化に比例して、Pull Requestマージ数が増加すると捉えることができると思います。 そのため、Pull Requestマージ数がKPI候補となり得るのではないかと考え、KPI選定のポイントと照らし合わせても以下の理由で最適であると考えました。 シンプルな値で分かりやすい 上記の式によりCSFとの整合性が取れている (開発時間の短縮を)現場の努力で改善可能 ダッシュボードより既に容易に計測可能 上記より、最終的に私たちのグループでは「 Pull Requestマージ数 」をKPIとして選定しました。 ただし、このKPIには注意点も存在します。 総業務時間と1タスクあたりのPull Request数が定数であることが前提であるため、この2つの要素が現状から大きく変化する場合、正しく成果が計測できないこととなります。 そのため、定期的に上記2つの数値は確認をし、変化が大きい場合はKPIを見直すことをルールとして定め運用します。 KGIとKPIの目標値について KPIマネジメント導入の初年度ということもあり、今期に関しては現状からの105%成長で設定しました。 2020/10〜2020/12をサンプリング期間として定め、こちらの期間の3ヵ月の平均値をベースに105%成長した数値を目標値として設定し、2021/1〜2021/9までの9ヵ月間の平均値にて計測します。 目標値を平均値としている理由には、繁忙期やプロジェクトのフェーズにより数値のばらつきも発生すると考えられるため、平均して一定のパフォーマンスが発揮されているかを測る意図があります。 まとめ 以上が私の担当するエンジニアグループがKPIマネジメントの考え方を元に目標指標と定量的な目標値を導いた内容となりますが、まだスタートラインに立った状態であると思います。 今後、設定した目標に対し実行・計測・改善を繰り返し、より生産性の高いエンジニア組織へと成長していきたいと思います。 今回の記事を通じ、私と同じようにエンジニア組織の定量的な成果計測に悩む方の一つのヒントになれば幸いです。
こんにちは。エンジニアの松尾です。 私がエンジニアチームのマネージャーになって1年が経過しました。日々の仕事に慣れてはきたのですが、徐々に部署内外で引き受けるタスクが増えてきたことで重要度が高いタスクの消化が難しくなってきていました。 そこで、LINE株式会社のブログで共有されていた下記の記事を参考に、ワークショップ形式で仕事の見える化と棚卸しに取り組みました。 引き継ぎのスムーズ化を図るため、LINE企画室が行った「お仕事解体ワークショップ」とは? 今回は 「メンバーによる私の仕事の棚卸し」 と 「上司の仕事の棚卸し」 の両方に取り組んでみたので、する側/される側の両面についてまとめてみたいと思います。 やったこと メンバーによる私の仕事の棚卸し きっかけ メンバーとの1on1で私とメンバーの仕事量のバランスについて話していたときに 前述の記事 が話題にあがり、「今持っている仕事をもっと引き継いでも良いのでは」という話になりました。ちょうど組織が変更されて新しいメンバーが私の部署に合流したタイミングでもあったため、自部署の仕事を洗い出す意図も込めてワークショップの開催を決めました。 仕事の洗い出し マネージャーしか知らないこと、メンバーしか知らないこと、のように「自分が抱えこんでいるタスク」を積極的に付箋に書き出しました。各自の手が止まっていく中で私の付箋書き出しが淀みなく進む光景を見て、メンバーからは「そんなことやってたんですか…」という声もあがりました。 引き継ぎする項目の決定 書き出した後には付箋を色で分類します。今回は黄色をデフォルトとして 「ほかの人にやってほしい(引き継げそう)」 をオレンジに、承認作業のような 「誰にも引き継げない」 を青に変更しました。 分類された私の仕事 次に、引き継げる可能性のあるタスクを うれしみ(引き継げるとうれしい) と ムズみ(引き継ぐのは難しい) の2軸でマッピングしました。 マッピングされた私の仕事 記載内容の詳細や不明点についてはメンバーからの質問に応じて説明していきました。 引き継ぎ内容の決定 マッピングの結果を見ながら、KPTのTryを決めるようなイメージで取り組みを決めていきます。例として下記のような対応がメンバーの意見で決まっていきました。 MTGのファシリテーション -> 特定メンバーに委譲/輪番制 外部からの問い合わせ窓口 -> チケット発行と割り振りのしくみ作り 手作業で行っていた運用作業 -> プログラムによる自動化 各種ソースレビュー -> チームの階層を作って分散 解体されてみると「こんな簡単に引き継げるのに、なんで1人で抱えてたんだろう」という気持ちになります。 上司の仕事の棚卸し きっかけ 私自身の手が空いたことで少し余力ができたので、そのぶん上司の仕事を巻き取ることもできるのではと思い立ちました。上司の立場の仕事を見ることでより高い視座を持って現状の仕事に取り組みたいという意図もありました。 ワークショップの内容 私を対象にしたときとほぼ同じ内容でしたが、「 Google Jamboard ではスペースの制限が厳しかった」というふりかえりを活かして miro を利用しました。 私の上司は組織のマネージャーでありエンジニア職のマネージャーでもあるため、部署以外でも採用や組織開発といった役割を担っています。そのため、タスクを洗い出したうえでまずカテゴリ(ロールに近いもの)を分類しました。 分類された上司の仕事 これらを俯瞰し意識しつつ、うれしみ/ムズみマッピングに付箋を置いていきます。 マッピングされた上司の仕事 採用や組織開発など引き継ぎの難しい仕事が多かったので、ムズみの強くないものを積極的に引き継ぐ(なくす)結果となりました。意外と単純な作業もあるので下記のような対応をしていく予定です。 承認作業: 権限を委譲して代理できる人を明記 自部署全体ミーティングの仕切り: 段取りをまとめて引き継ぎ ルーチン、単純作業: リマインド設定、自動化 わかったこと あくまでも弊社で実践してみた一事例ではありますが、私が体験した両方の立場で感じたことをまとめます。 解体される立場での気付き 🙅♂️ タスク量を客観的に見て管理できていない 自分のタスクの量を過去のピーク時と比較して調整しがちであることに気付きました。 本来はチーム内でのバランスや心の中でのうれしみも踏まえて割り振るべきなので、基礎的なことではありますが取り組み方を変えようと思います。実施前より人にタスクを渡す判断の材料が増えたと感じています。 🙆♂️ 意外と引き継ぎはWin-Winで着地できる 引き継ぎ先の仕事を増やしてしまうのが申し訳ないと思っていましたが、取り組み方と工夫によってプラスにもなることがわかりました。 たとえば私は朝会のファシリテーションを雑務ととらえて積極的に誰かに渡すことをしませんでした。ところがあるメンバーは「リモートで話す機会が減ったので、ほかの人に直接語りかける機会は貴重」ととらえて取り組んでくれているようです。 解体する立場での気付き 🙅♂️ 自分から見えないタスクは想定以上に多い 本人が「これは自分の仕事だから」と(悪く言うと)思考停止して外に出していないタスクがあり、チーム全体で見ると無駄につながっているケースが意外とあることに気付きました。 引き継ぎの可能性を自身で判断せずにまずは洗い出せるという点は、このワークショップの良さだと感じました。 ️🙆♂️ 見えるようになっただけでも価値がある 権限やスキルの問題で引き継ぎが難しいことも多々あります。ですが現時点でのタスクをほかの人に割り振れなかったとしても、新しく増やさないように対策を練ることはできそうです。 また、メンバーが将来同じ立場になることも考えられるため、その仕事を事前に見て体感できるという点でも価値があると思います。 次やること 定期的に仕事を棚卸しする機会を設けることが重要だと感じました。特に組織が変更されるタイミングとの相性が良さそうですので、今後も折を見てワークショップを開催していきたいと思います。 一方でワークショップを高頻度で開催することは難しいです。朝会での共有やかんばんの活用などを個々人に任せ過ぎず、日ごろのタスクを正しく可視化していければと思います。 まとめ 仕事を渡すのが苦手な人はマネージャーに限らずたくさんいると思います。そんな人も今回紹介したワークショップのように、何らかの機会を作ってぜひ引き継ぎを検討してみてください。 ちなみに、私の仕事を解体するワークショップの企画と進行はまるっとメンバーがやってくれました。快く引き受けてくれたメンバーには感謝しています。 これによってさらに良いチームを作ろうと気持ちも引き締まったので、メンバーにも別の何かで還元していければと思います。
QAグループの星野です。 昨年の2020年11月に公開された『LIFULLのQAの取り組みについて』にてQAグループの主だった活動について紹介されました。 本記事では、こちらで概要だけ紹介されている"リリース前リスク分析を起点としたQAのアクション"についてご紹介致します。 QAが プロジェクトメンバーとして参画していないプロジェクト を対象とした取り組みになります。 www.lifull.blog また、今年2021年1月にはそれらの活動の中からテスト計画の作成を行う『テスト計画コンシェルジュ』について紹介がありました。 QAがプロジェクトに対して直接的にアプローチする取り組みについてはこちらの記事をご覧ください。 www.lifull.blog RiskManagementNoteについて なぜ行っているか どんなことをしているのか どう行っているのか ET検討会について なぜ行っているか どんなことをしているのか どう行っているのか まとめ RiskManagementNoteについて なぜ行っているか LIFULLでは設計や実装を行っているエンジニアたちがテストにも責任を持っています。 テスト設計や実施のみを専門としている組織は存在しません。 よって、すべてのプロジェクトにQAチームが必ずしも直接的に関与する必要がありません。 しかし、自分たちの関わっていないプロジェクトで本番障害が発生しユーザーへ不利益が発生したときに「関係ありません」と知らんぷりは絶対にしません。 自分たちが直接的に関わっていてもいなくても、本番障害を自分たちで防げる可能性があったなら責任があると考えています。 大きなリスクを抱えたプロジェクトになるべく気がつけるように各開発部署の情報を抽出し、人の目で改修要件や仕様書を確認しています。 どんなことをしているのか 抽出したチケット情報からプロジェクトのドキュメントを参照して改修要件などを確認します。 基本的にはプロジェクトの比較的序盤、改修要件が定まっている段階のものが調査対象になります。 改修内容や影響範囲やリリースの予定日など様々な情報をまとめ、 調査/分析した結果をQAチームで確認し、なにかしらの対応が必要かどうかを検討しています。 どう行っているのか プロジェクトの情報を見ながらリスク、特にプロダクトリスクを考えます。 改修箇所で問題が起こった場合に「重要度:システムの機能への影響」「優先度:低下するシステムの価値」「発生確率:遭遇し得るユーザーの規模」の3軸で定量的に数値を出します。 それに加え、改修要件を見ながら「テストは十分に検討されているか」「過去の障害から予測できる障害はないか」「他プロジェクトと改修範囲がバッティングしていないか」「自動e2eテストで検知できるか」などを考えながら定性的なリスクを挙げていきます。 これらの定量的、定性的な情報からプロジェクトへQAが関与するかどうかを判断しています。 ET検討会について 続いてET検討会についてです。ETというのはExploratory Testingの略称で、探索的テストを指しています。 RiskManagementNoteではプロジェクトの比較的序盤で調査をしているのに対し、ET検討会ではリリース直前のものを対象に扱います。 なぜ行っているか 私が入社した時点ではRiskManagementNoteのみで、ET検討会は行われていませんでした。 あるとき、リファクタリングやSEO対策のための小さなプロジェクトが増え始め、1日にリリースされるプロジェクト数が大幅に増えた時期がありました(多い日には1日に30件程度リリースされていた)。 開始からリリースまでの期間が短い小さなプロジェクトが増えたことで、 RiskManagementNoteのチケット調査では網から漏れて掬い上げられないプロジェクトが出てきたり、 QAがRMNの検討フェーズに入った時点でリリースを翌日に控えているなど対応が追いつかなくなってきました。 また、小規模なリリースとはいえ、それだけの数がリリースされるとなると統合時に何があるかわかりません。 開発チームがテストをしていると言っても、他チームのリリースによる影響まで考慮して見ることは難しいためQAが水際作戦でケアすることにしました。 リリースについてはチケットで管理されているため、RiskManagementNoteで網から漏れてしまったプロジェクトもここで拾い上げることができます。 どんなことをしているのか 当初はリリース周りのチケットを手動で集めていましたが、現在は自動的に抽出し何件のリリースが控えているのかをbotが教えてくれます。 こちらもRiskManagementNoteと同様に「どんな障害が起こり得るか 」「類似する障害はないか」「テストは十分に行われているか」などの観点でプロジェクトの情報を確認します。 他、ET検討会が始まったときの「同時にリリースされる施策で衝突しそうなものはないか」といったものも気にしています。 どう行っているのか ここで対象とするものは翌営業日にはリリースされてしまうため、その日のうちに探索的テストを実施します。 開発チームが所有する環境で既に開発チームによるテストは実施されており、 QAが確認する環境はそれとは別のテスト環境であるため、開発チームのテストには影響がありません。 また特別な環境の準備も不要なので自由なタイミングで実施することができます。 リリースを止める際にも判断含め時間が必要になるため、QAチームはなるべく迅速に探索的テストに取り掛かります。 そのため、(少なくとも自分は)チャーターを入念に準備することはあまりせず、挙げたリスクを中心に実施しています。 まとめ QAの間接的なプロジェクトへのアプローチをご紹介しました。 プロジェクト内のエンジニアがテストに責任を持っているとしても、(少なくとも私は)QAが不要になることはないと考えています。 冒頭で直接的なアプローチとしてご紹介している テスト計画コンシェルジュ などの取り組みも含め、 開発チームが自分たちのつくりたいものに注力できるように、出来上がるものがより良いものになるようにサポートするのがQAの役目だと感じています。 LIFULLのQAチームはテストの設計や実施のみを専門とするような組織ではなく、 横断的な組織だからできること、開発したエンジニアがテストに責任を持っているからできること、 そういった「自分たちだからできること」とET会が始まったように「状況に応じて必要な行動を取ること」を大事にしているチームだと思います。 ここに書いている取り組みが、読んでくださっている方々の組織にそのまま適応できるかはわかりませんが少しでも参考になれば幸いです。
技術開発部の清水です。好きな食べ物は 広島風 お好み焼きと 広島県産 牡蠣と 広島県産 穴子です。 拡張に次ぐ拡張でサービスは便利なものに成長していく一方でソースコードは次第に複雑になっていきます。 そのまま放っておくと積み上げた技術的負債により開発コストが上がっていき、最悪の場合にはサービスの発展を停止させてしまう可能性もあります。 このような理由から、弊社では技術的負債を着実に返済していくべく生産性・技術的負債の可視化をMetabaseで行っています。 可視化する情報元はGithub API、CodeClimateQuality APIの2つのみです。 生産性の可視化 本流ブランチにマージされたPR数(生産数) 本流ブランチにマージされたPRによる意味のある変更行数(生産規模) 本流ブランチにマージされたPRの平均レビュー応答数(生産を助けた人員の労力) 本流ブランチにマージされた「1コミッターあたりの」PR数(1生産者あたり生産数) 開発者のコミッター・レビュアーとしての行動バランス 技術的負債の可視化 技術的負債の現況と現在に至るまでの推移 REMEDIATION_TIMEを自分ごとにできるようにする 本流ブランチにマージされたPR別のREMEDIATION_TIMEの推移 コミッター別REMEDIATION_TIME変動累積値 効果の高いリファクタリング対象ファイルの選定 おわりに 生産性の可視化 本流ブランチにマージされたPR数(生産数) 開発者にとって 生産性 とは何でしょうか。様々なご意見が予想されますが、生産性ではなく 生産数 ということであれば 本流ブランチにマージされたPR数 は開発者が身近に感じやすい一つの指標かと思います。 本流ブランチにマージされたPR数 PRは「 ある要件を満たすためにまとまったソースコードの変更」 であると言えますし、本流ブランチにマージされて初めて価値を生み出すという特徴があります。但し、これを「生産性」と結びつけるためにはいくつかの要素が加味されていません。PRの規模は大小様々ですし、PRをレビューした人員のコストも様々で、期間内に何名のコミッターが活動したのかも様々です。これらを可視化していきます。 本流ブランチにマージされたPRによる意味のある変更行数(生産規模) 意味のある変更行数というのは、空行やコメントなどを除いた行数です。 変更行数の多いPRは 切り戻しの難しさ もありますが、 レビュアーのレビューコストを増幅 します。 適切な粒度に分割できるようになると、レビュアーは少ない変更に集中してレビューすることができ、ひとつの生産にかける時間の総合を短縮することにつながります。 本流ブランチにマージされたPRによる意味のある変更行数 本流ブランチにマージされたPRの平均レビュー応答数(生産を助けた人員の労力) PRをマージするまでの期間に、 コミッター・レビュアー間でコメントの応酬を行った回数 です。 本流ブランチにマージされたPRの平均レビュー応答数 レビュアーが即座には受け入れられない疑問や質問の余地のある実装は、レビュアーのレビューコストを増幅するものです。 少ないレビュー応答数でPRがマージできるようになるような、わかりやすい実装やレビュー依頼は、レビュアーの労力を下げますし、ひとつの生産にかける時間の総合を短縮することにつながります。 本流ブランチにマージされた「1コミッターあたりの」PR数(1生産者あたり生産数) 前述した 「本流ブランチにマージされたPR数(生産数)」をその期間アクティブであったコミッター数で割った値 です。 生産数が順調に増えていたとしても、人員が増えたことによる結果なのであれば、アプリケーション起因の生産効率は変わっていないと考えられます。 本流ブランチにマージされた「1コミッターあたりの」PR数 100人で100PRをマージできる状態と、50人で50PRをマージできる状態では、生産効率はともに1とし 100人で200PRをマージできる状態は2であり、100人で100PRをマージできる状態に比べて2倍の生産効率であるという考え方です。 (=少ない人数でも多くのPRをマージできる状態が生産性の高いソースコード) この値がより大きく「本流ブランチにマージされたPR数(生産数)」も大きいのであれば「生産量・生産性ともに上がった」と言えるではないでしょうか。 (ただし、その変更の内容が設定ファイル・READMEの変更のみである可能性もあるため、PRの変更内容から判定し、それらを除外する必要はあります。) 開発者のコミッター・レビュアーとしての行動バランス ある開発者は実装ばかりを、ある開発者はレビューばかりをしている という状況はよくあると思いますが、そのような状況が続くと 属人化 の可能性が高まります。 コミッターの集中、レビュアーの集中を避けられるように、開発者のコミッター・レビュアーとしての活動バランスを、全体の開発者における相対的な分布図で表しています。 開発者のコミッター・レビュアーとしての行動バランス 水色の丸ひとつひとつが開発者で、X軸がコミッターとしての生産活動数、Y軸がレビュアーとしての生産活動数になります。丸の大きさは変更行数に比例し、コミッターとしての活動数が少なくても、その1つの開発が巨大である場合には大きく表示されます。実際にはカーソルをあわせると開発者名が表示されますが、ここでは伏せています。よりバランスの良い状態(左下から右上への直線に近似する状態)を、チーム全体で目指していくとチームとして開発者の活動バランスが高く、属人化がされていないと予測されます。 ここまでが「生産性」に関する指標です。いかがでしょうか。 これらの情報は全てGithub APIから取得した情報を元に可視化が可能です。 続いて 「技術的負債」 に関する指標です。 技術的負債の可視化 技術的負債の情報はCodeClimateQualityのAPIから取得した情報を元に可視化しています。 codeclimate.com 技術的負債の現況と現在に至るまでの推移 下記はあるプロダクトにおける技術的負債の推移を月次・週次・日次・PR別という粒度で推移グラフを出力したものです。 技術的負債の現況と現在に至るまでの推移 上段は現況を表し下段は現在の数値に至るまでの月・週・日・PRマージ別の推移を表しています。 ここではまず、そのRepositoryの技術的負債に関する現況と現在に至るまでの推移を把握することに努めています。 推移グラフの赤線は、 REMEDIATION_TIME(推定修復時間) です。これは健全な状態に直すまでにかかる時間の想定値であり最重要視しています。 緑線は IMPLEMENTATION_TIME(推定実装時間) です。これはこの状態になるまでにかけられた時間の想定値です。 灰線は TECHNICAL_DEBT_RATIO(技術的負債比率) です。これは規模の異なる複数のリポジトリを比較する際に有効な値です。 このRepositoryでは5月から9月まで順調にREMEDIATION_TIMEを減らしていき10月に微増した。 まず、このようなことが言えるかと思います。 なお、これらの指標はCodeClimateQualityの下記の記事で説明されています。 codeclimate.com REMEDIATION_TIMEを自分ごとにできるようにする 多人数で開発するRepositoryの場合、いくら技術的負債を可視化しても 自分ごととして考えづらい という難点があります。 また、その改善結果が正しく見えないことには、モチベーションは上がりづらいと思います。 本流ブランチにマージされたPR別のREMEDIATION_TIMEの推移 「あるPRでは1時間増加、次のあるPRでは13時間削減した」 というPR別のREMEDIATION_TIMEの推移をみることができるようにしています。 ここまでくると、どのPRにより、負債が削減・増加したのかは明らかで、それが自分の実装・レビューによるものであるのかも明らかです。 (画像では説明に不要な具体的な情報は伏せております) 本流ブランチにマージされたPR別のREMEDIATION_TIMEの推移 コミッター別REMEDIATION_TIME変動累積値 「ある開発者が一定期間内に複数の開発を繰り返すことで、ある開発時には100時間増加させたけど、後日別の開発時には200時間削減し総合的にこれまで100時間の削減をおこなった。」 このようなことが後でわかるように、コミッター別REMEDIATION_TIME累積を出力しています。 左は、よりREMEDIATION_TIMEをより大きく削減したPR、右は、コミッター別REMEDIATION_TIME累積を示します。 (画像では説明に不要な具体的な情報は伏せております) コミッター別REMEDIATION_TIME変動累積値 効果の高いリファクタリング対象ファイルの選定 いよいよ技術的負債に問題意識が生まれ、技術的負債の返済に時間をとれることになったとします。 では、限られた時間でまずどのファイルを変更すればいいのでしょうか。 CodeClimateQualityでは静的コード解析上のボトルネックは教えてはくれます。 しかし、当然のことですが静的コード解析であるため 開発プロセスや組織構造、実行順序などを考慮した物 ではありません。 その結果、単純に静的コード解析上のボトルネックに従うばかりでは 「コードは複雑だけどほぼ誰も触らないファイルを全力でリファクタリングしてしまう」 可能性があります。 静的コード解析上の大きな改善とならないとしても、できることなら限られた時間で、より改善効果を感じられるファイルをリファクタリングしたいものです。 高頻度で変更されたり、多くの人に変更されるファイルは、小さな改善数値でも大きな改善結果を感じられるはずです。 このような理由で、変更回数の多いファイル、変更者の多いファイルを各種指標に添えて可視化しています。 (画像では説明に不要な具体的な情報は伏せております) 効果の高いリファクタリング対象ファイルの選定 弊社ではこのようなダッシュボードを様々なRepositoryを対象に出力しています。 複数のRepositoryをこのような同じ測りで比較してみると次第に面白い傾向が見えてきます。 実装量が増えるにつれてREMEDIATION_TIMEも増えるRepositoryばかりではない。 X年しか経過していないがREMEDIATION_TIMEがX年以上増えてしまうRepositoryが存在する。 特定の開発者が物凄い勢いでREMEDIATION_TIMEを返済しているRepositoryが存在する。 特に最後の「特定の開発者が物凄い勢いでREMEDIATION_TIMEを返済しているRepositoryが存在する」このケースの気づきは、 技術的負債を返済してくれた人と功績を可視化 することだと思います。 同じRepositoryを開発する皆に恩恵がある尽力の結果ですので、称賛されるような文化醸成がされていくことでモチベーション向上にも繋がりますし素晴らしいことと考えています。 おわりに エンジニア職以外の方には技術的負債返済にコストをかけるメリットが伝わりにくい と言う声をお聞きしたことがあります。 上記のような重視する指標を提示し、交渉相手の重視する指標を提示してもらい、どのような影響を与えるのかを示すことができれば 技術的負債返済の必要性を理解していただき、交渉が円滑になるのではないでしょうか。 最後までお読みいただきありがとうございました!
こんにちは。Ltech運営チームの井坪です。 今回は、2021年1月18日(月)に開催した『Ltech#13 事業開発エンジニアとは?~実装は甘え~』についてレポートします。 lifull.connpass.com Ltechとは Ltech(エルテック)とは、LIFULLがお送りする、技術欲をFULLにするイベントです。特定の技術に偏らず、様々な技術の話を展開していく予定です。 事業開発エンジニアとは? 今回のテーマは『事業開発エンジニアとは?』です。 エンジニアと一言で言っても、アプリケーションエンジニアやフロントエンドエンジニア、QAエンジニアなど各方面の様々なエンジニアが活躍しています。 今回はその中でも、『事業開発エンジニア』というLIFULL HOME'S以外の新規事業にフォーカスしたエンジニアの方に語っていただきました! 3時間でプロトタイプをユーザーにお届け!LIFULLの高速仮説検証プログラムとは? 3時間でプロトタイプをユーザーにお届け!LIFULLの高速仮説検証プログラムとは? from LIFULL Co., Ltd. www2.slideshare.net 最初は、LIFULLの新規事業を加速させるための高速なプロトタイプの提供と仮説検証についてです。 以下の3つのプロセスを行い、高速なプロトタイプの提供を行ってます。 ユーザを主語にした仮説を構築(1h) 検証方法の設計(1h) 実装(1h) このプロセスを繰り返し行うことで、仮説検証で結果が出ないままリリースしても結果が出ず、『フェイルファースト』が鍵になることが見えてきました! 価値のあるプロダクトかどうか検証せず「きっと上手くいくはず」と実装し市場やユーザに対して甘い期待をするのではなく、実装する前に仮説検証を行いプロフェッショナルとして実装に甘えず取り組んでいます。 大規模サイト開発と新規事業開発の経験から見たそれぞれの違い 大規模サイト開発と新規事業開発の経験から見たそれぞれの違い from LIFULL Co., Ltd. www2.slideshare.net 次は、LIFULL HOME'Sと新規事業での開発経験から感じた違いについてです。 ※発表内容は発表者個人の見解になります。 以下の点について、お話していただきました。 開発の優先度 エンジニアの裁量 エンジニアとしての担当領域 PJメンバーとしての担当領域 求められる姿勢やスキル それぞれの良いところ/辛いところ 開発において納期・品質はどちらも重要ですが、新規事業ではある程度の品質を担保しつつより早くリリースすることで、ユーザ検証を行い、事業にスピード感を出すことで競合他社に差を付けるメリットがあるようです! 新規事業ではメンバーが少ないことが多く、開発は分業できず1人で担当する領域が広く必要なことは判断して対応していく必要があり、求められる姿勢やスキルは、エンジニアリング以外にも事業の成長に必要な企画を考えたり数字を分析したりも必要になってくるそうです。 最後に 今回は、新規事業に取り組む事業開発エンジニアに発表していただきました。 参加者からの方から、新規事業開発時の心構えや当事者の想い、プロトタイプ開発の意義を理解できたなどコメントをいただけ、LIFULLでの事例ではありますが参考になったのではないかと思います。 Ltechでは、LIFULLエンジニアが中心となって皆様の技術欲を満たすよう実例を交えた勉強会を開催しています。 今後もLtechを積極的に開催していきますので、 ぜひ気になった方は、connpassでLIFULLのメンバー登録をよろしくお願いします! lifull.connpass.com
テスト計画コンシェルジュとは テスト計画コンシェルジュの流れ 1:施策の概要を聞く 2:テストアイテム、テストスコープを明確にする 3:どのテストレベルでテストすればよいか考える 4:テストのアプローチを組み立てる 5:プロダクトリスクを挙げ、そのリスクが考えたアプローチでケアされているか確認する まとめ こんにちは。QAグループの松谷(まつや)です。 みなさんはテスト計画を行なっていますか? テスト計画では、「どのテストレベル」で「どの対象」に対して「どのようなテスト」をしていくかという、テストのアプローチを定めることが大切です。 このテストのアプローチの有無によって、プロダクト全体としてMECEで効率的なテストになるのか、抜け漏れが多い残念なテストになってしまうかが決まってきます。 今回は、プロジェクトチームと共にテスト計画を作成する「テスト計画コンシェルジュ」をご紹介します。 テスト計画コンシェルジュとは テスト計画コンシェルジュは、横断組織であるQAグループによるテスト計画作成代行サービスです。 プロジェクトチームからテスト計画コンシェルジュの依頼を受け、テスト計画ミーティングを行います。 そのミーティングでプロジェクトチームと一緒にテスト計画を考えます。 このときスケジューリングなどを含めた全ての計画を行うわけではありません。 我々とプロジェクトチームが話し合って、テストスコープを明確にし、互いに腹落ちするテストのアプローチを定義します。 テスト計画コンシェルジュの流れ テスト計画コンシェルジュは、プロジェクトチームから依頼があったときに実施します。 依頼はチケットで管理されています。その際の入力項目は以下です。 施策概要 規模(人数と全体工数) 開発拠点 開発期間 既存リスク このチケットで概要や規模感を把握し、テスト計画コンシェルジュのミーティングをセットアップします。 1:施策の概要を聞く ミーティングが始まりましたら、最初にテスト計画の対象となる施策の概要を聞きます。 施策の全体像を聞き、どういったことを実現したいのか把握します。 依頼チケットでもおおよその概要は把握してから臨んでいますが、認識のすり合わせを行なっていきます。 2:テストアイテム、テストスコープを明確にする 概要を聞きつつになりますが、徐々に話を掘り下げ、その施策のテストアイテムを洗い出していきます。 概要からわかるテストアイテムもあれば、 「○○は関わってこないのですか?」 「あ、そうですね。影響があるかと思います」 と、問答することで新しく浮かび上がってくるテストアイテムもあります。 他施策やシステムとの関わりなどは、横断組織である我々だからこそ気づく場合もあります。 さらにテストアイテムについて質問を交えながら話を掘り下げ、テストスコープを把握していきます。 「不安だからとりあえず全体的に」といった話も出ます。 ですが、テストする機能は何で、テストしない機能は何かをはっきりさせないと、テスト工数が膨れ上がってしまいます。 3:どのテストレベルでテストすればよいか考える テストする機能を細かく分けていくと、テストする粒度が見えてきます。 例えば以下のような粒度です。 ロジックがメインで計算結果を確認したほうがよい機能 CRUDのような処理や、インターフェイス部分を確認したほうがよい機能 他機能やシステムとの連携が多く、それらを通してテストしたほうがよい機能 これらが見えてくると、どのテストレベルでそれらのテストを行うかが見えてきます。 見えてきましたら、テストする機能をどのテストレベルで行うか当てはめていきます。 ユニットテスト 統合テスト システムテスト (受け入れテスト) テストレベルを考慮しない場合、ほとんどのテストがシステムテストに偏っていくので注意が必要です。 4:テストのアプローチを組み立てる ここまでで、どの機能を、どのテストレベルでテストするかが見えてきました。 次は、それらについてどのようにテストをするか、テストのアプローチを組み立てていきます。 テスト計画の段階ですので、プロダクトに対しての全体的なテストの枠を組み立てるイメージです。 詳細なテストの組み立てはテスト設計段階で行うことになります。 ここでは行うべきテストタイプや、探索的テストといったテスト方法を挙げて組み立てることが多いです。 (私はついついテスト設計段階のことまでしてしまうこともあります…) 各機能のことだけではなく「システムテストに入ったらまずは大きなバグを見つける目的での探索的テストをしましょう」といった作戦も伝え、テストの流れも組み立てることもあります。 この「どのようにテストをしていけばいいか」というアプローチが見えることにより、プロジェクトチームはテスト工程が見え、やるべきことがわかり、安心します。 5:プロダクトリスクを挙げ、そのリスクが考えたアプローチでケアされているか確認する 最後にプロダクトリスクを聞いていきます。 プロダクトリスクはそのまま聞いても意見が出ないことがあるので、以下のようなことを聞きます。 不安なこと 起きて欲しくないこと この際、プロジェクトリスクとプロダクトリスクの双方の意見が出てきます。 ここではプロダクトリスクにフォーカスします。 プロダクトリスクはテストによってケアできるためです。 このとき挙がったプロダクトリスクが、先に組み立てたアプローチでケアされているか確認します。 この活動が、アプローチの抜け漏れチェックとして働いています。 例えば 「実際の業務フローでちゃんと動くのか不安」 といったリスクが上がったら 「業務フローを使ったシナリオテストを追加しましょう」 と漏れていたアプローチに気づき対応することができます。 まとめ QAグループが行なっているテスト計画コンシェルジュの紹介でした。 テスト計画は、時間がかかりそう、という理由で敬遠されがちです。 ですが、何も計画も立てずにテストに臨んだ場合は、非効率なテストになったり、抜け漏れが発生する可能性が非常に高いです。 恐らく最後にはテスト計画にかける労力以上に膨大な労力が費やされてしまうでしょう。 今回紹介したテスト計画コンシェルジュでは、機能をいくつか追加といった規模の施策の場合、60分のテスト計画ミーティング内で行われます。 この時間でしたら敬遠するほどの長時間でもないですし、アジャイル開発にも組み込みやすいのではないでしょうか。 最後に2011年の"Ten Minute Test Plan"を紹介して終わりたいと思います。 huddle.eurostarsoftwaretesting.com
こんにちは! プロダクトエンジニアリング部の吉永です。 今回は2020/12/28(月)に社内イベント「かぞく参観日」で開催したプログラミング体験教室について紹介したいと思います! アジェンダ かぞく参観日とは? プログラミング体験教室について プログラミング体験教室の講師を引き受けた背景 プログラミング体験教室の教材テキストについて プログラミング体験教室のカリキュラムについて 実施してみて まとめ かぞく参観日とは? 「かぞく参観日」はLIFULLで働いている社員のご家族の皆さまに、LIFULLについて知っていただきたく開催している社内イベントです。 毎年年末に開催しており、昨年まではお子様達に実際にオフィスに訪問してもらい、オフィス内を見学したり、様々なイベントに参加してもらうイベントでした。 が、今年は新型コロナウィルスの影響もあり、オフィスへの訪問はせず、Zoomでのオンライン開催となりました。 初めてのオンライン開催ということもあり、事前準備などで 色々と苦労した点についても紹介していきます。 プログラミング体験教室について 例年開催しており、人気のあるプログラムということで、オンライン開催となった今年度も開催することになりました。 オフライン開催だった2019年は「 PETS 」という実際にさわって学ぶ教材を使ったプログラムを開催したようです。 今年度は完全オンライン開催ということで、ハードウェアを絡めたプログラミング体験は遠隔サポートの難易度が高いので難しいだろうと判断し、PCやタブレットで実施可能な教材を使用する前提で実施する内容を検討しました。 プログラミング体験教室の講師を引き受けた背景 私は前職で2016年から毎年4月~9月ごろまで、新入社員向けのプログラミング研修の講師を務めていました。 研修講師を務める前までは、どちらかというと自分自身へのインプット中心で、後輩や部下のOJTなどは業務だから行っているという気持ちで取り組んでいました。 仕事だから仕方なくという姿勢で取り組んでいた私のマインドを切り替えてくれたのが、2016年に初めて携わらせていただいた、新入社員向けのプログラミング研修の講師という仕事でした。 IT企業の新入社員といっても、昨今の人材不足の影響もあり、学生時代にプログラミング未経験で入社されてくる方も近年はかなりの数でいらっしゃいます。 プログラミング未経験の新入社員でも、3ヶ月間の研修を受けて配属されるまでの間に簡単なWebアプリケーションを構築できるまでに成長することができ、そんな方々のサポート、教育に携わることの「楽しさ」が恐らく今の私の教育関連への関心の高さを形成したのだと思っています。 自分の知識をアウトプットすること、説明する人毎に異なる観点で説明して理解してもらうこと、これらの「楽しさ」に気づくことができ、エンジニアとしてよりレベルアップできたと感じることができたので、現在ではインプットした内容を如何に早く、第三者に分かりやすい内容でアウトプットできるかということが私の学習サイクルになっています。 そんな背景もあり、LIFULLに転職した今でも、週一回の社内サークル活動にて非エンジニア向けのプログラミング教室を開催しています。 参考までに開催している教室で使用している教材記事の一覧です。 qiita.com qiita.com qiita.com qiita.com qiita.com qiita.com qiita.com qiita.com 今回はその活動を知ってくれていた人事部の方からお声がけいただき、かぞく参観日のプログラミング体験教室の講師を引き受けることになりました! プログラミング体験教室の教材テキストについて 前職で講師を務めていましたが、研修のカリキュラムや、研修で使用する教材テキストの開発などには関わっていなかったので、1から自分で内容を検討するところから始めました。 その際に大事にしたことは プログラミングを楽しいと思ってもらえること プログラミングの基本である、逐次・反復・分岐を詳細に説明することなく理解してもらうこと シンプルな動作を行うパーツを組み合わせて、少し複雑な動作を行うことができることを理解してもらうこと の3つです。 これら3つの要素を意識して作成した教材テキストをQiitaにて公開しています。 qiita.com qiita.com 体験教室当日は プログラミング体験~Scratchでプログラミング入門~ひらがな多め版 の記事をZoomで共有しながら実際にプログラミング体験をしてもらいました! ひらがな多め版を作った背景ですが、下記のような要件がありました。 今回の体験教室の対象年齢を小学校3年生以上としていた 体験教室が終わった後も復習で使えるように、お子様が読める文字で教材を作っておきたかった 事前準備で教材とは別の資料を試しに全文ひらがなで作ってみたところ、とても読みづらい資料になった よって全てをひらがなにするのではなく、小学校3年生までに習っている漢字を残して、習っていない漢字をひらがなにしたかった 習っていない漢字を調べるのは大変なので、事前準備を手伝ってくれたメンバーがテキストをペーストすると、小学校3年生までに習っていない漢字を赤字で表示してくれるWebツールを見つけてくれました。 正直このツールがなかったら全文ひらがなか、そのまま漢字を残した原文のままかのどちらかにしていたと思うので、このような便利なツールを見つけてくれたメンバーとこのWebツールを作ってくれた作者さんに感謝します! ※このツールを使ってみたい方は検索エンジンで「習っている漢字」などのキーワードで検索してもらえると見つかると思います! プログラミング体験教室のカリキュラムについて テキストの次はカリキュラムですが、教室の枠が1時間だったので、1時間でチュートリアルから演習問題作成までを行ってもらうことを考慮して設計しました。 概要説明・・・10分 概要説明で使用したスライドの大まかな内容です。 下記に加え、お子様向けにイラスト多めのスライドを作成していただきました。 プログラムとは? プログラムとは、コンピュータで動かしたいモノの「動きのじゅんばん」や「どうやって動かしたいか」を文字で書いて、コンピュータがその文字を読んで動かしているよ! どうぶつの森で、虫をつかまえたり、魚つりをしたりするのもプログラム! ポケモンGOで、モンスターボールをなげるのもプログラム! パパ・ママが作っているLIFULL HOME'Sで、おうちをさがすのもプログラム! プログラムってどうやって作るの? コンピュータで動かしたいモノの「動きのじゅんばん」や「どうやって動かしたいか」を文字で書いて作っていくよ! その他にも、今日みんなでいっしょにたいけんする「スクラッチ」のように、図形を組み合わせて動かしていく作りかたもあるよ! プログラムを作る人のことを、「プログラマー」とか「ソフトエンジニア」と呼ぶよ(よびかたは他にもたくさん!) みんなが大人になってはたらく時には、もしかしたらプログラムの作り方はかわっているかもしれないよ…! プログラマーってどんなお仕事なの? コンピュータで動かしたいモノの「動きのじゅんばん」や「どうやって動かしたいか」を文字でたくさん書いてプログラムを作るお仕事だよ! いきなりたくさんの文字を書くと、まちがえてしまうこともあるので…システムの全体図とか流れ図を作ったりするよ! 「動きのじゅんばん」や「どんな動きにするか」イメージがついたらたくさん文字を書いていくよ! 「動きのじゅんばん」や、「文字で書いた動き」が正しく動いているかチェックするよ! プログラマーって楽しいの? たいへんなこともあるけど、楽しいことの方が多いよ! 自分で作ったプログラムが家族や友だちに使ってもらえるとうれしいよ! 「べんりだね!」とかんしゃされることもあってとてもうれしいよ! プログラマーに向いている人ってどんな人? こんな人がむいているよ!あてはまらない人でもプログラマーになりたいって思ってちゃんと勉強すれば、だれでもなれるよ! 新しいゲームがでたらすぐにほしいって思う人 算数がすきな人 図工の時間にモノづくりするのがすきな人 ゲームを自分で作ってみたい人 きょうやること 「スクラッチ」っていう、プログラムをかんたんに作れるソフトを使って、プログラムを作ってみるよ! どうやったら音がなるかな?どうやったらキャラが動くのかな?みんなで考えてみよう! これでみんなもプログラマーデビューだ! Scratchチュートリアル・・・15分 プログラミング体験~Scratchでプログラミング入門~ひらがな多め版 の ねこを歩かせてみよう の旗を押して猫を歩かせるところまでをZoomで画面を共有しながら操作方法の説明を行いました。 演習時間・・・20分 参加してくれたお子様の親御さんのサポートのもと、教材テキストの流れに沿いながら演習問題を解いてもらいました。 演習問題発表会・・・10分 作成した演習問題を発表してもらいました。 演習問題解答例解説・・・5分 解答例の簡単な解説を行いました。 実際に事前に設計したカリキュラムの時間割とは少し違ってしまったのですが、当日の流れを見て、概ね上記のような流れで実施しました。 実施してみて 事前リハーサルで小学校一年生のお子様がいらっしゃる方に協力してもらい教材テキストの流れを一通り実施してみたところ、下記のフィードバックを得ることができました。 チュートリアルはあまり説明しすぎるとお子様が飽きてしまうので、操作方法などの概要を教えた後は、お子様に自由に操作してもらった方が良い。 演習問題の枠にあまりとらわれず、直感的に思いついたことをお子様にやってもらった方が良い。 マウスの操作方法など、PCの基本操作がわからないので、その辺りの操作方法からサポートしてもらえると良い。 これらを踏まえ、当日実施してみたところ、どのお子様もみな真剣な表情で演習問題に取り組んでくれていました。 演習時間は少しもくもくとやる雰囲気になってしまったので、もう少し皆でワイワイできるような雰囲気づくりを講師としてできれば良かったなと思いました。 発表会はマストにするのではなく、「皆に共有したい人ー発表してくださーい」、くらいのライトな感じにする方が良いと思いました。こだわりの作品を作成途中で無理やり発表させてしまうことは本意ではなく、またこの教室の目的はあくまでプログラミングを「楽しんでもらう」ことだったので、この辺りの配慮が欠けていたなと反省しています。 まとめ お子様向けのプログラミング体験教室を実施してみて、新入社員向けのプログラミング研修とはまったく別の観点や配慮が必要だということに気づくことができ、個人的には非常に多くのことを学べた、良い機会でした。 今回実施してみての一番の収穫は「お子様の発想力は大人を凌駕することがある」ということでした。 演習問題などの枠組みを用意してあげることも重要ですが、その枠から自由にはみ出てもらい、自由に作ってもらうことで運営側が想像もしない成果物を作ってくれるということを知れたのはとても良かったです。 教える側の想像を超えてくるものを見ることができるのはお子様向けプログラミング体験教室の醍醐味であり、教える側にとってもより教える楽しさを味わうことができるので、また教室を開催したいなと思えました! カリキュラムや教材テキストを作る側の苦労も体験することができ、今までは研修を実施するだけだったので、また一歩レベルアップできたかなと思います。 とはいえ、まだまだカリキュラムや教材テキストに関しては素人だと思いますので、色々な先人達の例を参考にしながら、自分なりのカリキュラムや教材テキストをもっと高いレベルで作成できるようになっていきたいと思います! 2020年からプログラミング教育が小学校で必修化され、今後ますます関心が高まっていく分野と思いますので、今後教材開発やカリキュラム作成に携わる方々の参考にしてもらえれば幸いです。 最後に、今回のプログラミング体験教室開催にあたりご協力いただいた方々、お忙しい中スライド作成やリハーサルなどにご協力いただきありがとうございました! 私一人では到底実施することはできず、チームの力で実施することができた、とても良い教室でした! 以上となります。 最後までご覧いただき、ありがとうございました。
こんにちは! 株式会社LIFULLで LIFULL HOME'Sアプリ Android開発チームの衛藤です! Android開発チームでは、不動産業界の不を解消すべく、これまでに最新テクノロジーを率先しプロダクトに反映し続けてきました。 現在のアプリバージョンはv12.12.0(ブログ執筆時点)となっており、12回ものメジャーバージョンアップを重ねてきたのかと思うと感慨深いものがあります! 私がLIFULLにジョインしたのは2014年7月。それまで存在していたアプリをフルリニューアルし、新たなv1.0.0として開発をしている最中のことでした。 中途採用のためAndroidの開発知識は少しはあったものの、内製開発自体は初めての体験だったため、チーム開発を含め非常に新鮮だったことを今でも思い出します。 さて、今回の記事はその6年間でLIFULL HOME'S Androidアプリがどのような変遷を遂げてきたかについて紹介しようと思います! 仕事の箸休めタイムにでも、リラックスして眺めて頂けると嬉しいです! LIFULL HOME'S AndroidアプリUI・UXの変遷 画面別に紹介 トップ画面 まずは起動時のトップ画面の変遷です。v1系からv12系になるまでの間、約4回のUI変更が行われています。 v1.0.0では、完全リニューアル版として新規リリースされました。ToolbarやNavigation Drawerが導入され、より使いやすくなったアプリとして生まれ変わりました。 トップ画面はしばらくこの状態が続き、v4.0.0でマテリアルデザインが導入されることで、より洗練されたUXとなりました。 v4.6.0では「特集」という、検索条件が予め設定されたテーマを検索できる機能が追加されました。 v4.8.0では、特集がタブ化され、ここで初めてBottomNavigationが導入されています。 さらにv4.10.0では、タブが廃止され、特集がトップ画面上部のエリアに大きく配置換えされました。この上部のエリアは、Firebase RemoteConfig + ReatimeDatabaseにより動的に変更可能な領域となっており、季節要因やその他状況に応じて柔軟に特集を出し分けることが可能となっています。 仕組みについては、以前iOSメンバーがイベントで登壇した資料があげられています。 LIFULL HOME'S Firebaseによる特集配信 from 庸介 高橋 www.slideshare.net 現在の最新バージョンv12系では一気にリニューアルされ、トップ画面が2つに別れています(後述のホーム画面)。 物件一覧画面 物件の一覧画面はそこまで大きく変更はされていませんが、細々とUI変更や便利機能が追加になっています。 特に、v5.5.0では掲載物件の間取り図が表示されるようになり、より視覚的にイメージしやすくなっています。 その他にも、物件一覧画面から物件をお気に入り登録する、といったことも可能になっています。 ※ 実在する物件にはモザイクをかけています。ご了承ください。 物件詳細画面 続いて物件の詳細画面です。上部に画像、そこから物件の詳細情報が続く画面設計は変わっていませんが、細かい機能追加がされてきました。 v5.1.0では物件パノラマ機能が追加になり、物件の部屋内部を360度パノラマで閲覧できるようになっています。 この「物件パノラマ」は私自ら機能提案を行いリリースまで行った初めてのプロジェクトとなりました。 その他にも、ストリートビューや初期費用概算(賃貸のみ)といった機能も追加されています。 その他のUI/UX変遷 やることリスト v4系では、「やることリスト」がリリースされました。 面倒な物件探しや入居前にやること、独自のマイタスク追加などチェック形式で整理することが可能な機能です。 優等列車情報 v5.1.0では路線・駅選択画面に「優等列車・始発駅」表示機能が追加になりました。 この機能は、私が家探しをする過程で不便と感じたことがきっかけで機能を提案し、プロジェクト化が決まりました。 またこのプロジェクトについては、エンジニアリングのみではなく企画立案から経験してみたいと上司に打診し、仕様策定・効果測定・APP実装・バックエンド実装含めてすべて一人で完遂したプロジェクトとなりました。 かざして検索 v8.0.0では、新しい検索体験である「かざして検索」がリリースされました。 時期としては2018年で、AI・機械学習がより実践的に各企業に取り入れられるようになったあたりでしょうか。LIFULLでもいち早く導入を行いました。かざして検索は、端末のカメラで建物をかざすと空き部屋情報が確認できるといった、これまでとは全く違う検索体験を実現しました。 初期の実装当時は独自で認識モデルを構築したのですが、その後2019年にML KitでもObject Detection and Trackingが発表され、早速アプリで対応させ、またMaterial Design for Machine Learningを導入しUXも大きく変更しています。スピード感をもって取り入れたことにより、Google I/O Extendedにて事例として紹介されました。 (42分14秒あたり) www.youtube.com それ以外にも各Webメディアやテレビにも取り上げられ、話題を呼んだ新機能となりました。 地図検索 v9.0.0では待望の「地図検索」が登場しました。 これまでは路線・駅・地域を指定することのみ可能でしたが、このバージョンからは地図上から物件を探すことが可能になりました。 自分の住みたい地域を表示し、場所を確認しながら物件を探せるため、より直感的に操作できるようになっています。 また、地図上で範囲を指定する「お絵かき検索」や気になる場所からの徒歩・車での所要時間とともに検索できる機能もあるため、好みの条件に応じて柔軟に検索することが出来るようになりました。 AIによる賃貸物件の提案機能 アプリで2つ目の機械学習機能のリリースで「AIによる賃貸物件の提案機能」というものがリリースされました。 過去に閲覧した物件をもとに、おすすめ物件をAIが提案する機能となります。 この機能はLIFULLのAI専属チームが開発した機械学習モデルを利用し、それをアプリに組み込んだプロジェクトとなります。 Instant Apps Google I/O 2016にて、「Instant Apps」が発表されました。ユーザーがアプリをインストールせずに、一時的にアプリの一部をダウンロードし利用できる機能です。 発表後、早速社内で取り組みを開始し、アプリのモジュール構成を刷新してInstant Apps対応を行いました。 機能としては、以下の2つに絞られています。 特集から物件の一覧が検索できる機能 物件の詳細が閲覧できる機能 ストアの「今すぐ試す」から起動することや、URIから直接物件の詳細画面を立ち上げる(アプリをインストールしていなくても)といったことが可能になりました。 また、アプリインストール動線を設置し、インストール後にInstant Appsで使っていた検索条件やお気に入り物件等を引き継いで利用することも可能になっています。 物件問合せ機能をネイティブ実装へ 気になった物件や内見したい物件に問合せを行う機能がありますが、もともとはWebのスマートフォンページを表示していました。v9.0.0の頃のスクリーンショットは、Webのスマートフォン用ページです。 物件の問合せ自体は問題ありませんが、Webページのためどうしても読み込み速度や操作感がネイティブアプリと比べて劣ってしまいます。 そこで、バックエンドAPIから準備し、ネイティブ実装として開発がスタートしました。 v10系でリリースを行い、そこから細々とUIをチューニングし、現行版(v12系)で落ち着いています。 UIとしてはほんの数画面のみですが、住まいを探しているユーザーと物件をマッチングする重要な機能のため、かなりの期間をかけて完成まで導いたプロジェクトとなりました。 ダークテーマ 業界に先駆けてダークテーマを導入しました。 この機能についてもエンジニア提案によるもので、同じく企画立案・効果測定含めてエンジニアが作り上げたものです。 Google Play Developersにも取り上げられ、注目が集まりました。 developer.android.com マイページからホーム画面へ v1.0.0の頃から存在した機能に「マイページ」というものがあります。検索履歴やお気に入り物件、保存した検索条件などをまとめた機能です。このマイページについても細かくUIアップデートを重ねていました。 既述の「AIによる賃貸物件の提案機能」もかつてはマイページに存在していました。 しかし、よりパーソナライズ化した機能を目指し、v12.0.0からは「ホーム」画面に移り変わりました。 UIも大きく変わり、機能的にもよりユーザーに寄り添ったコンテンツが表示されるように生まれ変わっています。 これまでの取り組みについては、2020年末にGoogle Developers JapanのYoutubeでも取り上げられました。 www.youtube.com まとめ 以上、過去6年間のLIFULL HOME'S Androidアプリ UI/UXの変遷を振り返ってみました。 v1.0.0の頃のUIからすると、かなりモダンに生まれ変わり、便利な機能もたくさん追加されました。 完全内製開発という強みを活かし、職種関係なく細かい機能提案や議論が盛んにされ、それが受け入れられる社風であることがここまでの変遷を可能にしてきたのではないかと感じています。 Androidは年々OSがアップデートされ、新たに利用できる技術が続々と登場してくる変化の激しい世界です。 新技術をいち早く取り入れ、より便利に利用できるプロダクトを世の中にリリースすることが重要です。 技術をキャッチアップし続ける必要はありますが、より良いプロダクトへと繋がる技術を提案し、自発的に導入できるのはエンジニアとしても楽しく働ける環境であることは間違いありません。 これからも、住まい・暮らしに寄り添い、便利にサービスを利用して頂けるよう、チームメンバー一丸となりプロダクトを発展させていきます。 最後まで読んで頂き、ありがとうございました! 時間があれば、ご自身で携わられているサービスの変遷を振り返ってみてはいかがでしょうか! 最後に LIFULLでは、そんなプロダクトを一緒に盛り上げて頂ける仲間を募集しています! ご興味がある方、ぜひ以下の応募フォームよりエントリーくださいませ!! hrmos.co 「面接までは考えてないけど、社風や事業内容聞いてみたい…」という方向けに、カジュアル面談も実施しています(採用合否には関係ありません)。 カジュアル面談は以下からご応募ください! hrmos.co
こんにちは。LIFULL でネイティブアプリのスペシャリストをしている菊地です。 普段は LIFULL HOME'S アプリ(iOS, Android)の開発チームで Tech Lead をしています。 2020年12月3日(木)、4日(金)に開催された Google Developers ML Summit に BigQuery で実現するユーザーの傾向に合わせたレコメンドシステム というセッションで登壇させていただきました。 cloudonair.withgoogle.com 当日はまさかのトップバッターということもあり、ライブ Q&A でどういった質問が来るか?そもそも質問くるのか!?という緊張感が凄かったです。 ここでは時間の都合でセッションの中で回答できなかったことや、もう少し詳しいお話を書かせていただければと思います。 Google Developers ML Summit とは Google Developers ML Summit は年に一度、Google Cloud 主催で ML(Machine Learning) に関する技術・事例の紹介などを行うために様々な開発者が一同に集まるイベントになります。 データサイエンティスト、アプリケーション開発者向けに、最新の Google Cloud AI や、機械学習サービスの活用例の紹介。 TensorFlow、Cloud AI などの活用事例、機械学習モデルの開発や利用、データサイエンティスト/機械学習エンジニアを繋げるプラットフォーム「Kaggle」の紹介 公式サイトより 講演資料は こちら で公開されています セッション内容 今回、登壇させていただいたセッションは、 BigQuery で実現するユーザーの傾向に合わせたレコメンドシステム になります。 内容としては、LIFULL HOME'S の Android アプリに実装した 「お気に入り傾向が似ているほかのユーザーがお気に入りに入れている物件をレコメンドする」 機能について、開発のきっかけや、どのようなものを比較・検討したうえで実現したか?というものを発表しております。 ※ こちらもチェック!好みが近い人が閲覧した物件 と表示されている部分が今回実装したものになります。 開発する際の課題と解決 開発する際に課題として上がってきた項目は主に下記の3つになります。 1. レコメンドに必要な学習データをどう集めるか? レコメンドを行うためには学習データとしてユーザーの行動を集める必要があります。 今回は、Firebase Analytics を既に導入していたため、「物件をお気に入りに追加した」というイベントを計測し、Firebase にある BigQuery Export を利用することで実現しました。 2. レコメンドエンジンをどのように構築するか? レコメンドエンジンの実現には、GCP では様々な方法で実現することができます。 検討した方法 Recommendations AI BigQuery ML Cloud Data Proc AI Platform 選択したもの 元々の選択肢にはなかった BigQuery による協調フィルタリング を選択しました。 ※ 詳細についてはぜひセッションまたはスライドをご覧いただければと思います。 3. レコメンド結果をアプリからどうやって利用するか? レコメンドエンジンが抽出したレコメンド結果をアプリから利用するためにどこに置くか?について検討する必要がありました。 アプリから呼び出せる API を作って BigQuery を直接読み取る、別で DB を用意するなど様々なものが考えられます。 今回は、Firestore にユーザー毎の Document が存在していたことから Document 配下に直接書き込む事で、アプリからの直接参照も行えるなどメリットがあったため、Firestore を選択することにしました。 構成図 今回、最終的に構築されたレコメンドシステムのアーキテクチャはこちらの図のようになります。 レコメンドシステム全体の処理としては下記のような3つで構成されております。 アプリから「物件をお気に入りに追加した」というイベントを Firebase Analytics で取得し、BigQuery Export を用いて BigQuery にデータをためる Cloud Scheduler で毎日一度起動する Cloud Functions(Pub/Sub 経由) が BigQuery に対してクエリで協調フィルタリングを行い、抽出結果を Firestore に格納する アプリから Firestore に対して、ユーザー毎の Document にアクセスし、3 で生成された抽出結果(レコメンド結果)を取得する 開発秘話(裏話) 開発のきっかけ LIFULL HOME'S アプリの開発チームでは、普段からこういう機能を提供できないか?こんなことをしたら楽しんでもらえないか?という話をかなりの頻度で話しています。 これはそういうことを話す時間を設けているわけではなく、 ただの雑談 でそういう話をすることがあり、雑談が盛り上がってそのまま開発までしてしまうことがあります。 今回の不動産物件レコメンドシステムについては、 アプリ内でユーザーの行動に合わせたレコメンドって少ないよね? 好みとかに合わせたものってないかも? というところから始まり、 ECなどでよく見る "この商品をお気に入りに入れた人はこちらもお気に入りに入れています" みたいなのが提供できるといいかも! と盛り上がっていったことがきっかけになります。 盛り上がった後には、ちゃんと既に提供しているレコメンドとの違いや、このレコメンドで提供できる価値があるか?というところも話した上で検討が始まりました。 開発までにかかった日数 今回、調査や検討にはかなりの時間がかかりました。 というのも 雑談から始まったプロジェクト であること、 最初はチーム全体ではなく数名 で盛り上がって調べていた、ということが挙げられます。 設計や調査に時間をかけたこともあり、一番時間がかかったのはアプリでどう見せるか?という企画面になります。 全体を通しては実際に開発することが決まってからリリースまでには一ヶ月もかからず開発することができました。 iOS アプリとの相性 今回、LIFULL HOME'S の Android アプリで開発を行いましたが、開発したレコメンドシステムは、すべてバックエンド側のため iOS アプリでも利用が可能です。 いつ頃リリースされるか?まったく同じ内容でリリースされるか?ということは決まっておりませんが、それぞれのプラットフォームのユーザーの特性やアプリの体験に合わせた形で再利用して活用できればと考えています。 AWS や Azure ではなく GCP で開発した理由 LIFULL HOME'S アプリでは、以前から Firebase を導入しています。またマイクロサービスとして AWS、GCP の両方を使い分けています。 そのため、AWS か GCP のどちらかでの開発を行うというのが決まった状態でスタートしました。 最終的には、レコメンドエンジンの中核となる BigQuery に合わせたというのがありますが、Cloud Functions のトリガーによる Firebase の拡張が豊富なこと、既に構築しているアプリ向けプッシュ通知のシステムを GCP で構築していたため、より手軽に開発ができるということで GCP を選択しました。 予算のお話 セッション中に何度も「費用感が・・・」といった形で何度も予算の話を出しておりました。 今回のプロジェクトは元々予算がなく、他のプロジェクトの予算を削減してこちらに回すという形で捻出しました。 費用をかければもっと手軽にレコメンドシステムを実現することは可能ですが、それぞれの構成案の費用間やメリット・デメリットを知っておくことは今後のためにもなると考え、徹底的に費用に拘ってレコメンドを実現する手段を探すことにしました。 人件費なども考えると普通に BigQuery ML などで構築した方が・・・という場合もありますが、同じようなことを検討されている方々でそれぞれの環境に合わせてどうやって実現していくか?ということを考える際の参考になれば幸いです。 データサイエンティストとの関わり方 今回は、レコメンドエンジンの核となる BigQuery で協調フィルタリングを行う部分について、データサイエンティストに相談に乗っていただきました。 BigQuery で協調フィルタリングでがきることはわかっていましたが、実際にクエリを書くとなるとアプリチームのスキルだけでは時間がかかってしまいます。 そのため、普段から BigQuery なども使いこなしているプロに相談しようとなり、弊社のデータサイエンティストにこういうことをやりたいんですけどと相談したところ、数時間後には試験的なクエリを提供していただき開発を一気に進めることができました。 まとめ 今回、Google Developers ML Summit で発表させていただいた BigQuery で実現するユーザーの傾向に合わせたレコメンドシステム についてご紹介させていただきました。 こちらで紹介させていただいたレコメンドは、LIFULL HOME'S Android アプリ内にてご利用いただけます!! ※ レビューいただいたコメントは中の人が見て返信してますので、ぜひアプリの使い勝手やご意見などを気軽にコメントいただけると嬉しいです!いただいたコメントはアプリの改善にも活かしていきます! play.google.com セッションの中でも触れましたが、個人的には BigQuery ML を試したいという思いはあったのですが、お金という現実と向き合って"やりたいことをどう実現するか?"と"費用という問題とどう戦っていくか?"というところについてこだわって進めたプロジェクトになります。 今回の内容がレコメンドを作ってみたいと考えている方の参考になれば幸いです。それぞれの構成の詳細についてはセッションスライドに記載があるので、ぜひご覧ください。 LIFULLではメンバーを募集しております! カジュアル面談もありますのでご興味ある方は是非ご参加ください! hrmos.co