654 文字
3 分

CSS in JS 2022-10

2022-10-17

React では CSS を記述する上で、現状 styled-components や emotion をはじめとした Runtime CSS in JS ライブラリが支配的ですが、パフォーマンスなどを考えると本来静的な CSS ファイルつまり Zero Runtime の方が好ましいです。今までさほど問題に上げられて来ませんでしたが、React 18 によって今後 Zero Runtime CSS in JS を使う圧が強くなっていく可能性が高いです。

Runtime vs Static#

Ref: https://github.com/reactwg/react-18/discussions/110

  • Runtime CSS in JS は現状”レンダリング中”に style を挿入するケースで並列レンダリングが非常に遅くなる
    • コンポーネントが順次レンダリングされていくと、その度に新たなスタイルが挿入され再計算が発生する
    • 競合するルールが存在した場合、ルールが先行して追加されるため再計算が複数回発生する
      • このユースケース用に useInsertionEffect が追加された
        • DOM の参照にアクセスできないことを除いて useLayoutEffect とほぼ同様に振る舞う
  • React 自体にこれらの問題を解決する計画はない。
    • 静的に抽出されたスタイルに使用し、動的な値に単純なインラインスタイルを使用することを推奨する
      • 効率的な解析や、キャッシュが強力であるという点でも優れている
      • ページ数に比例して CSS ファイルサイズが肥大化するという懸念が以前はあった
        • Atomic css や Tailwind css のようなユーティリティスタイルなどを有効活用することで、ファイルサイズは横ばいになる

Zero-runtime CSS in JS の比較#

  • Linaria
    • https://linaria.dev/
    • emotion や styled-components ライクな API なため移行が容易
    • @linaria/atomic: atomic styles 用
  • vanilla-extract
    • https://vanilla-extract.style/
    • 型が強力
    • 仕組みが他ライブラリと大きく異なり、移行には慣れが必要
      • CSS などのファイルを JS で読めるようにする提案が存在し、将来的にこうなるのではないか?という設計になっている
      • CSS Modules ライクな API
    • @vanilla-extract/sprinkles: ユーティリティクラスの提供
    • @vanilla-extract/recipes: variant を持つスタイルの生成
  • Twin

CSS ファイルサイズが肥大化する問題への対処#

ほとんどのライブラリで対応手段が用意されている上、現在においてはほとんどの場合無視できる程度の負荷しかない。それよりもコストの高い CSS の記述などを気にした方がいい。

  • Linaria
    • @linaria/atomic
  • vanilla-extract
    • @vanilla-extract/sprinkles
  • Twin
    • 当然 Tailwind CSS を積極的に利用していくこと
    • Utility CSS クラスを何らか手段で用意しておけば良い
CSS in JS 2022-10
https://blog.ohirunewani.com/posts/css-in-js-2022-10-4ed21e15c8664c8481ad327d93147fa1/
作者
hrdtbs
公開日
2022-10-17
ライセンス
CC BY-NC-SA 4.0