サービス開発におけるアプリデザイナーの役割について

投稿開発部デザイナーの辻(@cooktsuji)です。

去る10月26日、「Cookpad Tech Kitchen#3 サービス開発におけるアプリデザイナーの役割」と題して、デザイナー向けのイベントを行いました

このイベントでは、「クックパッド」「トクバイ」のiOS/Androidアプリサービス開発において、デザイナーの役割や大切にしていることをテーマに、4名のデザイナーが発表をしました。

この記事では、その様子についてお伝えします。 尚、今回のイベントでの発表資料は公開を予定しておりません。

登壇者発表

デザイナーの組織の話について

まず、VP of Product Design 兼 投稿開発部長の池田(id:tikeda)から、クックパッドのデザイナー組織について発表しました。

ここでは、

  • クックパッドには、多種多様なデザイナーがいること
  • 横串と縦串を意識したデザイナーの組織編成
  • デザイナーとしての目標や評価軸について
  • プロダクトオーナー思考について

などを紹介しました。

デザイナー組織の体制については以下の記事で解説しているので、是非一読下さい。

毎日の料理のためのアプリデザインの毎日

次に、検索事業部のデザイナー倉光から、クックパッドのアプリ開発で取り組んでいる開発フローやプロトタイプを事例と共に発表しました。 f:id:tomoya-tsuji:20161102145541j:plain ユーザーインタビューやGitHubを利用したデザインレビュー、アプリエンジニアがデザインを提案するなどの工夫についていくつか紹介しました。 GitHubを利用した開発やプロトタイプを作り、開発を行っていくフローに関して、当技術ブログにいくつか記事がありますので、ご興味ある方はあわせてご覧ください。

楽しい買物を増やすためのデザイン

次に、株式会社トクバイのデザイナー吉井より、トクバイアプリの開発フローと知見について紹介しました。 f:id:tomoya-tsuji:20161102145555j:plain

この発表では

  • トクバイアプリ開発がどのように行われているか
  • 理想の形への到達プロセス
  • レビューの改善

などについての概略を紹介しました。 トクバイのアプリ開発については以下の記事でも解説しています。

複数プラットフォームで新機能を開発時に苦労したこと

最後に、投稿開発部デザイナー若月(@puzzeljp)より、iOSアプリで新しくリリースした「限定公開レシピ」の開発時に気をつけたことや苦労したことについて発表しました。 f:id:tomoya-tsuji:20161102145603j:plain プラットフォームごとに異なる機能を整理するために表を作って可視化し、共有したり、実装後のデザイン修正によるスケジュールの遅延時の対応などをお話しました。

プラットフォームに応じたデザインに関しては以下の記事でも紹介しています。

QAセッション

上記4名の発表の後、パネルディスカッション形式のQAセッションを行いました。 当日、参加者の皆様から沢山の質問をいただきました!

ここでは、当日時間がなくお答えできなかった質問から3つ選んで回答します。

f:id:tomoya-tsuji:20161102145437j:plain

Q:実装されたものとデザインとの差異が合った場合、どうやってエンジニアさんにフィードバックしていますか?

A:差異が合った場合、デザインの修正を行って Zeplin でエンジニアさんに共有して修正してもらうことが多いですが、最近では Xcode の Interface Builder を触ってデザインの確認・変更の一通りをやり、エンジニアさんには PR で確認してもらいなるべくやり取りを少なくなるよう努力しています。(投稿開発部・若月)

Q:ユーザーインタビューの頻度・実施のタイミングや関わるメンバー(役割分担)や人数などを教えてください。

A:実施タイミングは「特定の施策について、利用状況をユーザーさんの背後の生活環境も含めて聞きたいとき」です(参考までに、検索事業部では2016年10月は2名に実施)。インタビューユーザーの探し方ですが、クックパッドに会員登録されている方々の中で対象ユーザーとして条件の近しい方にまずはメールでお声がけしています。 インタビューに中心的に関わるメンバーは2名程度ですが、インタビュー結果はドキュメントにまとめ次第、すぐに開発チーム全体に共有されます。(検索事業部・倉光)

Q:デザイナーが少ない中でもうまく回す工夫などありますか?

A:自分がやるべき範囲を見極めることを意識しています。 トクバイでは隔週ごとに約1ヶ月先までの大枠の開発計画を立てているので、 そこでサービスの全体感やエンジニアの先の動きを見て、 デザイナーとしてどう動くべきかを早めに掴むようにしています。 また、デザイナーのコストをどこにかけるのかの判断も重要ですね。 細かい部分は直接のデザイン指示やレビューで賄うなど、 手が足りない範囲をコミュニケーションでカバーすることも必要だと思います。 (トクバイ・吉井)

懇親会

上記セッションの後、懇親会を行いました。

懇親会では、他の弊社デザイナー、エンジニアも参加しながら、参加者と様々な意見交換や談話をしました。 f:id:tomoya-tsuji:20161102145655j:plain

多くの皆様にご参加いただけたおかげで、より深掘りした話をしたり、各社のアプリ開発の知見を共有するなど、活発な情報交換が行えたと思います。

