LoginSignup
13
15

More than 5 years have passed since last update.

reactのshouldComponentUpdateについて

Last updated at Posted at 2015-09-10

気持ち

ReactのComponentは、stateが更新されるとコンポーネントが丸っと再描画されます。このとき、Virtual DOMのおかげで差分のみがDOMに反映されるので、性能をそんなに劣化させる事なくUI制御をすることが可能になります。

でも、アプリで表示するデータがFBのタイムラインみたいに無限に取得できるような画面の場合、いくらVirtual DOMといえどもさすがに辛いのでは。さらに、もしそのデータがネストしていたら、実際に描画しないとしてもネスト部分のループ処理は行われるわけだよね?実際どうなの?

調べてみた

ということで、jsperfで実際にやってみました。

[
  {
    id: 1,
    firstName: 'xxx',
    lastName: 'XXX',
    children: [...]
  },
  ...
]

という感じのネストしたデータを大量に表示するコンポーネントを二つ用意し、一つは何も考えずにコンポーネントを定義、もう一つはshouldComponentUpdateを使って、childrenの配列に変化がなければ(つまり !== で比較してfalseであれば)childデータの表示コンポーネントは再描画しない、というようにしています。

shouldComponentUpdateは、コンポーネントを再描画するかどうかを決定するAPIで、defaultは常にtrueを返す、つまり常に再描画するようになっています。
https://facebook.github.io/react/docs/component-specs.html#updating-shouldcomponentupdate

結果はこちら
http://jsperf.com/react-performance-shouldcomponentupdate
(表示が重いのでブラウザ一瞬固まるかも。固まってもそっとしといて)

root2のほうがshouldComponentUpdateを使った結果ですが、結果は明白ですね。

1秒間に10回再描画処理(実際には何もしてない)が走るのに対し、shouldComponentUpdateを使わない方は1秒間に1回の描画すらできていません。

とはいえ

shouldComponentUpdateを使うと、コンポーネントのメンテナンスコストも上がりますし、この差分チェックロジックにバグがあれば意図した通りにUIが反映されない、という辛いバグにぶつかるかもしれません。今回の例だと、dataコンポーネントの表示全体としては問題ないけど、なぜかchildlenデータ部分の表示だけおかしい、みたいなことが起きるかもしれません。FBが推奨するようにimmutable-jsとPureRenderMixinを組み合わることを考えた方が良いかも。

まとめ

性能面が問題になるくらいに複雑なデータを表示しないのであればこのAPIを使う必要はなさそうですが、万が一性能が問題になった時はshouldComponentUpdateで回避できることを思い出そう。

13
15
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
13
15