No more ガタンッ――React/Redux、Atomic Design、CSS Modulesを取り入れたアメブロのフロントエンド開発の裏側:大規模ブログサイト表示速度改善 大解剖(2)(2/2 ページ)
2004年から続くブログサービス「アメブロ」が2016年9月にシステムをリニューアル。本連載では、そこで取り入れた主要な技術や、その効果を紹介していく。今回は、ReactやRedux、Atomic Designなど、フロントエンドを構成する技術について。
Atomic Designによるコンポーネント階層管理
Presentational ComponentsとContainer Components
前述したように、コンポーネントは再利用前提で作られており、他のコンポーネントに影響を与えないピュアなコンポーネントであることが望ましいとされています。しかし、アプリケーションを作っていくうちに、「データ取得処理や状態を取得・更新する」といった、見た目以外の処理を行う必要性が出てきます。
こういった内容をどこに書いたらいいのかという問題に対して、Reduxでは、見た目のみに関心を持つ「Presentational Components」と状態を管理する「Container Components」という2つの種類に分けることを提案しています。通常、「Container Components」は上流に位置し、「Presentational Components」へ「props」としてデータを渡します。
アメブロにおけるAtomic Design
通常のアプリケーションであれば、Presentational ComponentsとContainer Componentsの2階層で問題ありませんが、アメブロの規模では管理する状態が多く、特にContainer Componentsの行数が多くなってしまいました。そこでAtomic Designの考え方を取り入れてより階層を増やし、状態を管理するコンポーネントの行数を減らし、それぞれが独立して存在できるようにしました。
アメブロでは、以下のようにルールを決めて運用しています。
- Atoms(Presentational Components)
最小限単位のコンポーネントで、IconやButtonなどが該当します。親コンポーネントから渡されたpropsを元にHTMLを返却します。
- Molecules(Presentational Components)
再利用前提のコンポーネントで、ListやModal、User thumbnailなどが該当します。親コンポーネントから渡されたpropsを元にHTMLを返却します。
- Organisms(Container Components)
画面上の大きな一部のコンポーネントです。HeaderやEntry、Naviなどが該当します。この階層のコンポーネントでは、データ取得処理を記述したり、Redux Stateとconnectしたりして、状態を保持できます。ここで取得した状態はpropsとして、Molecules,Atoms のコンポーネントに引き継がれます。
- Templates
path(URL)ごとのコンポーネントです。ひな型となるコンポーネントであるため、必要なパーツをOrganismsからインポートし、リスト化するだけの役割にします。
- Pages
ベースとなるページのコンポーネントです。基本的には渡されたコンポーネント(this.props.children)をそのまま表示するだけのコンポーネントです。アメブロはSPAであるため、1ページのみ存在しています。
CSSのスコープ管理手法
CSS開発で難しいことの1つに、影響範囲を把握する点が挙げられます。各セレクタがグローバルなスコープであるCSSでは意図しない重複や上書きが行われてしまうことがあります。1ページ用のCSSではうまくいくかもしれませんが、コンポーネント指向とは必ずしも相性が良いとはいえません。
コンポーネント指向を生かす手法
それらを解決するために、幾つかの手法が考えられてきました。
1つは、BEMのようにクラスの命名規則でモジュール化し、疑似的にスコープを作る手法です。他にも、スタイルをJavaScriptオブジェクトとして扱いそれ自体をstyle要素に適用することでスコープを作るCSS in JSや、CSSファイルのクラス名を自動的に固有になるように付与してスコープを作るCSS Modulesなどがあります。
CSS ModulesによるCSSスコープ制御
アメブロは、システムだけではなく組織の規模も大きく、担当者が変わることもあるので、変更の影響範囲が絞れることが極めて重要です。その規模の大きさから、命名ルールなどを決めたとしても守り続けていくのが少し大変でもあります。
そういった点から、今回のリニューアルではCSS Modulesを採用し、スコープを管理することにしました。1つのReactコンポーネントに1つのCSSファイルを用意し、Webpackとcss-loaderを使って、自動的に固有のクラス名を付与することで影響範囲を管理できるようにしています。
CSS Modulesでは普通のCSSとして記述できるので、CSSの機能をそのまま使えますし、もし今後、設計変更する際にもそのまま流用しやすいと想定しています。
デザインとユーザー体験のアップデート
最後に、アメブロのシステムリニューアルの際に、デザインやユーザー体験の向上のために加えたアップデートを幾つか紹介します。
「No more ガタンッ」
システム移行前のアメブロでは、高さが固定されていないモジュールが複数あり、初期表示時に時間差で表示され「ガタンッ」としていました。「ガタンッ」は、誤タップを誘発してしまうので好ましくありません。そこで、今回のシステム移行では、モジュールの高さを固定することを前提にデザインしました。そうすることで、同時にナビゲーションも固定され、ページの遷移がしやすくなりました。
コンテンツファースト
アメブロのモバイル表示は2010年にリニューアルした当時、Twitterを中心に流行していた「モジュールごとに囲むデザイン」でレイアウトされていました。今回のリニューアルのタイミングで画面幅いっぱいに表示する「コンテンツファースト」なデザインにアップデートしました。コンテンツ中心で読みやすく、今風な印象になりました。
カラーパレット調整
アメブロで利用される色は特に管理されていませんでした。むやみに色が追加されると、乱雑で統一感がなくなり、そのページでどこが大事な部分なのか認識しにくくなってしまいます。そこで、Frontifyというサービスを使ってドキュメント化し、コード上ではCSSのカスタムプロパティを使って管理するようにしました。
アクセシビリティ
今回のリニューアルを機にアクセシビリティに関しても気を配っていくことにしました。アメブロは多くの人に使われるサービスであるため、できる限りのアクセシビリティ対応をしておく必要があります。今回は、ESLintのjsx-a11yプラグインや、WAI-ARIAを利用してマークアップをしました。
ただし、本格的な対応はまだまだであり、やっとスタート地点に立ったというところです。
人気の技術だからこそ、チーム内の共通言語化が容易になる
ご覧のようにアメブロシステムリニューアルでのフロントエンドは、現時点で人気の技術を集めた「王道」的なものになりました。
フロントエンドのライブラリは特に変化が激しい分野ですが、そんな分野だからこそ人気の技術をうまく取り入れ、チーム内の共通言語化を容易にすることは大規模システムを運営する上で役に立つと思います。また、人気の技術はコミュニティーが大きく、活発であるため、世界中の技術者と協調しながら開発できるという楽しさもあります。
次回は、DockerやCIなど、システム運営の効率化のためにアメブロリニューアル時に導入したDevOpsの手法についてお伝えします。
筆者紹介
原 一成(はら かずなり)
2008年にサイバーエージェントに入社し、アメーバブログ、アメーバピグ、アメーバスマホなどのフロントエンドを担当。近年はサーバサイド・クライアントサイド両方の実装をしている。
共著書に『フロントエンドエンジニア育成読本』(技術評論社刊)、『Web制作者のためのGitHubの教科書』(インプレス刊)など。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- JavaScriptを中心としたWebアプリ開発の栄枯盛衰まとめ――LiveScriptからAngularJS/React.jsまで
@ITが誕生した2000年頃はJavaScriptが不遇だった時代。そこから現在のような人気のプログラミング言語になるまでには、どのような歴史があったのか。15周年を迎えた@ITの豊富なWeb開発関連記事とともに振り返る。 - いまさら聞けないReact、Virtual DOM、JSX超入門
Facebookが公開しているJavaScriptライブラリ「React」について、その概要や特徴、Webページに導入する方法や基本的な使い方を解説します。 - Node.jsのMVCフレームワーク「Express」の基礎知識とインストール
MEANスタックを用いたWebアプリの開発方法について紹介していく連載。今回は、サーバーサイドJavaScriptのNode.js用MVCフレームワーク「Express」についての概要、インストールとひな型作成の方法を紹介します。次世代フレームワーク「Koa」の紹介も。