React
css-in-js
styled-components
emotion

CSS-in-JSのライブラリとして「emotion」を選択している理由

どうも、sakitoです。

本業や副業でもReactを使っているのですが、CSS-in-JSを実現するためのライブラリとして、emotionを採用しています。
今回はemotionの紹介も交えながら、採用している理由を投稿します。

emotionとは?

スクリーンショット 2018-11-04 23.09.49.png

emotion - Introductionでも記載があるとおり、glamglamorstyled-componentsglamorousに触発された後発ライブラリです。

たとえばglamorousはpaypalが開発をしていたcss-in-jsのライブラリなのですが途中でメンテナンスが停止しました。
その理由については、glamorousのGitHubにこのような記載があります。

For details on the unmaintained status (and to help people with an automated migration to emotion), see #419.

記載されている#419のIssueはDeprecate glamorous 💄 in favor of emotion 👩‍🎤のタイトル通り、glamorousを停止しemotionに移行するというものです。
簡単に説明をすると、glamorousでできることはemotionでできるからという訳です。
このようにemotionでは多くのCSS-in-JSライブラリの良いところを取り入れています。

現在GitHubスター数は、5000を超えておりnpm trendsで調べてみると人気のstyled-componentsに迫るダウンロード数です。
スクリーンショット 2018-11-04 21.49.35.png

最近ではReactを使用した静的サイトジェネレーターとして人気の高いGatsbyJSチュートリアルも、styled-componetsからemotionに置き換えられました。

emotionは現在v9からv10への移行をしています。
v10はまだbetaなのですが、すでにGitHub上のドキュメントはv10に対応しています。
現状のv9に関する情報はドキュメントサイトを参照とのことです。

emotionの機能

emotionは多くの機能を含んでおり、充実したライブラリです。
代表的な機能をあげたので使用方法については、ドキュメントが充実しているので参照してください。
- CSSスタイル
- Styled Componentsと同じstyledの記法
- Composition
- Object Styles
- Typescriptサポートcsstypeによるcss構文のサポート
- セレクターのネスト
- Media Queriesによるレスポンシブ対応
- グローバルcss対応
- Server Side Rendering
- テーマの作成
- JestでSnapshot Testing

emotionを採用した理由

数多くのCSS-in-JSの中でなぜemotionを採用しているのか説明します。

機能面

冒頭でも述べたようにemotionは後発のライブラリなので、多くのCSS-in-JSのライブラリで実現できることはemotionでも実現可能です。
たとえば、Styled Componentsのようなstyledの記法テーマの作成も実現できます。

styled記法のようにstyleを与えるコンポーネントタグを生成するだけではなく、css記法をObject Styles機能でスタイルを追加することもできるのがemotionの良さです。

// styledの場合
import styled from 'react-emotion'

const Button = styled('button')({
  color: '#000',
})

render(<Button>This is darkorchid.</Button>)
// Object Stylesの場合
import { css } from 'emotion'

const className = css({
  color: '#000',
})

render(<div className={className}>This is darkorchid.</div>)

その他にもawesome-css-in-jsにはこのような表が記載されています。
表にある通り、emotionは大抵の機能が含まれます。
スクリーンショット 2018-11-04 22.12.47.png

表ではReact Nativeのサポートにチェックがありませんが、すでにこちらのPRでReact Nativeの対応がマージされているので、オールチェックになります👏

実行速度

CSS-IN-JS-Benchmarksにこのようなが記載されています。
Mount TimeとRerender timeを計測した結果ですが、emotionのcssをObject Stylesで割当てたソースでは上位の結果になっています。

スクリーンショット 2018-11-04 22.20.21.png

emotionでstyledを使用したソースstyled-componentsを使用したソースの結果を比べてもemotionの方が上位です。

ファイルサイズ

最後にファイルサイズを比較します。
こちらのstyled-components-vs-emotionにこのような表が記載されています。
Sizeの項目に注目すると微差ながらemotionのサイズが小さいということが分かります。
スクリーンショット 2018-11-04 22.32.35.png

最後に

これらの比較はstyled-componets v3のときの比較です。
現在styled-componetsはv4になり、Releasing styled-components v4 finalを参照する限り、かなりの
パフォーマンス向上が果たされたと思われます。
しかし、emotionもv10の開発を行なっているので期待したいところです。

emotionを採用するかどうかは記法の好みにもあるかと思います。
チームで話し合った上でemotionのcss記法が好みであれば採用してもよいと思います。

これでよりemotionの認知が広まればいいな〜〜〜というお気持ちです。