NodeListのイテレーション比較

document.querySelectorAllなどで取得するNodeListはArrayのインスタンスではないため
forEachやmapといったメソッドを持っていません。

そのためループで展開したいときは普通にfor文使うとか、
Array.prototype.forEachをcallで呼び出すとか
ライブラリの関数を利用するといった選択肢がありますが
それらのパフォーマンスを計測・比較してみました。

結果はこんな感じ、平均して遅いのはfor inや$.each、
速いのは通常のfor文やwhileでした。
NodeList Iteration · jsPerf

通常のArrayだとこのように、極端なパフォーマンスの差は見られません。
Array Iteration · jsPerf

結論としては、普通にfor文にしましょうとなるんですが、
lodashはfor, whileに次ぐ実行速度で、記述量も少なくて済むので
既にlodashを入れているor他にも使いたいメソッドがあるのであれば
選択肢としては十分にありではないかと思います。

内部的には渡されたリストがArrayのインスタンスでなければ
while文を使ったイテレータ関数の文字列を生成して、
Functionコンストラクタに突っ込んで実行するという、結構泥臭いことをしているようです。
やはりパフォーマンスを最優先にしている印象ですね。

あと、for文書くときに

for (var i = 0, len = list.length; i < len; i++) {

のようにlengthをキャッシュした方が速い、というのは割と定説になっている思うのですが、
最近のJavaScriptエンジンでは自動的に最適化されるので必要ないという話も
耳に挟んでいたのでその比較も先ほどのjsperfに入っています。

for (var i = 0; i < list.length; i++) {

lengthをキャッシュした場合と比較してもほぼ遜色ないどころか、
Firefoxではむしろ速くなっています。
モダンブラウザ・スマートフォン向けの開発なら、lengthのキャッシュはもう必要ないですね。

※この他にインクリメントの前置・後置も比較してみましたが、特に差は確認できませんでした。