確定申告を乗り越えるDBパフォーマンス改善 - Aurora 移行の舞台裏

アプリケーション基盤開発エンジニアの Nayuta です。私が先日登壇した freee Tech Night Online #9 の様子を簡単にご紹介したいと思います。「確定申告を乗り越える DB パフォーマンス改善」をテーマとし、会計 freee のデータベース移行 (MySQL→ Aurora) についてお話しました。

登壇者達の写真

Nayuta (@NayutaYanagisaw)

  • アプリケーション基盤開発エンジニア、2019年6月に中途入社(写真左上)。
  • ストレージミドルウェアに関する仕組み作りや運用改善を担当。趣味的に MariaDB Server にコントリビュートしている。

Terasawa (@terakoya76)

  • SRE、2017年10月に新卒入社(写真右上)。
  • 人事労務 freee の開発に参画した後、SRE チームでインフラの運用・改善を担当。サービスの運用、開発者のサポート、DB の改善がミッション。

のぶじゃす (@noblejasper)

  • ラジオパーソナリティ、2017年に中途入社(写真右下)。
  • mixi、ソーシャルゲーム企業でソフトウェアエンジニアを経験し freee に。入社後はエンジニア→エンジニア採用担当→エンジニアと DevBranding を担当。
  • しゃべりたがり。声が大きい。

レプリケーション遅延が小さな Aurora を選択

nayuta が考え込んでいる写真
大変だったことを思い出しながら話しました

1年で最も負荷の高まる確定申告に向けて、どのような対策を行ったか教えてください。

Nayuta: 様々な対策を行ってきましたが、最も大きいのはデータベースを MySQL から Aurora に移行したことです。

なぜ Aurora に移行したのでしょうか?

Nayuta: Read をスケールアウトできるようにし、負荷を下げたいというのが一番のモチベーションでした。

会計 freee は、freee が提供する中では最大規模のサービスなのですが、サービスの特性上 write がとても多いんです。そのため、Aurora に移行する前はレプリケーション遅延のコントロールが難しく、レプリカをほとんど使えていない状態でした。

いままでは MySQL をスケールアップすることで負荷の増大に対応していたのですが、最近では最大に近いインスタンスタイプを使っていて、後がない状態でした。そこで、仕組み上レプリケーション遅延が小さく、read のスケールアウトが容易な Amazon Aurora への移行を決断しました。

Aurora 以外の選択肢は検討しましたか?

Nayuta: Spanner や TiDB などのいわゆる NewSQL は検討の俎上に上がりました。と言うのも、NewSQL を使えば read だけでなく write もスケールアウトできる可能性があるからです。

しかし、MySQL から NewSQL への移行は構成の変更があまりに大きく、確定申告に間に合わせるのは難しいと考えました。そこで、直近では MySQL と高い互換性を持ち、read のスケールアウトが可能な Aurora に移行することにしたんです。

もっとも、厳密な計測は行っていませんが、write 性能についても Aurora の方が MySQL よりは高いはずです。

いかにして Aurora の性能検証を行ったのか

移行前にどのような検証を行いましたか?

Nayuta: 主眼に据えたのは、本番クエリのリプレイによる性能検証です。会計 freee はかなりのトラフィックがあるサービスで、かつワークロードも非常に多様です。なので、人工的なシナリオに基づいた負荷試験をやるよりは、実際のクエリをリプレイする方がより正確に性能を見積もることができると考えました。

ちなみに、クエリのリプレイには Percona 社製の pt-upgrade というツールを改造して使ったのですが、今思えば独自にツールを開発した方が柔軟性が高かったかなと思います。これは反省点ですね。

どのような試行錯誤がありました?

Nayuta: 一部のクエリで Aurora の方が数倍レイテンシーが高くなるという現象が観測されました。IO が大量に発生しそうなクエリが多かったと記憶しています。このときは一瞬「もう移行は無理かも…」と思いましたね。

それは焦りますね。どのように対処したんでしょうか?

Nayuta: いやー、本当に焦りました。実はその後の調査で、buffer pool size を十分に大きくすれば上の問題は緩和されることがわかったんです。負荷試験のために本番より小さなインスタンスサイズを使っていたので、本番と比べて沢山の IO が発生する状態だったのが原因と推測しています。

