あかさたの最近の仕事
2007-11-10 13:56 :
dojo.gfx(dojo 0.4.3) が IE で遅い件について改善にトライした

ここしばらく、Kodougu の IE における高速化を行っていました。これまで、Kodougu の IE 対応は機能カバー率こそ 100% であるものの、速度は Firefox の 1/10 以下という非常に舐めた状態でした。機能カバー率は 50% 程度であるものの Opera 対応の方が実用性が高いかもしれません。
私が IE というものを分かっていないせいだろうと思っていたのですが、どうも調べれば調べるほど、dojo 0.4.3 の dojo.gfx が怪しいということになってきました。(dojo 1.0 が出た時点でやたら古いものを使うなって話ですが。)そこで、 dojo のどこが遅いのか調査してみることにしました。
■ Kodougu のパフォーマンスの調べ方
(1) 以下にアクセスしてください。
http://www.kodougu.net/p/kodougu/diagram/tool/1?profile=true
(2) 「p」キーを押してください。
すると、画面下の方にさまざまなメソッドの処理時間が表示されます。その中の、render メソッドの time/count カラム(単位は秒)を見てください。ちなみに、私の環境(超強力)で 1.6sec です。つまり、一回の描画に 1.6 秒かかっていることになります。Kodougu では、図を開いた直後と何かの操作を実行した後に通信と図の描画処理が実行されます。通信は非同期なので、レスポンスはそれほど悪化させません。つまり、描画処理の重さ≒Kodougu の重さということができます。
■ 原因
結論としては、dojo の VML 要素作成コストが高いことがわかりました。
ちゃんとコードを追っていないのですが、要素生成時のアフィン変換が問題のようです。SVG であれば、Group 要素の属性に行列を記述することで、ブラウザ側(ネイティブコード)で実行されます。VML の場合、そうした機能はないようです。dojo では、applyTransform というメソッドが実行されますが、この中で SVG なら SVG の要素の属性に行列に記述、VML の場合、JavaScript でグループの子要素それぞれの座標を変更しているようです。
dojo が悪いというよりは、SVG と VML との互換性を確保する上でやむを得ないという事情があるようです。(コードを見る限り、アフィン変換そのものは dojo では実装していないように見受けられましたが・・・。)XAML ではアフィン変換をサポートしていたと思うので、Silverlight が普及して VML が無くなれば、この問題は自然と消えていく質のもののようです。
# とはいえ、それには数年かかるので、Kodougu では何とかしなくてはなりませんが。
■ 対策
対策としては、IE では dojo.gfx の使用を取りやめるということを開始しました。あまりに影響範囲が大きいのでまだ途中ですが、部分的にこれを行い、すでに 50% 程度高速になっています。一つ一つの要素作成コストは、1/10 から 1/100 程度になっていると思います。JavaScript ではオブジェクトの生成コストが問題になることが多いのですが、dojo では行列計算まで加わるので、さらにコストがかかっているという状態です。
Kodougu では今のところ平行移動しか使っていないので、グループごとの相対座標はあきらめて、すべての要素の座標を絶対座標で記述することで対処できました。
■ 結論
IE では Silverlight の普及待ちということになりそうです。それまでは「IE なんて死んでしまえ!」という状況が続きそうです。
■ 追記(2007/11/10 14:41)
applyTransform 以外にもいくつかボトルネックになっていると思われる個所があるようです。(createObject というメソッドがとにかくボトルネックになっていて、上記記事ではその中の applyTransform だとかを追っています。)追いきれん・・・。
トラックバック
この記事のトラックバック URL:http://www.rmake-labo.com/akasata/articles/trackback/230
言及リンクのないトラックバック(このブログに触れていない記事のトラックバック)は無視されます。
Posted by あかさた(編集)

2007-11-12 21:01 : dhrname
http://www.kodougu.net/p/kodougu/diagram/tool/1?profile=true
を、Firefox + Firebugで試してみましたが、
遅くなる原因は、dojoによる、vmlとsvgの要素のつくりすぎかと。
上の例では、図を動かすと、200個以上の要素をすべて消してから、また新たに要素を作り直しています。
Firebugだと、この作業に非常に時間がかかっています。
さらに、transform属性を書き換えると、一瞬で移動したので、描画性能は関係ありません。
Firefox+firebugで「ツール -> Firebug -> Inspect Element」を選択してみてください。
Firebugの情報は検索すればすぐに見つかります。
2007-11-12 22:01 : あかさた
コメントありがとうございます!
おっしゃるとおり、本質的な問題は要素の作成しすぎだと思います。ちょっと状況を整理します。
(1) そもそも VML 要素が多すぎる
(2) 操作のたびに全要素を再生成している
(3) dojo.gfx._creator.createObject() は IE と Firefox の間で 3 ~ 4 倍、createGroup に至っては 30 倍程度の速度差が出ている
(4) IE のレンダラーが遅いわけではない
(5) IE でも Firefox 程度のパフォーマンスが出てほしい
まず、(1) は、図を少数の path で記述すれば要素の生成コストを抑えることができます。回転がある(矢印の先端など)ので、どれくらい減らせるかは未知数ですが、それなりには減らせると考えています。(2) は、一つの操作が与える影響範囲を絞り込めていないため、今は手をつけていません。(3) は、IE のみ dojo の使用を取りやめることで、要素の生成コストは数分の一になりました。ただ、それでも IE と Firefox の間にはまだ速度差がかなりあります。(トータルなパフォーマンスでは 8 倍近いのですが、IE 向けコードから createGroup を排除できていないだけなので、最終的には小さな問題になるでしょう。)
(1) と (2) については、おいおい改善できる問題なので、「がんばれ、自分!」で済む問題と把握しています。ただ、dojo を使って同じ処理を実行したときに、IE と Firefox の間で速度差が 10 倍以上開くとなると、複雑な図になると結局「IE では使い物にならない」という話になってしまいそうで、手を焼いています。
dojo 1.0 で Silverlight を試してみるという方法もあるので、いただいた情報を参考にもう少し試行錯誤してみます。ありがとうございました。
2007-11-12 22:27 : dhrname
がんばってください。応援しています。