2007/10/19

removeChildをするときには、その前にEventを全部取ること!

removeChildのみならずreplaceChildのときも必要!さらに、innerHTMLで内でEventを指定していた要素にも必要!

前からIE6にはメモリリークがあるってことは知っていた。そして、要素同士が双方にポインタを持つこと?で、そのメモリリークが起こると知ってはいた。そして、それを避けるべきだということも言葉では理解していた。でも、実際にどうすればいいの?ってことがわからなかったのだ!そして、つい先ほど、その問題解決がわかった!!!超感動!

確かに最近開発したWebアプリでは、再読み込みをする度に重くなっていき、絶対メモリリークしているなってことに気づいていた。でも、だからってどうしたらいいかはわからなかった。って、それはそれで問題なのだけど、こうやってわかった以上は早速月曜日に修正するぜ!

で、どうやって気づいたかというと、YUI TheaterのDouglas Crockford氏のThe Theory of the DOMからだった。いいよ!いいよ!Qualityも良かったけど、本当に勉強になるっす。一応3つも映像があって、全部で一時間半弱なんだけど、見てよかった!ここには、そのメモリリークについて話があったPart3を貼り付けておく。メモリリークの話だけなら、Part3の最初の6分くらいなので、それだけチェックしてもいいかも。

で、講義の中で上げられていた削除する前にイベントを削除する方法としては、上の映像では次の関数を使用していた。実際に動かしていないから間違っているかもしれんけど、だいたいこんな感じ。

  1. function purgeEventHandlers(node) {
  2.   walkTheDOM(node, function(e) {
  3.     for (var n in e) {
  4.       if (typeof e[n] === 'function') {
  5.         e[n] = null;
  6.       }
  7.     }
  8.   });
  9. }
  10. function walkTheDOM(node, func) {
  11.   func(node);
  12.   node = node.firstChild;
  13.   while (node) {
  14.     walkTheDOM(node, func);
  15.     node = node.nextSibling;
  16.   }
  17. }

もしくはYUIのpurgeElementで指定した要素以下の要素のイベントを一掃してくれるとのことだ。
まぁ、方法がわかれば簡単に作れるさ。prototype.jsなどでElement.remove()とかしているところもremoveする前にイベントを一掃しないとメモリリークしてしまうので、気をつけないといけない。私の問題はまさにこれだったと思う。というわけで、Douglasさんのファンになりましたので、当分YUIを調べることになりそうす。
うーむ。やってみたけど、メモリが開放されない。。。なんでだろ。dragdrop.jsのdraggableをたくさん作って、その上のDIVコンテナのinnerHTMLを書き換えているので、おそらくdraggableな要素が無くなってもメモリは持っているかのようだ。。。ちょっと調査せなかんな。

つーか、Wordpressのバージョンを上げたらwysiwygエディタを消すオプションが無くなってた。。。orz
ソースコードのスペースを勝手に削りやがって!!!!空行も削りやがる。許せん!くそー。腹が立ってきた。
って、少し調べたら私の他にも腹が立っている人はいるみたい。
Idea: Option to turn off WYSIWYG editor, sitewide!
解決方法がtinymceのディレクトリを削除しろだって?やってらんねー。

つーわけで、wp-includes/general-template.phpのuser_can_richedit関数の$wp_rich_editを無理矢理falseにしたった。

Leave a comment

Bloglines feedburner