gotin blog

Whatever gotin wanna write

GreasemonkeyスクリプトのGM_xmlhttpRequestとかで取得したhtmlとかxmlをいじる場合はxpathだと遅いことが多いかも

GM_xmlhttpRequestはresponseXMLを返してくれない。
DOMを作ってくれない、ということ(作ってくれなくていいんだけど)。
xpathするにはDOMを作る処理が必要になる。
DOMParser使うとか、適当なelementのinnerHTMLに突っ込んだりする。
そのときの処理時間がそれなりにかかるので、正規表現とかでひょいひょいパースするほうが早く終わるケースが多いような気がする。
だけど正規表現だと読みにくくてつかれてしまうので、例えばこんな感じの関数でも定義しておけばそれなりに読みやすくなりそうだしそれなりに速いし、ってことになるかなぁ、どうだろう。

function getTags(html, tagName, className){
  var cls = "";
  if(className){
    cls = "[^>]*?class=\"" + className + "\"";
  }
  var reg = new RegExp("<" + tagName + cls + "(\\s|.)*?>([^<]*)</" + tagName + ">", "ig");
  return html.match(reg);
}

function getTag(html, tagName, className){
  var tags = getTags(html, tagName, className);
  return (tags && tags.length) ? tags[0] : "";
}

function getTagText(html, tagName, className){
  return getTag(html, tagName, className) ? RegExp.$2 : "";
}

と、いうのはSBMCommentViewerでLivedoor Clipが読めてなかったのを直してたときに正規表現でパースするほうが(SBMCommentViewerでは元々正規表現で書いてあった)ずいぶんと速く(10倍以上の差)動いたので、一般的にもそういうケースが多かったりするかなと思ったので。
そのときのコード(XPathでたどる方法も書いて試してみたもの)も載せようと思ったんですが、ライセンス的にそのまんま載せたりしちゃダメかもということで自分でつくった関数だけ掲載してみました。


そもそもブラウザにロードされたhtmlとかxmlとかはその時点でDOMが作られてるはずなんで、DOMツリーを作る時間は考えなくて良くて、xpathは十分速く動くはずです。念のため。

追記:
正規表現パースのほうがXPathより10倍以上速かった、というのはXPathの書き方がまずいからかもしれないです。その可能性大いにあります。。。
というのと、実際の時間は2000ms vs 200msほどなんで、2秒待てる処理なら多少遅くたっていいじゃん、ってのもあるかもしれないです。いや2秒と0.2秒は体感できる違いだなぁ。。
それからcssなおしました。表示崩れ問題もなおったかなと思います。

さらに追記:
もう一つ念のためですが、Greasemonkeyじゃなくて、普通のページ内のJavaScriptXMLHttpRequestでとってきたxmlをパースするときも、responseXMLですでにDOMツリーが作られているのでXPath使った方がよいと思います。
逆に言えばJavaScriptXPath使わないほうがいいことがあるのはGreasemonkeyスクリプトぐらいかも。