AutoPagerizeやLDRizeなどのスクリプトで、ページごとの構造を記述するSITEINFOに書くXPathは、どう書いたら速いのかが話題にのぼっていたので、JavaScript-XPathを使ってXPathがDOMツリーから要素を見つけ出す雰囲気を視覚化してみました。JavaScript-XPathが各ロケーションステップで要素がマッチするかどうかをテストするときに呼ばれている(んだと思う)attrMatchという関数の引数に渡される要素をロギングして、そのデータをもとにちょっと時間をずらしながら要素をハイライトしています。
attrMatchが呼ばれている要素を視覚化したものです。実際のXPath実装とは異なります。JavaScript-XPathではdescendant::*((//*))の評価をgetElementsByTagName()で行っているため、getElementsByTagName()が中でどうDOMツリーを走査しているかは視覚化されていません。またdescendant::*[@class="..."]はJavaScript-XPathの中ではgetElementsByClassNameを使うように最適化されていますが、それだと視覚化でる部分が減ってつまんないので無効にしてデータを取りました。
まずTwitterのページで、次のページへのリンクを意味するAutoPagerizeのnextLinkのXPath: //div[@class="pagination"]/a[@rel="prev"] で作ってみました。
Firefox2, Firefox3, Safari3.1で動作確認済み。IEだとみられないですごめんなさい。
Twitter nextLink evaluation
下の画像は、上のページを開いてFirefox3のFull Page Zoomという、ページを拡大/縮小してみられる機能を使って3段階くらい縮小してDOMツリー全体が入るようにしてキャプチャしたものです。
細かい点みたいのがそれぞれDOMツリーの中のタグひとつひとつを示していて、ツリーの深いところにある要素ほど右のほうに表示されるようになっています。DOMツリーをWindowsのエクスプローラでみたかんじです。上のほうにあるDOMツリーの大半を占めている部分は、followingしているひとのリスト部分です。下のほうにある同じような繰り返しは発言のリストの部分です。このDOMツリー上でXPathが評価されるときに参照されたノードが赤く色がついていきます。
評価しているXPathは //div[@class="pagination"]/a[@rel="prev"]/a[last()] なので、はじめにDOMツリーの中にあるdivタグが全部取り出されて赤くなり、次にその子要素のaが赤くなります。参照されたタグの種類によって色分けしておいたらよかったなと思います。
Twitterのページでは、結果が得られるまでに26の要素が参照されていました。
nextLinkのXPathは //div[contains(concat(" ",@class," ")," pager ")]/a[last()] で作ってみました。
FriendFeed nextLink evaluation
XPathはTwitterのときとほとんど変わりませんが、段違いに走査しているノードの数が増えていて、DOMツリーが真っ赤になります。

これはなんでかしらないけどFriendFeedのHTMLが偏執的にやたらdivばっかり使って組まれているのが原因で、はじめの //div のところでたくさんマッチしちゃうからです。結果としてTwitterのときとほとんど変わらないXPathなのにFriendFeedではnextLinkを見つけるのに424の要素が参照されています。
getElement*By*()系の関数がどういう仕組みになっているのかわかってないとあんまり意味がなくて、中途半端になってしまってGeckoのReflowをアニメーションにするのようなのは簡単にできるものでないのがよくわかりました。
トラックバック元エントリにこのエントリへのリンクがない場合はトラックバックを受け付けません。
http://labs.gmo.jp/mt/mt-tb.cgi/213
comments