💅

CSS in JSとは

2022/07/17に公開約3,700字

Click 👉 to read the article in English. https://takuyakikuchi.tech/what-is-css-in-js

CSS in JSとは

JavaScriptを用いてCSSを記述するアプローチ。
CSSはコンポーネントに定義され、外部のCSSファイルに依存することなく、コンポーネント単体で独立する。

下記の例はstyled-componentでのstyling。
(引用元:https://styled-components.com)

const Button = styled.a`
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
  background: transparent;
  color: white;
  border: 2px solid white;

  ${props => props.primary && css`
    background: white;
    color: black;
  `}
`

render(
  <div>
    <Button
      href="https://github.com/styled-components/styled-components"
      target="_blank"
      rel="noopener"
      primary
    >
      GitHub
    </Button>

    <Button as={Link} href="/docs">
      Documentation
    </Button>
  </div>
)

結果が以下のbutton。
output

代表的な CSS in JS

CSS in JSの何が良いのか

CSS in JSのメリットとされる代表的なものを挙げていく。

  • カプセル化
  • メンテナンス性

グローバルなCSSを利用している場合、CSSの定義を変更した際にどこへ影響があるか分かりづらいので、セレクト階層や命名規則などCSS設計にてこれに対応する必要がある。
CSS in JSでは、影響がコンポーネントに閉じられるため、細かいCSS設計が不要になる。

  • 動的スタイリング
  • ライブラリが提供する各種便利機能
    • 自動でベンダープリフィックスを挿入
    • Sassのようなネストセレクターも可能

ランタイムにCSSが生成される為、JavaScriptのpropsを利用した動的なスタイリングなど、JavaScriptでの複雑なロジックをもとにstylingが可能になる。
また、ライブラリが提供する便利機能が使えるのでDXが向上する。(これは学習コストも伴うが)

  • CSSの静的解析

CSS、Sassでは、クラス名を間違っていたとしても実行するまで気づくことができない。また、未使用のスタイルを静的解析により検出することができない。
CSS in JSは、ESLintやTypeScriptコンパイラといったJavaScript向けの静的解析ツールにより、未使用のCSSを簡単に検出することができるため、バグの発見、修正が楽になる。

  • 移植性

スタイルとコンポーネントが同じファイルにあることで、そのコンポーネントを他のプロジェクトで使用することが容易になる。

CSS in JSの何が良くないのか

以下、CSS in JSのデメリットの代表的なものをあげるが、パフォーマンスが一番大きな点になるので、セクションを別に説明する。

  • 可読性が悪い
    • どれが styled-components かわからなくなる問題
    • クラス名が読めない
      例:
<li href="/blog/ecl19xgcapo" class="sc-iqseJM jtAoBP">...</li>
  • 学習コスト(ライブラリによる)

CSS in JSの記法が独特で、それぞれのライブラリによって記述方法が異なるため、学習コストはある。

パフォーマンス

従来のCSSでは、ウェブページを読み込むと、ブラウザはCSSを読み込んで適用するだけなのでサイトへの負荷が少ない。

一方、CSS in JSでは、JavaScriptで定義されたCSSを解析し、CSSにマッピングされたJSX要素を作成する。
ブラウザはCSSスタイルタグを動的に生成し、それを読み取ってウェブページに適用する。この読み込みと生成にパフォーマンス上の時間がかかる。(二重解析)

  1. 一度はライブラリによって解析
  2. 次にスタイルが挿入されるときにブラウザによって解析

サイトの負荷パフォーマンスを気にするならば、ランタイムCSS-in-JSは最適解ではない。

ゼロランタイム CSS in JS

上記の、二重解析によるパフォーマンス時間の損失を改善するための解決策となるのが”ゼロランタイム"。

"ゼロランタイム"とは、CSS-in-JSの構文でスタイルを作成するが、生成されるのは他のCSSプリプロセッサが生成するような.cssファイルであるCSS in JSのこと。

ビルド時にCSS in JSのコードからCSSを抽出し、ブラウザがこれらのスタイルを読み込んでウェブページに適用するので、最終的にスタイルタグを生成する際に通常浪費されるランタイムが節約される。

パフォーマンスが重要な、規模が大きいプロジェクトや複雑なプロジェクトで特に有用である。

benchmarks
コンポーネントがレンダリングされる際に発生する、初期スタイルのinjectionのパフォーマンスの比較
(画像元:https://stitches.dev/docs/benchmarks)

代表的なゼロランタイムCSS in JS

まとめ

the state of css 2021
(画像元:https://2021.stateofcss.com/en-US/technologies/css-in-js)

The State of CSS 2021: CSS-in-JSでもstyled-componentsがusageでトップをとるなど、現在のCSSで広い使用率を占めているCSS in JS。
パフォーマンスのデメリットを改善した、ゼロランタイムのCSS in JSの台頭など今後も要注目である。

参考資料

GitHubで編集を提案

Discussion

ログインするとコメントできます