LoginSignup
2
1

More than 3 years have passed since last update.

CSS-in-JSを使うとどれくらいパフォーマンスに影響するか計測してみた。

Posted at

InfoQの記事を読んでいるとCSS-in-JSに関して以下のように書いてありました。

スタイル付けされたCSS-in-JS実装は、スタイル付けされていないバージョンと比べて50%以上もレンダリングに時間がかかるように見えた。

CSS-in-JSはパフォーマンスが落ちるとよく聞くものの、実際どうなのか知りたかったので計測してみました。

計測方法

CSS-in-JSを使って作成したコンポーネントとそうではないコンポーネントのレンダリングに掛かる時間を計測して比較します。
CSS-in-JSのライブラリはemotionとstyled-componentsを採用しました。

計測には以下のコードを使用します。
Appをレンダリングすると、画面上部にボタン, その下にNormalDivコンポーネントがNUMの数だけ表示されます。
ボタンを押下するとNormalDivコンポーネントが再レンダリングされます。
再レンダリングが終わるとボタンを押下してから再レンダリングまでにかかった時間を計測してコンソールに表示します。

計測用コード
import React from 'react';
import NormalDiv from './NormalDiv';

const NUM = 2 ** 8 // 表示するコンポーネント数

const TestFC: React.FC<{randomValue: number}> = ({ randomValue }) => {
  return <>
    {new Array(NUM).fill(null).map((__, i) => (
      <NormalDiv key={i}>Hello World {randomValue}</NormalDiv>
    ))}
  </>
}

let start: number;

const App = () => {
  const [randomValue, setRandomValue] = React.useState(0);

  React.useLayoutEffect(() => {
    const end = new Date().getTime() - start
    console.info(end)
  })

  return (
    <React.Fragment>
      <button onClick={() => {
        start = new Date().getTime();
        setRandomValue(Math.random());
      }}>Force Rerender</button>
      <TestFC randomValue={randomValue} />
    </React.Fragment>
  );
};

NormalDivコンポーネントはCSS-in-JSを使わないもの、emotionを使ったもの、styled-componentsを使ったものの3種類を用意して、レンダリングに掛かる時間をそれぞれ計測して比較します。

用意したNormalDivコンポーネントのコードは以下のとおりです。

CSS-in-JSを使わない場合
import React from 'react';

const NormalDiv = (props: any) => <div {...props} />
emotion
import styled from '@emotion/styled'

const NormalDiv = styled.div``;
styled-components
import styled from 'styled-components'

const NormalDiv = styled.div``;

結果

表示するコンポーネント数 256 512 1024 2048 4096 8192
CSS-in-JS未使用 [ms] 74 122 252 516 939 2028
emotion [ms] 115 241 367 707 1506 2748
styled-components [ms] 154 231 361 721 1531 2830

CSS-in-JS未使用の場合と比較してemotion, styled-componentsは +30% ~ +90% 程度レンダリングに時間がかかった。

emotionとstyled-componentsの間ではレンダリング時間に大きな差はなかった。

まとめ

InfoQの記事のとおり、たしかにCSS-in-JSを使うとレンダリングに時間がかかるようになりました。

私は名前をつけるためにconst Article = styled.divのような変数化を多用していました。
しかし、パフォーマンスが悪化するのでなんでもかんでもstyledを使って変数化するのは控えようと思います。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1