いまどきのイベントハンドリングは遅いのかどうか問題

id:HolyGrail 周りで盛り上がってたので、ちょっと調べてみた。
DOMContentLoaded イベント使ったら、計測どころを何処にしていいかわからないので、それ以外の部分で。

昔ながらのやりかた。

<html lang="ja">
<head>
<title>Test</title>
</head>
<body>
<script>
var start = new Date();
</script>
<div>
<ol>
  <li><a class="events" onclick="javascript:(function(){alert(1)})()">click!</a></li>
</ol>
</div>
<script>
var end = new Date();
alert(end.getTime() - start.getTime());
</script>
</body>
</html>

いまどきのやりかた。

<html lang="ja">
<head>
<title>Test</title>
<script>
var $C = (function() {
  if (document.getElementsByClassName) 
    return function(classname,tag,node) {
      if (node == null) node = document;
      if(tag == null) tag = '*';
      return document.getElementsByClassName(classname,tag,node);
    }
  else 
    return function(classname,tag,node) {
      if (node == null) node = document;
      if(tag == null) tag = '*';
      var elems = node.getElementsByTagName(tag);
      var pattern = new RegExp('(?:^|\\s)' + name + '(?:\\s|$)');
      var found = [];
      for(var i = 0, length = elems.length; i < length; i++)
        if(pattern.test(elems[i].className)) found.push(elems[i]);
      return found;
    }
})();
var addEvent = (function() {
  if(document.addEventListener)
    return function(elem,type,fn,useCapture) {
      elem.addEventListener(type,fn,useCapture);
    }
  else if (document.attachEvent)
    return function(elem,type,fn,useCapture) {
      elem.attachEvent('on' + type);
    }
  else
    return function(elem,type,fn,useCapture) {
      elem['on' + type] = fn;
    }
})();
</script>
</head>
<body>
<script>
var start = new Date();
</script>
<div>
<ol>
  <li><a class="events" >click!</a></li>
</ol>
</div>
<script>
var elems = $C('events');
for (var i = 0,length = elems.length; i < length; i++)
  addEvent(elems[i],'click',function(){alert(1)},false);
var end = new Date();
alert(end.getTime() - start.getTime());
</script>
</body>
</html>

結果

li 要素を 400 にして試してみた。環境は、MacBook (CPU:Core Duo 2GHz, MEM: 2GB)

ブラウザ 昔ながらのやりかた いまどきのやりかた
Firefox3B5 10ms 32ms
Safari3.1.1 9ms 8ms
Opera9.27 20-50ms 40-80ms

結論

体感では違いがわからない程度。Safari はむしろいまどきのほうが早い傾向がある。Safari すげー。


まあ、特殊な事情が無い限り、いまどきのやりかたのほうがいろいろと便利なのでいいんじゃないすかね。
jQuery とか YUI なんか使うと、イベントバブル辺りもよしなにやってくれるし、便利便利。逆に初心者は積極的にライブラリ使った方がいいと思う。


補足

10000 でも試してみた

ブラウザ 昔ながらのやりかた いまどきのやりかた
Firefox3B5 2000-3500ms 1900-2400ms
Safari3.1.1 180-200ms 200-210ms
Opera9.27 650-710ms 1300-1500ms

だいぶ結果が変わった。
当り前だけど、完全に実装によるよね。
一概に速いとか遅いとか言えないので、その辺、特定の環境を根拠にどうこう言うのはおかしいよな。


はっきり言えるのは、 Safari3 素晴らしいと言うことぐらいですね。