また、今回はハロウィンが近かったので、ハロウィンをテーマにした料理も振る舞われました。 f:id:tomoya-tsuji:20161102145710j:plain

まとめ

いかがでしたでしょうか。

この他のデザイナーの取り組み事例は、こちらのデザイン記事一覧をご覧ください。 クックパッドでは、今後もデザイナー向けのイベントを行っていきたいと考えています。

一緒にサービス開発を行っていくデザイナーも募集しています。 ご興味のある方は是非!ご応募お待ちしております。

【学生限定】夜の合同説明会を開催します【クックパッドxドワンゴxグリーxはてな】

将来に悩んでいる学生のみなさん、こんばんは。成田(@mirakui)です。

11/18(金)に、ドワンゴさん、グリーさん、はてなさん、そしてクックパッドという4社の合同で「夜の合同説明会」を開催することになりました。

エンジニア志望の学生さんに向けたパネルセッションなのですが、普通とは違った趣向ですので、この4社に興味がある方はぜひご参加ください。

お申込みは下記の connpass からお願いします。

夜の合同説明会 - クックパッド, ドワンゴ, グリー, はてな - connpass

以下、このイベントがどうすごいのか説明します。

パネリストが豪華

私を始め、各社のトップエンジニアが一同に介します。このメンバーが一箇所に揃うのはめったにない機会だと思います。レジェンドの皆さんの前に私も緊張しています。

  • 司会
    • 庄司嘉織 (クックパッド株式会社 人事部長/エンジニア) @yoshiori
  • パネリスト
    • 藤本真樹 (グリー株式会社 取締役 執行役員常務 最高技術責任者) @masaki_fujimoto
    • 大西康裕 (株式会社はてな 執行役員 サービス・システム開発本部長) @yasuhiro_onishi
    • 成田一生 (クックパッド株式会社 VP of Engineering) @mirakui
    • 清水俊博 (株式会社ドワンゴ 人事部長/エンジニア) @meso

全員飲んでいる

登壇時、パネリストは皆お酒を飲んでいます。お酒を交えながら本音で語り合うイベントというのが今回の趣旨です。

その場でしか聞くことができないぶっちゃけトークが飛び出す可能性が高いです。私は色んな意味で緊張しています。

※参加者のみなさまにもお酒を振る舞うため、20歳以上限定とさせてください

気軽に質問を投げられる

申し込み時に質問を書くところがあるので、偉い人が酔っ払っていれば答えてくれるかも? というギリギリを考えて攻めてみてください。

なにが飛び出るかわかりませんが、パネリスト一同みな覚悟して望んでいます。この業界に興味のある学生の皆さんは、この機会にぜひお越しください。

お申込みはお早めにこちらまで!

夜の合同説明会 - クックパッド, ドワンゴ, グリー, はてな - connpass

非SPAなサービスにReactを導入する

投稿開発部の外村(@hokaccha)です。今回はReactについてのお話です。

ReactとSPA

最近JavaScriptやそれを取り巻くフレームワークなどの話題では、サーバ側はAPIのみを提供し、View(HTML)は全てJavaScriptで描画するような、いわゆるシングルページアプリケーション(以下SPA)についてよく語られます。

一方で、SPAを構築するにはコストがかかることも事実で、特にフロントエンドエンジニアが多くない環境では、従来通りサーバーサイドでViewを書きつつ動的な部分だけJavaScriptで処理するというアーキテクチャのほうが現実的な場合も往々にしてあります。

今回はこのような、サーバー側でHTMLを生成し、一部の動的な部分だけをReactで書くためのTipsを紹介します。

なお、基本的にサーバーサイドはRails前提ですが、RailsにおけるReactの開発環境の構築方法などについて以下の記事や資料を参照ください。

コンポーネントの例

例えばブログ記事に「いいね」が押せる機能を考えてみましょう。機能としては

  • いいねできる
  • いいねが解除できる
  • 自分がいいねしているかどうかわかる
  • いいねしているユーザー数が見れる
  • いいねユーザーの一覧がポップアップで見れる
  • ユーザー一覧は20件ごとに読み込む
  • いいね押したときにログインしてなければログインの誘導ポップアップが出る

このように、小さいコンポーネントではありますが、複数の状態や機能があり、いいねの付け外しやユーザー一覧の取得はAjaxで行う必要があります。

テンプレートをhamlやerbで書いてjQueryでDOM操作をして実現することもできそうですが、このような機能をjQueryだけでメンテナブルなコードを書くのは簡単ではないと思っています。一方Reactは宣言的で見通しのよいコードでコンポーネントを記述でき、Viewの機能のみを提供するという単機能なライブラリのため、こういった部分的に利用するケースでも導入しやいです*1

また私自身、これと同じような機能をjQueryとReactの両方で実装した経験がありますが、例えこのぐらい小さい機能であってもReactのほうが楽に実装できると感じました。サーバー側のテンプレート言語とReact側のJSXとでテンプレートの言語が分かれてしまうというデメリットはありますが、個人的にはそこを差し引いてもメリットのほうが大きいと思っています。

