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が早いのは予想通り。clone,DocumentFragmentはあまり目立った効果はなく、性能が良い時もあれば悪い時もあった。もっと複雑なDOM構造だと効果が出るかもしれない。
そこで、(cloneを使った実装を勝たせる気見え見えの実験だけど)あまりいけてない実装をした時に、cloneするとしないで差があるか、というのをやってみた。処理としては、5イテレーションごとにdivブロックを生成し、個々のアイテムをそのブロック内に逐次appendしていく。テストケースとして、1.画面上のDOMにappendする、2.cloneしたDOMにappendし最後に差し替える、の2パターンを試した。
cloneのほうが確かに性能は良い。が、大きな差が出た、というわけでもないので、わざわざリファクタリングで直すほどでもないのかな。それよりもまずは逐次appendをやめるべきだし、5イテレーションごとのブロックも$newBlockみたいな変数にキャッシュしてそこにappendしてから$viewにappendするべきでしょう。あるいは、もっと複雑なDOM構造だと効果が出るのかも。
他に気になるTIPSがあったら随時追記していく。