1

私はJavascriptを多用し、多くのDOM操作を含むプロジェクトを開発しています。コードが大きくなるにつれて、 Internet Explorerでのページの読み込み時にJavasriptの実行に遅延(約1〜2秒)が発生する場合があることに気付きました(9)。この遅延はFirefoxでは発生しませんでした。

例えば:

// the actual code contains much more stuff
$("body").append("<p>paragraph</p>");

p動的に生成されましたが、最新のブラウザでページが読み込まれた直後に表示されるはずです。pしかし、IEでは、静的コンテンツがすべて読み込まれた後にが追加されていることがはっきりとわかることがあります。これにより、ページ全体がジャンプします。

IEを再起動すると、遅延はなくなりました。ただし、多くのDOM操作が行われた場合は、次のページの更新時に再度発生します。

memory leakオブジェクト参照を無効にすることはめったにないので、これが原因であるかどうかを考えています。

var foo = $("#foo");
foo.on("click", function() {
    var bar = '<div id="bar">bar</div>';
    $("body").append(bar);
    // nullify bar
    bar = null;
});
// nullify foo
foo = null;

質問:

  1. 上記の例のように使用が完了したら、すべてのオブジェクト参照を無効にする必要がありますか?

  2. Q1の答えが「いいえ」の場合、いつ、どのような条件でオブジェクト参照を無効にする必要がありますか?

  3. 無効化以外にメモリリークを防ぐために他に何ができますか?

PS:数年前に尋ねられた同様の質問をいくつか読んだことがありますが、それらは主にIE6/7用です。

4

1 に答える 1

4

上記の例のように使用が完了したら、すべてのオブジェクト参照を無効にする必要がありますか?

いいえ、それはやり過ぎです。

Q1の答えが「いいえ」の場合、いつ、どのような条件でオブジェクト参照を無効にする必要がありますか?

もう必要ないが、まだ生きている機能の範囲内にあるとき。あなたの例でfooは、クリックハンドラーから参照できるため、ハンドラーがDOMにアタッチされている限り、ガベージコレクションは行われません。しかし、を無効にする理由はありませんbar

無効化以外にメモリリークを防ぐために他に何ができますか?

  • 変数はまったく使用しないでください。あなたの例では、単純に連鎖を使用できます。$("#foo").on(…);
  • ハンドラー関数が使用される実行コンテキストと無関係である場合は、ハンドラー関数を別のスコープで宣言します。
$(document).ready(function() {
    var foo = $("#foo");
    foo.on("click", showBar);
    // do anything else with `foo`
});
function showBar() {
    var bar = '<div id="bar">bar</div>';
    $("body").append(bar);
});

数年前に尋ねられたいくつかの同様の質問を読みました。それらは主にIE6/7用です。

これは、IE6 / 7のガベージコレクターにいくつかのバグがあるためです(javascript、循環参照、メモリリークMSDN の記事)。それでも、上記の手法はそれとは無関係であり、正しく機能するGCを前提としています。また、GCを最適化すると、GCは不要になる場合があります。たとえば、V8は、実際にはスコープ内にあるが再度使用されない変数を収集します(モジュールパターンのデバッグ:呼び出されるまでスコープ内にない関数?)。

于 2013-02-23T17:41:59.593 に答える