こんにちは、フロントエンドエンジニアの近藤です。Yahoo! JAPANのスマートフォンのウェブトップページのフロントエンド開発業務と、社内で利用されているデザインシステムの開発に携わっています。
近年、デジタルプロダクトを持つ多くの企業で、デザインシステムが活用されています。デザインシステムには、ビジュアルとしてのデザインの規定だけでなく、実際のプロダクトに利用できるUIライブラリやコンポーネントライブラリなどが含まれます。そのため、デザインシステムの構築にはデザインとエンジニアリングの両方の力が不可欠です。
本記事では、私が開発に携わっているデザインシステム「Riff」の紹介とともに、フロントエンド部分におけるデザインシステムの開発・運用や導入における取り組みを紹介したいと思います。これからデザインシステムを作っていく方、既にデザインシステムを運用している方の一助になれば幸いです。
デザインシステムとは
デザインシステムは決まった定義があるわけではありませんが、デジタルプロダクトにおいては一般的に下記の機能を含んだものと認識されています。
- スタイルガイド
- UIにおけるデザインルールやガイドラインを規定したもの
- UIライブラリ
- SketchやFigmaなどのデザインツール向けのライブラリ
- コンポーネントライブラリ
- ReactやVueなどのフレームワーク上で用いるライブラリ
色やタイポグラフィ、要素の形状などをルール・用語集としてスタイルガイドに定め、それを実際のプロダクトに直ちに用いることができるライブラリとして提供します。これにより、プロダクトの迅速な開発と提供を可能にし、チームの生産効率を高めます。また、プロダクトを利用するユーザーに対しては、一貫したデザインによってプロダクトに対する学習を助け、ユーザー体験を向上させます。
ヤフー社内のデザインシステム「Riff」
Yahoo! JAPANには大小含めさまざまなサービスがあり、Riffはそれらのサービスで横断的に利用するための、ヤフー社内のデザインシステムです。UIデザインの品質向上、業務効率化を目的としており、狩野モデルで言うところの「当たり前品質」を担保しています。
Riffは、現在4つのプロダクトで構成しています。
- スタイルガイド
- UIビジュアルデザインにおける基本的な指針を定義したもの
- Riff Design Token
- スタイルガイドで定義している各種トークン情報
- Riff Design Kit
- Sketchで利用できるUIライブラリ
- Riff React
- Reactで利用できるUIライブラリ
フロントエンドエンジニアの役割は主にRiff Reactの開発が中心となっており、受け取ったデザインを基にコンポーネントを開発しています。Riffでは、ボタンや入力フォームといった、再利用や組み換えが容易であり、順応性に優れたコンポーネントを主に提供しています。
前述したように、Riffはさまざまなサービスで横断的に利用されるのを想定しており、サービスの文脈を阻害することなく汎用的に利用できるコンポーネントが求められるためです。
デザインシステムの開発・運用時における改善の取り組み
デザインシステムにおけるコンポーネントは作って終わりではなく、それが利用者の使いやすい状態になっていたり、迅速に提供し続けていけるかも重要です。そのため、コンポーネントの管理・運用に関する改善も継続的に行っています。今回はそのうちのいくつかの取り組みを紹介しようと思います。
コンポーネントカタログとデモ環境の提供
コンポーネントの詳細なAPIはドキュメントから確認できますが、それとは別に、実際に動いているコンポーネントを一覧できる場所が用意してあると、コンポーネントの機能がより把握しやすいです。RiffではStorybookを用いてコンポーネントカタログを用意しており、コンポーネントの表示パターンを簡単に確認できるようにしています。
また、実際にコンポーネントを触って動かせる独立した環境があれば、利用者はRiffの導入前に検証を行えたり、コンポーネントの挙動を即座に確認できます。そこで、コードを編集しながらコンポーネントを動かすことができる、Playroomによるデモ環境の提供も行っています。
ビジュアルリグレッションテストでコンポーネントの表示差分を検知
モジュール性が高いコンポーネントは頻繁に再利用されるため、変更による影響範囲が大きいです。そのため、変更による表示差分の変化が意図したものであるかは慎重に確認する必要があります。しかし、手を入れる箇所によっては影響に気づけないまま見落としてしまう可能性があります。そこで、Riffではreg-suitでのビジュアルリグレッションテストによって、コンポーネントの表示の変更差分を機会的に検知できる仕組みを導入しています。
これにより、開発段階で意図しない変更に気づくことができ、それが混入した状態でのリリースを防げるようになっています。
色のコンストラスト比の検証を機械化
Riffではスタイルガイドのテキストと背景のコントラスト比が「4.5:1」以上と定められています。ただし、利用者側ですべての実装がこのルールにのっとっているかを確認するのは難しい上、すべてのパターンをスタイルガイドに用意するのも現実的ではありません。そこで、すべてのテキストと背景色の組み合わせでコントラスト比を計算し、表形式で判定結果を表示できるようにしました。
この表を見ればテキストと背景色の組み合わせがひと目でOK、NGであるかが分かるので、利用者は簡単に問題のない組み合わせを選べます。
コンポーネントの利用数の測定
デザインシステムの目的の一つとして業務効率化があげられますが、しばしば課題となるのはどれぐらい業務効率の改善がなされたかの可視化が難しいことです。
現在Riffでは利用者へのアンケートで満足度を集計し、定性的に効果を測定しています。項目には選択肢による回答だけでなくコメントによる自由記述も受け付けることで、利用者の感想や役に立った部分、具体的な改善点なども吸い上げられ、Riffの品質向上に一役買っています。
それとは別に、Riffによる効果を定量的に測定する試みも行っています。利用者側のソースやリポジトリに対してCI上から集計スクリプトを定期的に実行し、利用されているコンポーネントの数や割合を測定するというものです。利用されているコンポーネントを可視化し、その利用数や占める割合から、利用者側がコンポーネントを新規に開発・運用せずに済んだかを算出すれば、どれぐらい業務効率の改善に寄与しているかを定量的に示せます。
// 利用されているコンポーネント情報を抽出
{
"matchFileNum": 22,
"searchFileNum": 243,
"rate": 0.09053497942386832,
"importedComponentNum": 31,
"importedComponents": [
{
"filePath": "frontend/src/components/modules/CGradeTopics/CGradeTopics.tsx",
"imported": "@yj-intl/riff-react",
"components": [
"Button"
]
},
{
"filePath": "frontend/src/components/modules/CookieBlockAlert/CookieBlockAlert.dynamic.tsx",
"imported": "@yj-intl/riff-react",
"components": [
"Alert",
"AlertDescription",
"AlertTitle"
]
},
...
]
}
デザインシステムをプロダクトとして独立させる
Riffは全社で横断して利用できるデザインシステムである性質上、さまざまな環境で支障なく動作することが求められます。Yahoo! JAPANには数々のサービスが存在し、それらを提供している環境は千差万別です。そのため、デザインシステムはサービスのアーキテクチャにできるだけ干渉しない、独立したプロダクトである必要があります。次に紹介する事例は、実際にサービスに導入してもらった際に起きた問題と、それを受けての改善になります。
導入先でのビルド環境の構築を不要に
Riffで提供しているReactコンポーネントではスタイルを記述するために、treatというCSS-in-JSライブラリを利用していました。treatはビルド時にコードを生成するため、Riffを利用するサービス側でも導入するためのアーキテクチャを整える必要があります。
私が担当しているスマートフォンウェブトップページでもRiffを導入することになったのですが、スマートフォンウェブトップページはNext.js上で動作しているため、Next.jsをtreatが動作するバージョンまで上げたり、treatを動作させるためのRiffで提供しているProviderをサービス側のコードに挿入する必要がありました。
その影響で、CI上での自動テストでエラーが出てしまったり、アプリケーションをPaaS環境にデプロイできなくなってしまったりと、多数の問題が起きました。それらの解消にはある程度の時間を要するため、別の案件・作業の優先度との兼ね合いもあり、一時は導入を見送る案も出ました。最終的には導入を進めることになり問題も解決して導入できましたが、その作業には約2週間費やすことになりました。
サービス側は常にビジネス案件を多数抱えているため、それらとの優先度の兼ね合いでデザインシステムを導入することになります。そのため、デザインシステムを導入するコスト自体が高くなってしまうのは望ましくありません。実際に、他のサービスではアーキテクチャを変更するのが難しかったため、導入を見送ったケースもありました。
これらのことから、Riffは利用者の環境にできるだけ依存しないよう、利用者側でビルド環境が必要となるCSS-in-JSから、配布時には既にスタイルがビルドされている状態となるSassへと変更しました。これによって、利用者はRiffのためのビルド環境の構築が不要となり、利用者側の既存のコードにも手をいれることなくRIffを導入できるようになりました。
コンポーネントからアイコン機能を分離し、SVGコードのみを提供
Riffには汎用的に利用できるアイコン集も含まれています。アイコンは種類やサイズ、色などを指定でき、ウェブだけでなくiOS・Androidアプリでも利用可能なものです。
このRiffのアイコンを社内のAndroidアプリがベクター画像形式(ここではSVG)で利用したいとの要望がありました。アイコンデータはSketchのDesign Kitでしか提供していなかったため、SVGとして利用するにはSketch上でアイコンデータを書き出す作業が必要です。この場合、SVGコードの中身はデザインツールの出力方法に依存することになるため、出力されるデータにはデザインツールによって異なるSVG属性が含まれることになります。アイコンデータが出力する環境によって変わる可能性があるのは、アイコンの一貫した挙動を担保できないため望ましくありません。
検討した結果、RiffにSVGデータだけを利用できる機能を追加することになりました。SVGはアイコンデータを含むRiffのSketchファイルからスクリプトにより動的に生成するので、Sketchの更新時に自動でSVGコードを生成することで、常に最新の状態が出力できます。
これにより、利用者はデザインツールに依存せず、純粋なSVGのアイコンデータを簡単に利用できるようになります。この機能はRiff-Iconという新たなプロダクトとして提供する予定です。
以上の事例から分かる通り、デザインシステムは利用者の環境やアーキテクチャを制限しないようにすることが望ましいです。仮に利用者の環境が何らかの要因で変える必要が出ても、デザインシステムと利用者側の環境に依存がなければ、次の環境へ移行したとしてもそのままスムーズにデザインシステムを利用し続けられるでしょう。
おわりに
デザインシステムはその名の通り「システム」であるため、その構築にはエンジニアリングは不可分です。長期的にデザインシステムを運用するためには、開発者と利用者、双方にとって使いやすいプロダクトであり続ける必要があります。その中でも、本記事では特にフロントエンド部分に焦点を当てて、デザインシステムの開発・運用における改善の取り組みを紹介しました。
Riffはまだ発展途上のプロダクトであり、社内で利用しているサービスもまだ限られています。今後も継続的に改善を続け、多くの利用者にとって有益となり、さまざまなサービスで利用されるプロダクトに成長させていきたいと思います。
こちらの記事のご感想を聞かせください。
- 学びがある
- わかりやすい
- 新しい視点
ご感想ありがとうございました
- 近藤 春海
- Yahoo! JAPAN ウェブトップページエンジニア
- Yahoo! JAPANのスマートフォンウェブトップページの開発・運用をしています。