Facebookのソフトウェア技術者であるNaman Goel氏は、先日のReact Finland 2021でStylexについて講演した。Stylexは新しいfacebook.com Webサイトで使用されたFacebook独自のCSS-in-JSソリューションで、大規模ReactアプリケーションにおけるCSS-in-JSの主な問題点(使用されていないスタイル、CSSファイルの肥大化、CSS-in-JSライブラリのサイズ)を軽減する。Goel氏によると、2021年末までにオープンソースとして公開される見込みである。
React Finland 2021での講演"Rethink CSS — Introducing Stylex"の中で、Goel氏は、Stylexには"高速であること"、"親しみやすいこと"、"フレキシブルであること"という3つの目標がある、と説明した。
最初の目標は、ソースファイル内で検出されたCSS関連のインストラクションを抽出して、静的なCSSファイルにコンパイルすることで実現されている。これによって開発者は — ユーザも — CSS-in-JSライブラリのコストを負担する必要がなくなり、Linariaなどの静的CSS-in-JSライブラリと同じように動作するものになる。比較のために述べると、一般的なCSS-in-JSライブラリのstyled-components
には13KB(ツリーシェイク可能)のJavaScriptが含まれており、その部分をアプリケーションの割当量から差し引いておく必要がある。ユーザエクスペリエンスを改善するために、ページの最初のロード時にダウンロードしなくてはならないJavaScriptの量を制限するという、ベストプラクティスを順守するWebアプリケーションの数が増えている。
一例としてGoel氏は、Stylexライブラリで使用されている以下のコードを示した。
const styles = stylex.create({
base: {
position: 'absolute',
top: 0,
start: 0,
end: 0,
bottom: 0
},
active: {
position: 'static',
}
});
<div className={stylex(styles.base, isActive && styles.active}/>
上記のコードは、以下のようにコンパイルされたCSSファイルになる。
.position-abs {
position: absolute;
}
.top-0 {top: 0; }
.start-0 {left: 0; }
.end-0 {right: 0; }
.bottom-0 {bottom: 0; }
.position-st {
position: 'static';
}
このCSSファイルが、対応するHTMLに関連付けられるのだ。
<div
className="
position-abs
top-0
start-0
end-0
bottom-0
"
/>
コンパイル後のCSSファイルを最適化するため、Stylexでは、使用していないスタイルを削除すると同時に、繰り返しを行わずに再利用可能なアトミックなスタイルを識別することでCSSファイルのサイズを低減している。スタイルの再利用によって、コンポーネントの数に応じて直線的に増加するCSSファイルサイズから、より多くのルールが再利用可能になることで頭打ちになるCSSファイルサイズへのスイッチが可能になる。
さらにStylexでは、ユーザインターフェースに影響を与えないために、ランダムな順番によるCSSバンドルのロードをサポートする形式でスタイルを解決している。CSSルールの順番がユーザインターフェースにどのような影響を与えるのか、Goel氏は以下のように説明している。
上の図は、"CSS specificity rules"の結果として、ルールの定義順によって異なるスタイルが適用される可能性を示したものだ。ユーザエクスペリエンス改善のために大規模なアプリケーションは、バンドルに分解されて必要時にオンデマンドでロードされる場合がある。これによって、CSSルールの順番がバンドルのロード順に依存することになり、順番を事前に保証することが不可能になるのだ。
Goel氏はさらに、StylexがReactのPropsを使ったスタイル構成を可能にしている点も強調している。
開発者はぜひ、React Finland 2021での講演記録を見てほしい。Stylexで行われた技術的およびデザイン上の選択の内容が、多数のコード例やイラストによって詳しく説明されている。React Finland 2021は8月30日~9月3日、オンラインで開催された。