del.icio.usの重そうな処理速度を計測した
del.icio.usのclass=postかdesc周辺をGMで何かしたくなったのでやってみたけど遅い。適当な文字列を各ブックマークタイトル前に挿入するGMを書いて、FireFoxで50 entry/page、10回(だけ!)平均で測定してみた。それほど厳密な計測じゃないので計測状態の違いで差はあると思うけど、できる限り近い状態で計測したつもり。
del.icio.us/ui/static/delicious.jsで出てくる$cを普通に使った場合
Start: GM実行可能フェーズ, Loaded: GMで登録したonloadハンドラ先頭, End: GM内処理終了。詳細は後で出てくるソース参照。
[Loaded - Start] | [End - Loaded] | [End - Start] | |
---|---|---|---|
1 | 5719 | 1172 | 6891 |
2 | 3125 | 1234 | 4359 |
3 | 2672 | 1188 | 3960 |
4 | 3328 | 844 | 4172 |
5 | 2859 | 844 | 3703 |
6 | 2968 | 844 | 3812 |
7 | 2813 | 843 | 3656 |
8 | 2360 | 1187 | 3547 |
9 | 2375 | 1234 | 3609 |
10 | 2375 | 1219 | 3594 |
avg. | 3059.3 | 1060.9 | 4120.3 |
// ==UserScript== // @name test_del.icio.us // @description hogehohohohohohohogeeeeee // @include http://del.icio.us/* // ==/UserScript== (function() { alert('test_delicious start') var gm_start_time = (new Date()).getTime() addEventListener('load', function() { var page_loaded_time = (new Date()).getTime() var forEach = unsafeWindow.forEach var $c = unsafeWindow.$c var $DIV = unsafeWindow.$DIV var descs = $c('desc') // var descs = $c('desc', $c('posts', document, 'ol'), 'h4') forEach(descs, function(d) { d.parentNode.insertBefore($DIV({}, "[[unko]]"), d); }) var gm_end_time = (new Date()).getTime() alert([ 'test_delicious end. \n', 'start: ' + gm_start_time + '\n', 'loaded: ' + page_loaded_time + ' diff:' + (page_loaded_time - gm_start_time) + '\n', 'end: ' + gm_end_time + ' diff:' + (gm_end_time - page_loaded_time) + '\n', '[end-start] : ' + (gm_end_time - gm_start_time) ].join('')) }, true) })()
初回はブラウザの何かがどうにかなって遅いのだと思う。onload実行されるまで約2800msくらいかかってる。GMでいれた処理(End - Loaded期間)も1000ms近くかかってる。GM内では対したことしてないけど、なんとなく$cが時間かかってそうなので$cを使ってる処理を探したところ、Mp3.go(),Folds.go()で使われていることを確認した。$c関数はgetElementsByClassNameの検索対象のDOM階層、対象タグも指定できるような関数で、del.icio.usのlib.jsに入ってる。
Mp3.goではdocument内の全anchorのうちclass='mp3'のものを検索して、動的レンダリングしている。Folds.goではtag-bundleの折りたたみ挙動の書き換えを実施。こちらはdocument内の全ulからclass='bundles'のものを検索している。とりあえず、この二つの$c処理だけ計測してみた。計測にはbookmarkletに以下のコードをキーワードbbfとして登録して実施した。Ctrl + Lだと瞬時にアドレスバーに移ると今回のような計測に便利だとわかった。
javascript:(function(){var before=new Date().getTime();%s;var result = new Date().getTime() - before;alert('process time(ms)='+result)})()
Mp3.go, $c('mp3', document, 'a')処理時間
タグ付けてないyoupyさんのページと比較してみた。
rtk2106 | youpy | |
---|---|---|
1 | 453 | 47 |
2 | 453 | 31 |
3 | 438 | 31 |
4 | 469 | 47 |
5 | 453 | 47 |
6 | 468 | 31 |
7 | 469 | 63 |
8 | 468 | 47 |
9 | 485 | 47 |
10 | 469 | 63 |
avg. | 462.5 | 45.4 |
10倍くらい違う。タグクラウドにmp3クラスないからpostsクラスで絞った結果だけ検索することで高速化できそうな気がする。
Mp3.go, $c('mp3', $c('posts', document, 'ol'), 'a')
rtk2106 | youpy | |
---|---|---|
1 | 62 | 47 |
2 | 78 | 47 |
3 | 63 | 47 |
4 | 93 | 47 |
5 | 62 | 47 |
6 | 62 | 47 |
7 | 62 | 31 |
8 | 78 | 47 |
9 | 62 | 47 |
10 | 94 | 31 |
avg. | 71.6 | 43.8 |
速くなった。
Folds.go, $c('bundles',document,'ul').each(function(f){ $c('label', f)[0] })
Folds.goでは$c('bundles',document,'ul')だけだとほとんど時間かかってなくて、その下のlabel検索で時間がかかっていた。
rtk2106 | youpy | |
---|---|---|
1 | 718 | 47 |
2 | 750 | 15 |
3 | 750 | 47 |
4 | 750 | 31 |
5 | 734 | 47 |
6 | 719 | 31 |
7 | 734 | 46 |
8 | 734 | 47 |
9 | 750 | 47 |
10 | 734 | 47 |
avg. | 737.3 | 40.5 |
対象がタグクラウド部のせいか、18倍くらい違う。class='label'検索対象をh3タグ限定にして計測してみる。
Folds.go, $c('bundles',document,'ul').each(function(f){ $c('label', f, 'h3')[0] })
rtk2106 | youpy | |
---|---|---|
1 | 16 | 32 |
2 | 0 | 15 |
3 | 15 | 0 |
4 | 0 | 16 |
5 | 16 | 16 |
6 | 15 | 31 |
7 | 16 | 31 |
8 | 15 | 16 |
9 | 16 | 16 |
10 | 16 | 15 |
avg. | 12.5 | 18.8 |
速くなった。
Delicious.Shortcut.init内の$('.posts')
これも遅そうだったので計測した。del.icio.usで使ってる$()関数はjQueryのものらしい(とコメントに書いてある)。
rtk2106 | youpy | |
---|---|---|
1 | 969 | 125 |
2 | 859 | 109 |
3 | 875 | 109 |
4 | 891 | 110 |
5 | 829 | 109 |
6 | 875 | 110 |
7 | 844 | 110 |
8 | 844 | 110 |
9 | 875 | 125 |
10 | 969 | 110 |
avg. | 883 | 112.7 |
Delicious.Shortcut.init, $('.posts', $id('main'))
$()関数も検索コンテキストを指定できるのでgetElementByIdした結果から検索するようにしてみた。
rtk2106 | youpy | |
---|---|---|
1 | 125 | 63 |
2 | 140 | 78 |
3 | 156 | 78 |
4 | 125 | 94 |
5 | 125 | 78 |
6 | 140 | 78 |
7 | 187 | 78 |
8 | 156 | 78 |
9 | 141 | 79 |
10 | 172 | 78 |
avg. | 146.7 | 78.2 |
速くなった。
以上を踏まえて、元のGMで要素選択する対象を絞る
descs取得のコードをコメントアウトしてるものと交換して計測した。
[Loaded - Start] | [End - Loaded] | [End - Start] | |
---|---|---|---|
1 | 2672 | 78 | 2750 |
2 | 3516 | 62 | 3578 |
3 | 2844 | 62 | 2906 |
4 | 2953 | 63 | 3016 |
5 | 2828 | 47 | 2875 |
6 | 2344 | 47 | 2391 |
7 | 2344 | 63 | 2407 |
8 | 2344 | 62 | 2406 |
9 | 2797 | 63 | 2860 |
10 | 2953 | 62 | 3015 |
avg. | 2759.5 | 60.9 | 2820.4 |
変更対象期間(End - Loaded)を高速化できることを確認した。
本当は遅くなってる問題の箇所をGMで高速化したバージョンに置き換えとかできればいいのだけどhtml中に直接書かれているscriptタグを書き換える方法がわからない。GMが呼ばれた時点ではまだscriptタグが評価されていなく(外部スクリプトでグローバルに置いた変数への参照が不正になる)、GMで登録したonloadのタイミングでは既に実行後であることは確認した。
一般的なまとめとして、なんでもかんでもタグ付ければいいってもんじゃないということがわかった。del.icio.usの人もいっぱいタグ付ける人いないだろう、ってことで放置してるような気がする。tag-cloudのuse minimum=5にしとけば5未満の小さいタグがいっぱいな場合に速くすることはできるはず、だけど自分のユーザページではそれほど体感速度の向上は無かった。