また、この問題は本番環境では起きていないようです。実際、本番環境の DB を Aurora に入れ替えた後、主要な API のレイテンシーを監視していたのですが、大きな変動はありませんでした。

運用課題の対策としてクラスター切り替えの仕組みを用意

terasawa が神妙な顔をしている写真
神妙な面持ちで語るTerasawaさん

運用面での検証で苦労したことはありましたか?

Terasawa : マスター昇格のオペレーションの準備が大変でした。会計 freee は、サイズが非常に大きいテーブルが多く、マイグレーションの対象によっては完了までに1日近くかかってしまうものもあるんです。

そういった長時間のマイグレーションに対して、これまでは事前にマイグレーションを掛け終えた DB を別途用意しておき、定期メンテナンス時にアプリケーションからの向け先を入れ替えるマスター昇格を活用していました。

RDS for MySQL ではマスター昇格機能が Managed Service の一部として提供されていましたが、Aurora では内部的な仕組みが違うこともあり、そういったオペレーションをサポートする機能が提供されていません。そのため、こちら側でそこの仕組みを整備する必要がありました。

Nayuta: Percona の pt-online-schema-change を使うという手もあったと思いますが、何でマスター昇格の仕組みを作ったんでしたっけ?

Terasawa : 今回は性能特性の異なる Database Engine への移行ということもあり、移行直後に何かしらの問題が発生した場合、直ぐに切り戻したいと考えていたんですよね。そのため、移行時および移行後の運用双方で利用できるクラスター切り替えによる仕組みを整備することに決めました。

具体的には新旧マスター間で双方向レプリケーションを張って、データの書き込みを同期し、その上で実際に書込み可能なマスターは常に1つのみに制限します。あとは切り替えのタイミングで書き込み可能状態とトラフィックの向け先の切り替えを行うという仕組みを用意しました。

Nayuta: そういえば、3-4年前にの Aurora に移行する目論見はあったらしいんですが、当時はいま言った問題を乗り越えられず中止になったようです。

Terasawa: 我々が入社する前の話ですが、そう考えると3年越しの悲願が達成されたと言ってもよさそうですね(笑)

移行の判断から約2ヶ月で移行を完了

具体的に移行はどのように行いましたか?

Nayuta: あまりに大変すぎて移行時の記憶が飛んでいます…

そこを何とか、思い出してください。お願いします!

Nayuta: そうですね…、2020年の11月に経営陣の GO が出て、12月の中旬に移行したのですが、移行後問題が生じた場合に切り戻すための仕組みや手順の整備がとにかく大変だったと思います。そのあたりは主に Terasawa さんが頑張ってくれました。

Terasawa : 前提として、マスターの負荷が非常に高いので、レプリケーション遅延を考慮した移行手順および切り戻しのシナリオを整えるのに苦労した記憶がありますね。

移行作業自体は無事に済みましたか?

Nayuta: MySQL に戻せる状態を2〜3週間維持して、無事に年末年始も超えられたので、1月頭に移行完了となりました。様々なトラブルを想定して作業に臨みましたが、実際は割とスムーズに行きましたね。

移行してみてどのようなメリットがありましたか?

Nayuta: やはりレプリケーション遅延が小さいのが良いですね。今後負荷が高まった際には、クエリをレプリカに逃がすという選択肢が取りやすくなりました。Write 性能も高く DB 関連のアラートが激減したと思います。Terasawa さんからも何かありますか?

Terasawa : レプリカへクエリを逃がすのもそうですし、Parallel Query の利用など、アプリケーション開発者からも負荷を和らげる取り組みがしやすくなったのはとても大きいと思います。何より無事に移行が完了して、ホッとしています。

のぶじゃす: ぜひ、確定申告の際には『会計freee』を使ってみてください。安定していますよ!

イベントの本編はここまでです。この後は「アフタートーク」でより深いな技術談議が繰り広げられました。

▶freee Tech Night 次回は4月23日に

「freee Tech Night Online #10 人事労務freee、EKS移行」を開催!