react-railsを使った自動マウント

このようにReactを動的なコンポーネントだけに使っていくという手法の場合、面倒なのがReactコンポーネントのマウントです。SPAの場合は基本的にルートコンポーネント一つをマウントすれば済みますが、こういった構成の場合は1ページに複数のコンポーネントをマウントするケースが多くなります。

例えばブログ記事のページで、いいねとコメントの2つの動的なコンポーネントがあるとします。まずはテンプレートを次のようにして

<h1><%= @entry.title %></h1>
<%= @entry.body %>

<div class="like-component"></div>
<div class="comment-component"></div>

JavaScript側で対象のDOM要素に作成したReactコンポーネントをマウントします。

document.addEventListener('DOMContentLoaded', () => {
  let like = document.querySelector('like-component');
  let comment = document.querySelector('comment-component');

  ReactDOM.render(React.createElement(LikeComponent), like);
  ReactDOM.render(React.createElement(CommentComponent), comment);
});

2つくらいであればこれでもいいですが、コンポーネントを作る度にこのようなコードを書かないといけないのは面倒です。また、コンポーネントの初期値としてpropsを与えたいというケースも出てくるでしょう。

そこでRailsの場合はreact-railsを使うのがオススメです。react-railsにはサーバーサイドレンダリングなどの興味深い機能もありますが、今回はview helperとreact_ujsを使った自動マウントの機能を紹介します。

先程の例はreact-railsを使うと次のように書くことができます。

<h1><%= @entry.title %></h1>
<%= @entry.body %>

<%= react_component('LikeComponent') %>
<%= react_component('CommentComponent') %>

JavaScript側ではreact_ujsを読み込んでおき、コンポーネントをグローバルから参照できるようにしておくだけで自動的にコンポーネントがマウントされます。

また、引数でpropsを渡すこともできます。

<%= react_component('LikeComponent', liked: @current_user.liked?(@entry), likeCount: @entry.likes.count) %>

このようにすることでLikeComponentに初期値をpropsとして渡すことができ、Ajaxで通信せずとも初期描画を行うことができます。

また、react_ujsの自動マウントはturbolinksにも対応しており、turbolinksでページ遷移したときに自動でマウント・アンマウントを行ってくれるという機能があります。jQuery時代にturbolinksを使って$(document).ready()が走らなくてハマる、という経験されたことがある方には嬉しいかもしれません。

Railsを使わない場合や、それだけのためにreact-railsを使いたくない場合は同じような仕組みを実現するのは大した手間ではないので自作してもいいと思いますが、1ページに複数コンポーネントをマウントする場合は、何かしらこのような自動マウントの仕組みがあると便利です。

react-micro-container

Reactではルートコンポーネントが全ての状態を管理し、子のコンポーネントにはpropsとして値を渡すようにすることで、できるだけコンポーネントから状態を取り除くというプラクティスがあります。このとき子要素で発生したイベントをルートコンポーネントに伝える手段が必要になります。

愚直にやるとイベントハンドラを子要素に渡し、全てのコンポーネントでイベントを拾って一つ上の親にあげていくという処理が必要になります。例えば、いいねコンポーネントで、「いいね」や「もっと見る」を押したときのイベントをルートコンポーネントまで伝えるのは次のようなイメージです*2

f:id:hokaccha:20161026134922p:plain

これがいわゆるイベントのバケツリレーです。今回のような小さいコンポーネントの場合も、内部でコンポーネントを分割していくと容易に数段のネストしたコンポーネントになります。

何かしらのFluxフレームワークを使ってもよいですが、こういった小さいコンポーネントにFluxフレームワークはオーバースペックなことも多いです。そこで拙作ですが、react-micro-containerという小さいライブラリを使うと、イベントのバケツリレーだけを簡略することができます。

f:id:hokaccha:20161026134928p:plain

個人的には小さいコンポーネントではこれぐらいで十分なケースも多いと思っています。詳しい使い方などはこちらの記事を参照してみてください。

小さいReactアプリケーションのためのライブラリ書いた - Qiita

注意点として、これは小さいコンポーネントであればうまくいきますが、規模が大きくなってくるとイベントの数が多くなりすぎて破綻してくるので、そういった場合はFluxフレームワークを導入するなどの対応が必要になるかもしれません。

まとめ

サーバー側で静的なHTMLを出力しつつ、動的にしたい部分だけをReactを使って実装する際のTipsについて紹介しました。

ReactはFluxなどを使って大きいアプリケーションを作ろうとすると、とたんに設計が難しくなってきますが*3、こういった小さいコンポーネントから導入する方法であれば、JavaScriptの設計になれていなくても導入しやすいですし、現状のアプリケーションに一部分導入するということも可能です。

Reactに興味はあるが難しそうで二の足を踏んでいるという方はこのようなところから利用してみてはいかがでしょうか。

*1:PolymerやVue.jsも同じようなことが実現できそうですが今回はReactにフォーカスしています

*2:コンポーネントのツリーはわかりやすくするために簡略化しています

*3:Reactに限った話しではなく、規模が大きくなれば何を使っても難しくなります