IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

prototype.js の document.getElementsByClassName は重い

JavaScript でオブジェクトを作って、関連する HTML 上の要素にアタッチするような手法がよく用いられていますが。
その際にどのような方法で要素を取得していますか?

僕は prototype.js の document.getElementsByClassName を使ってクラスを抽出してアタッチしています。

しかし、このメソッドはかなり重い。。。

ためしに、以下のような id ベースで複数の要素を抽出するメソッドを作ってベンチマークをとってみました。

document.getElementsByIdPrefix = function(idPrefix) {
  var children = [];
  idPrefix += '_';
  for(var i = 0; true;i ++) {
    var child = document.getElementById(idPrefix + i);
    if(!child) {break}
    children[i] = child;
  }
  return children;
};

実際のベンチマークこちら

約 10 倍の差です。

遅い理由としては

  • いったん要素を多数取得して、クラス名を別途探さなければならない。
  • $A 関数が重い。
  • inject が重い。など

getElementsByClassName を多少高速化することはできますが、結局は限界があるでしょう。
クラスはひとつの要素に対して複数設定できるなど、かなり便利な道具ですが多様は禁物ですね。

いつか、ネイティブなメソッドとして getElementsByClassName が実装されることを願います。