freee-tech-night.connpass.com

▶今回のイベントのアーカイブ(録画)

youtu.be

【調査】freee のリモート入社ってどうなの?リモートネイティブの jaxx さんと開発チームのコミュニケーションを探ってみた

みなさんコロナ禍をいかがお過ごしでしょうか。

もう1年近くコロナと戦ってきた私たち。これまで色んな知見は溜まってきたけれど、コミュニケーションが限られる中での入社受け入れってまだやっぱり難しいですよね

今回はそんなコロナ禍で freee がどんな風に新メンバーを受け入れているかご紹介します。

すぎけんの写真

こんにちは sugiken です。
2019年に新卒入社し、会計 freee の開発チーム(愛称: 地獄チーム)で働いています。

去年の7月に入社した jaxx さんと、チームのマネージャーである him0 さん(ヒモさん)にコロナ禍入社がどんな感じだったかを聞いていこうと思います。

sugiken の顔写真 今日はよろしくお願いします。

him0 の顔写真 jaxx の顔写真 よろしくお願いしま〜す。

him0 の顔写真 対話形式珍しいね。

sugiken の顔写真 真面目な内容なので体裁はポップにいこうかなと。
インタビューするのは初めてなので質問雑だったらごめんなさい。

sugiken の顔写真 (企画したのは良いんですが、すでにちょっと記事を書くのがめんどくさいです。)

コロナ禍の入社のアレコレ

sugiken の顔写真 では早速、去年入社した頃のことから質問していきたいと思います。 僕が jaxx さんのオンボーディングパートナー*1を担当していましたね。

jaxx の顔写真 そうでしたねー。
入社初日に freee Tシャツの棚とドリンクバーとトイレの場所を教わりました。

him0 の顔写真 ん?Tシャツとドリンクバーとトイレだけ?

sugiken の顔写真 はい、衣食住は大事なので、まず真っ先に教えました。

him0 の顔写真 なるほど...

sugiken の顔写真 jaxx さんは入社前にリモートワークに対する不安はありましたか?

jaxx の顔写真 正直なかったですね。前職もリモート始まっていたし、転職活動もリモートだったから。

him0 の顔写真 (企画倒れじゃん)

sugiken の顔写真 なるほど、リモートネイティブ世代ですね。

jaxx の顔写真 世代でくくられたの久しぶりです。

入社1ヶ月目の雰囲気

sugiken の顔写真 入社して1ヶ月はどんな感じでしたか?

jaxx の顔写真 地獄チームがやっていることはすぐキャッチアップできました。
チームが和気あいあいとしたので、Slack でも質問しやすかったです。

him0 の顔写真 お手本のような回答だ。

sugiken の顔写真 him0 さん、こう言われてますけど、リモートだしやっぱり意識してサポートしてたんですか?

him0 の顔写真 いや、才能かな。

sugiken の顔写真 あの、記事にしづらいんで。

him0 の顔写真 はい。もちろんリモートで人を受け入れるのが始めてだったから、手厚くしたつもりではあるかな。

sugiken の顔写真 具体的にどんなことしてましたか?

him0 の顔写真 困っていることはないか、サポートできることはないか、コロナ前の受け入れをイメージして積極的に声をかけるようにしてました。

sugiken の顔写真 him0 さんは優しいですね。

コロナ禍のコミュニケーション

sugiken の顔写真 jaxx さん、 freee に入って人間関係はどうですか?

jaxx の顔写真 会計 freee に関わるエンジニアとは結構知り合えていますね。

sugiken の顔写真 そんなに一緒にプロジェクトやってるとかじゃないですよね。

jaxx の顔写真 会計 freee のエンジニア20名全員が参加する全体朝会で誰がどこで何をやっているのかが何となくわかってきました
あとはプロダクト横断的な委員会活動も色んな人を知れますね。

sugiken の顔写真 なるほど。jaxx さんはフロントエンド委員会に参加していますよね。

jaxx の顔写真 そうですね、そこで人事労務 freee のエンジニアや、普段一緒に働くことのないエンジニアともコミュニケーション取れてます。
出社したらご飯行きましょーとか話してます。

