2017-01-19 5 views
1

私は、主にキャンバス上で動作するJavascriptでプロジェクトを作成していますが、DOMに多くのメニューを動的に作成することも含まれています。私はJQueryを使用していません。代わりに、document.createElementを使用して要素を作成し、それをappendChildを持つ親に追加するカスタム関数を使用しています。要素を削除するには、element.parentNode.removeChild(element)を使用します。作成される要素はどのような型でも構いません。入力、画像などを含む。HTML要素を追加して削除した後に恒久的に減速する:その原因とその修正方法は何ですか?

問題は、多くの要素を作成して削除した後、ページが大幅に減速し始め、この数が増えると着実に悪化します。一度に要素が存在する。しかし、Javascriptは遅くならない。メインの更新ループは問題ありませんが、マウスイベントとDOMの操作に関連するすべてが、ページが再ロードされるまで遅くなります。

これまでも同様の問題が発生しましたが、多くの要素を作成したり削除したりしなかったため、一般的に無視されています。

私が原因として考えているのは、参照がクリアされてDOMの可視部分から削除されても、document.createElementによって作成された要素がメモリ内に存在し続けるということだけです。あるいは、おそらく親要素を削除しても、子要素がなくなっているように見えても、すべての子要素を適切に削除することはできません。

私の質問は次のとおりです。DOMが表示されず、JS変数が指し示されていない場合でも、作成された要素がDOMによって保持されていますか?これが減速の原因になりますか?もしそうなら、どうやってDOM要素を適切に破壊するのですか?

+1

DOMから要素を削除する前に削除してください。 考えられるもう1つの原因は、作成された要素への参照をメモリに保持することです。同様に、要素を作成して変数に代入し、その変数に到達可能な状態が続く場合、その要素はガベージコレクションできません。 –

+0

@GiacomoCosimato:これは問題でした!多くのメニューでは、多くのイベントリスナーでカスタムキャンバス要素が使用されていましたが、適切にクリアしていませんでした。それが動作することを修正した後!ありがとうございました! – IndigoFenix

+0

私は助けてうれしかった:) –

答えて

2

それがhere説明したように:

削除された子ノードはまだメモリ内に存在しませんが、もはやDOMの一部 です。最初の構文形式が表示されている場合、後で ノードを削除して、コード内でoldChildオブジェクト参照を使用して再利用できます。 しかし、2番目の構文形式では、oldChild参照 は保存されていません。したがって、コードが ノードへの参照を他の場所に保存していないと、すぐに使用できなくなり、取り消し可能になります。 通常、短い後に 時間。

そして、あなたはhereとして記述何かを試すことができます:

あなたのようなあなたのDOM要素を削除することができ
var garbageBin; 
window.onload = function() 
{ 
if (typeof(garbageBin) === 'undefined') 
    { 
    //Here we are creating a 'garbage bin' object to temporarily 
    //store elements that are to be discarded 
    garbageBin = document.createElement('div'); 
    garbageBin.style.display = 'none'; //Make sure it is not displayed 
    document.body.appendChild(garbageBin); 
    } 
function discardElement(element) 
    { 
    //The way this works is due to the phenomenon whereby child nodes 
    //of an object with it's innerHTML emptied are removed from memory 

    //Move the element to the garbage bin element 
    garbageBin.appendChild(element); 
    //Empty the garbage bin 
    garbageBin.innerHTML = ""; 
    } 
} 

:あなたが作成した要素に任意のイベントを添付する場合に必ず

discardElement(yourDomElement); 
+0

これはデスクトップ上のごみ箱のようなものだ。 – zer00ne

+0

問題が他のものであることが判明したにもかかわらず、これはまだ素晴らしいトリックです! element.parent.removeChild(element)要素全体を削除する方法よりもずっと簡単です。 – IndigoFenix

関連する問題