Edited at

DOM操作のパフォーマンス

More than 5 years have passed since last update.

backbone.jsなどのjsライブラリで画面生成されるアプリだと、javascript部分のパフォーマンスがアプリのさくさく感にすごい影響を与える。特に、レンダリング部分がトロいと、画面スクロールとか最初の画面生成にもたつきが発生して、いちいち引っ掛かりを感じるアプリとなってしまう。

では実際のところ、どう書いたら性能良くなるの?、ということでネットをさまよってると、「DOM操作を極力なくせ」、というのが共通の見解のようだ。

例えば、イテレーションの中で一つ一つappendするのではなくてまとめてappendしたほうが良いとか、そもそもappendじゃなくて文字列でinnerHTMLに入れたほうが良い、一度作ったDOM構成をcloneして使うと良い、cloneしたDOMを操作してからreplaceしたほうが良い、とかいろいろTIPSが出てくる。

そんなわけで、自分として気になるtipsをjsperfで試してみた。

append vs htmlについてはすでにこちらに。html使ったほうが早いようだ(古いブラウザだと結果が逆のようだけど)。

まずはappendについて。1.逐次appendと、2.一括append、3.append先をcloneした描画されない状態のDOMに対して逐次appendして最後にreplace、4.DocumentFragmentにappendして最後にターゲットのDOMにappendするケースの4つ。

appendの比較

一括appendが早いのは予想通り。clone,DocumentFragmentはあまり目立った効果はなく、性能が良い時もあれば悪い時もあった。もっと複雑なDOM構造だと効果が出るかもしれない。

そこで、(cloneを使った実装を勝たせる気見え見えの実験だけど)あまりいけてない実装をした時に、cloneするとしないで差があるか、というのをやってみた。処理としては、5イテレーションごとにdivブロックを生成し、個々のアイテムをそのブロック内に逐次appendしていく。テストケースとして、1.画面上のDOMにappendする、2.cloneしたDOMにappendし最後に差し替える、の2パターンを試した。

cloneの比較

cloneのほうが確かに性能は良い。が、大きな差が出た、というわけでもないので、わざわざリファクタリングで直すほどでもないのかな。それよりもまずは逐次appendをやめるべきだし、5イテレーションごとのブロックも$newBlockみたいな変数にキャッシュしてそこにappendしてから$viewにappendするべきでしょう。あるいは、もっと複雑なDOM構造だと効果が出るのかも。

他に気になるTIPSがあったら随時追記していく。