sugiken の顔写真 それ楽しそうですね!

地獄チームのコミュニケーション

sugiken の顔写真 ところで地獄チームと言えば雑談ですよね。
Slack の統計情報によると、bot 系のチャンネルを除くと地獄チームが一番投稿数が多いらしいです。

jaxx の顔写真 入社してすぐ雑談のしやすさは感じましたね。
Slack で何でも書きやすいです。

sugiken の顔写真 みなさん雑談のために意識していることとかあるんですか?

him0 の顔写真 weekly ミーティングの雑談コーナーで何か書きたいから、毎週末違うことをしてネタ探してるかな。

jaxx の顔写真 猫カフェ行ってましたね。

猫カフェに行ったことを報告する him0 さん
猫カフェに行ったことを報告する him0 さん

him0 の顔写真 猫カフェ良かったー。

jaxx さんは何か意識してます?

jaxx の顔写真 僕は疲れてそうな人とか、プロジェクトが佳境な人がいたらなるべく冗談を言うようにしています。

sugiken の顔写真 たしかに、jaxx さんは Meet (ビデオ通話) ミーティングの最初に雑談を仕掛けるイメージ。

jaxx の顔写真 逆に僕が忙しい時もあるので、持ちつ持たれつかなと思ってますね。

sugiken は?

sugiken の顔写真 僕は Slack で何かしらリアクションつけるように意識してます!
見てくれている感って大事だと思うんです。
例えばこんな感じ。

yodaさんの育児抜け投稿に emoji をつける
yodaさんの育児抜け投稿に emoji をつける

sugiken の顔写真 なんでもない投稿だし、リアクションも別に必要ないけど、「行ってらしゃい」的なね。

あ、噂をすれば。

何かを察知してインタビューのビデオ通話に入ろうとする yoda さんの Slack 投稿

yoda の顔写真 こんにちは。

sugiken の顔写真 突然ですけど、雑談のために意識していることありますか?

yoda の顔写真 (ほんとにインタビューされた)
えー僕は流れに乗ってますね。

jaxx の顔写真 盛り上げてくれますよね。

yoda の顔写真 はい、まぁみんなもボケたり面白い話とか、くだらない話ししているので、その流れに乗ってツッコんだりボケたり質問したりしてます。

sugiken の顔写真 yoda さんが聞いてくれてるんで、僕も話しやすいです。

コロナ禍のコミュニケーションで大事なことは

him0 の顔写真 思ったんだけど、地獄チームが雑談多いのは jaxx さんが来たからではないかも。
リモートでも雑談が絶えないよね。

sugiken の顔写真 確かに!!
jaxx さんの入社が決まったから何かをした訳ではないですね。

him0 の顔写真 そうそう。
普段からみんなが気軽に話して笑い合えるのが地獄チームの良さなのかも。

jaxx の顔写真 確かに元からいるメンバーがよくボケるから、ボケて良いんだって気持ちになりましたね。

yoda の顔写真 わかる。

him0 の顔写真 ボケだけなのか。


雑談を絶やさないために

sugiken の顔写真 いやー企画的にとてもよい結論が出た。(ニッコリ

地獄チームは雑談が、和気あいあいとした空気を生んでいたんですね!

jaxx の顔写真 でも”雑談”って難しいですよね。

him0 の顔写真 weekly のミーティングとかで意図的に話すきっかけを作ると、自然と雑談も増えてくるよね。

sugiken の顔写真 どこの猫カフェ行ったのかとか気になりますもんね。

sugiken の顔写真 僕はジャーマネ*2の him0 さんが Slack に times channel(個人用のチャンネル)を持っていないのが良い感じだと思います。
チームのチャンネルで独り言を書くから自然と会話が生まれてる。

him0 の顔写真 地獄チームのチャンネル = 自分のチャンネルくらいに思ってる。
ついついチームチャンネルって業務連絡だけになっちゃうから、積極的にハードルを下げていってる

桜の報告をする him0 さん
桜の報告をする him0 さん

jaxx の顔写真 雑談のきっかけが散りばめられてるんですね。

まとめ

地獄チームの魅力に迫ってみました。雑談が多いと毎日働くのが楽しいです。
コロナ禍での入社時のオンボーディングやコミュニケーションなどを手厚くやるのはもちろんだけど、雑談のきっかけを散りばめることで自然な雑談が増えるのかもしれません。
みなさんも普段の何気ない独り言を、チームに共有してみてはどうでしょうか。

雑談でみんな笑顔!!

みんな笑顔の地獄チーム

*1:freee に早く馴染んでもらうようにサポートする係

*2:freeeにおけるマネージャのこと。単にメンバーの上に立つ者のことではなく、”タレント”であるfreeeのメンバーを叱咤激励し、成長・活躍をサポートする役割のこと。

freeeアクセシビリティー・ガイドラインVer. 202104.0を公開しました

こんにちは、freeeのアクセシビリティーおじさん、中根です。

締切が延長されたおかげで、先日余裕を持って確定申告を終わらせることができました。確定申告は概ね独力でできるのですが、紙で交付される書類やアクセシビリティーが低いPDFで交付される書類から情報を転記するところだけは相変わらず人に頼らないと突破できず、毎年残念な気持ちになっています。でも確定申告が終わると気持ちも軽くなり、気温も高くなっていよいよ春が来るなあという感じになります。

さて、それでは今回の更新内容を紹介します。 そして最後にイベントのお知らせもあります。

axe改めaxe DevToolsのルールに関する情報を追加

まず、freeeでも活用していてガイドラインの参考情報でも取り上げているアクセシビリティーのチェック・ツールaxeがいつの間にかaxe DevToolsに改名されていました。ということで各所の表記やスクリーン・ショットを修正しました。 というのはある意味どうでも良い話で、ここからが重要です。

axe DevTools(以下axe)を使っていると、表示されたアクセシビリティーに関する指摘が具体的になにを意味しているのかがよく分からないことがしばしばあります。 特にaxeを使い始めて間もない場合などは、判断に迷うことが多いと思います。

そこで、axeの各ルールがWCAG 2.1のどの達成基準に対応しているのか、さらにその達成基準が対応しているfreeeのガイドラインはどれなのかということが分かるような情報を追加しました。

ただし、この情報はaxe-coreのソースに基づいて自動的に生成しているものです。 axeのソースを見ると、各ルールとWCAG 2.1の達成基準との対応は分かるようになっています。 そしてWCAG 2.1の達成基準とfreeeのガイドラインの対応についてはガイドラインにも掲載しているものを処理しやすい形式に加工したものを用意して処理しています。 これらの情報を基に、axeの各ルールと対応するWCAG 2.1の達成基準、その達成基準に対応するfreeeのガイドラインのリストを機械的に作製し並べているだけです。 ですから、提示されている情報が不完全な可能性があることに充分に注意してください。

チェック内容をまとめたスプレッドシートの公開

各ガイドラインを満たしているかどうかを確認するために示している「チェック内容」について、これまでも全項目を掲載したページがありました。

このページですべてのチェック内容を確認することは可能なのですが、実際にチェック作業を実施する場合には必ずしも使いやすい形式ではありません。

freeeでは、チェックを実施する際にはこの情報をまとめたGoogleスプレッドシートを使っています。 先頃、ひっそりとこのスプレッドシートを一般公開しました:

そして、今回の更新でガイドラインからもこのスプレッドシートへのリンクを掲載しました:

Google Drive上でこのスプレッドシートのコピーを作成してご利用ください。スプレッドシートの1枚目のシートに、簡単な使い方や更新履歴を記載していますので参考にしてください。

そして文末でご案内するイベントで、実際にどのようにチェックを行うのかも含めて、freeeでのアクセシビリティーの取り組みについて紹介しますので、こちらも参考にしてください。

その他の変更

これ以外にもチェック内容の見直しを行っています。詳しくはリリース・ノートでご確認ください。

また、このブログではお知らせしませんでしたが、Ver. 202103.0もリリースしています。

引き続きご意見などお待ちしています

今回の変更についても、それ以外の部分についても、ご意見やお気付きの点など、GitHubリポジトリーのIssuesやPull Requestsでお知らせください。

イベント開催のお知らせ

ということで、今回公開したチェックリストを使ったアクセシビリティー・チェックの実施方法なども含めて、freeeでのアクセシビリティーの取り組みについて紹介するイベントを開催します。

  • 日時:2021年4月9日(金)19:00~21:00
  • 会場:オンライン
  • 参加費:無料

以下のページからお申し込みください:

connpass.com

Webのダークモードを実現するには

こんにちは、freeeのUXチームでデザインシステム “Vibes” を作っている id:ymrl です。

ダークモード流行ってますよね。私は最初はしっくりこないなと思っていたんですが、食わず嫌いは良くないと思って試しているうちに、いつの間にかダークモードのほうが落ち着くようになってしまいました。

そしてそうなってくると、だんだん「自分たちの作っているWebサービスもダークモードに対応するべきなのか?」という気持ちになってきてしまい、最近はずっとダークモードのことを考えています。ということで今回はダークモードをやるべきなのか、実現する方法はどうなっているのか、UIデザインで気をつけるべき点何かというのを考える記事を書いてみます。

※「ダークモード」はApple製品で使われている呼び方で、Androidでは「ダークテーマ」と呼ばれていて、Windowsでは「ダーク○○」のような呼び方をしていなさそうです。この記事では「ダークモード」で表記を統一して呼ぶことにします

Webにダークモードは必要なのか

現時点では、ダークモードはWebサイトの必須の機能というわけではなさそうです。有名なWebアプリケーションではたとえばYouTubeやGitHubはダークモードに対応していて、使用しているOSの設定に準じるようにしたり、好みの配色を選べるようになっているようです。

GitHubのスクリーンショット。Themesという項目名で Default to system / Default light / Default dark から選択することができる
GitHubの設定UI
設定方法は Managing your theme settingsで紹介されている

Web上でOSの設定に準じてスタイルを切り替えるのは、CSSのメディアクエリで prefers-color-scheme という特性を使うことで実現できるようです。つまりWebでは「ダークモードで使用しているかどうか」は「ユーザーの好み」として扱っているということなんですね。

developer.mozilla.org

YouTubeやGitHubのような毎日使うサービスでは、ユーザーの好みに寄り添うことができるよう、サービス側で配色を切り替えたり、ユーザーがどちらを使うか設定できるのは好ましそうです。会計freeeのようなビジネス向けSaaSでも同じことが言えるでしょう。

おそらく現在は、ダークモードを使用している多くのユーザーは、WebブラウザではダークでないWebページが表示されることに違和感を持っていません。そのためWebでのみ展開するアプリケーションであれば必ずしもダークモードへの対応を急ぐ必要はなさそうです。しかし、モバイルアプリもリリースしてそちらはダークモードに対応していたりすると、Webとアプリで表示の一貫性が崩れてしまったり、一部画面をwebviewで表示しているとその画面だけ明るい配色になってしまったりします。ネイティブアプリとの連続性を重視すると、ダークモードへの対応を考える必然性が生まれてきそうです。

Webでダークモードを実現する

上で述べたとおり、CSSのメディアクエリで prefers-color-scheme を使用することで、OSでの設定にあわせてダークモード/ライトモードを切り替えて表示することができます。Webアプリケーションで使用するには、各所の配色をCSSのカスタムプロパティ(変数)として定義しておき、メディアクエリによって切り替えることによって実現するのがシンプルそうです。

以下は雑に書いたダークモードを実現するコードの例で、OSの設定に従ってダークモードとライトモードを切り替えられるようになっています。

:root {
    --textColor: #333;
    --backgroundColor: #fff;
    --linkColor: #4575B4;
}
@media (prefers-color-scheme: dark) {
    :root {
        --textColor: #fff;
        --backgroundColor: #222;
        --linkColor: #6398DE;
    }
}
body {
    color: var(--textColor);
    background-color: var(--backgroundColor);
    margin: 1rem;
    padding: 0;
}
a {
    color: var(--linkColor);
}

上記のCSSをあてたページをダークモードとライトモードを切り替えながら見ているGIFアニメ

CSSのカスタムプロパティは残念ながらInternet Explorerでは使用できず、Internet Explorer向けにもスタイルを提供するためにはもっと記述量を増やす必要が出てきます(prefers-color-scheme も使用できないので、このメディアクエリ内だけはシンプルに保てるはずです)。最近は国内でも各社でInternet Explorerのサポートを終了する動きが加速しているため、Internet Explorerサポートを終了したサービスからダークモード対応のWebアプリケーションが増えてくのではと筆者は予想しています。先述のYouTubeやGitHubもInternet Explorerのサポートを終了しています。

ダークモードでのUIデザイン

技術的にWebのダークモードがどう実現されるのかはわかってきました。ではダークモードのUIデザインではどんなことに気をつける必要があるのでしょうか。

なかなか想像が難しい気がしていたので、freee社内で開発しているデザインシステム “Vibes” のStorybookから適当なサンプルを見繕って、ブラウザの開発者ツールでスタイルを書き換えてダークモードの配色にしながら考えてみました。

入力フォームと送信ボタンのあるサンプルUIと、それをダークモードにしたものを並べてある
ダークモードの配色を試した画面

領域の表現

今回は背景色としてほとんど黒に近い濃いグレーから明度をすこしずつ上げた色を、かなり適当に3色用意しました。完全な黒にしないのは最近のスマートフォンのようにOLEDを使用しているディスプレイでは、完全な黒から他の色への描画が遅延することがあるからだとか。

元々の配色 #FFFFF, #F9F7F4, #EFEDE8 と、ダークモード用の #121212, #222222, #272727 を並べている

一般的に、ライトモードのときはほかのUIにオーバーレイするUIに影をつける表現をするのに対し、ダークモードではUIの応じて背景色を明るくすることで「浮いている」ことを表現します。Vibesでは画面内の区切られた領域を表現するために背景色を変えている部分があり、「浮いている」部分だけでなく、そういった部分の背景色も用意しなければならなくなりそうです。

今回はそういった要素が無い場所で試していましたが、実際のfreeeのUIではモーダルウインドウやポップアップメニューが多用されています。シャドウ・ボーダー・背景色の組み合わせをライトモードのときとは別に考えていく必要があり、単純な色の置き換えのように一筋縄ではいかなそうなことが見えてきました。

色の調整

Vibesでは、テキストの配色のコントラスト比を 4.5:1 になるように設計しています。これは freeeアクセシビリティー・ガイドラインでの定義 やその元となった WCAG (Web Content Accessibility Guidelines) での定義に従ったものです。

ダークモードの配色を作ってみると、文字やボーダーの色選びがライトモードのときよりもしやすいと感じました。コントラスト比は「相対輝度」によって計算するのですが、相対輝度の高い白や薄いベージュに対してコントラスト比を高めるには相対輝度を低く、暗い色にしていく必要があり、しかしそうすると色どうしの識別が難しくなっていくのです。ダークモードでは比較対象が暗い色なので相対輝度の高い明い色がたくさん使えるようになり、使える色の種類が多くなったように感じられたのだと思います。

コンピューターで表現される色はR, G, Bの三原色の組み合わせで表現されるわけですが、人間の目はこれらのうちGを強く感じ、Bを最も弱く感じるため、相対輝度の計算時にはそれを調整する係数がかかるようになっています。つまりfreeeのコーポーレートカラーである青は他の色より暗めに見えるのを調整する必要があるわけですが、freeeの印象を残しつつも視認性の高い色を選べるよう、特に慎重に進める必要がありそうです。

ライトモード用の配色の #C33939, #4575B4, #6F6B62 と、ダークモード用に調節した #E46F6F, #6398DE, #9D9A92

まとめ

今回はダークモードの実装やUIデザインを試作したことで、技術的な課題やUIデザインで注意の必要そうなところが見えてきました。ただ色を置き換えるだけというわけでなく、情報の表現の仕方やユーザーの受ける印象も調整しようとすると、それなりに手間がかかりそうということも見えてきています。そのあたりも踏まえつつ、ユーザーの期待に応えられるUIデザインをしていければな、と思っています。