8

私は、AJAX で定期的に更新される一連のデータを表示するように設計された Web アプリケーションに取り組んでいます。一般的な使用シナリオは、ユーザーが 1 日中開いたままにして、ときどきちらりと見ることです。

ブラウザのメモリ フットプリントが時間の経過とともにゆっくりと増加しているという問題が発生しています。これは、Firefox と IE 7 の両方で発生しています (ただし、Chrome では発生しません)。数時間後、IE7 のフットプリントが ~200MB になり、FF3 のフットプリントが ~400MB になる可能性があります。

多くのテストを行った結果、AJAX 呼び出しが応答されている場合にのみメモリ リークが発生することがわかりました。サーバーが何も応答しない場合は、ページを開いたまま何時間も放置してもフットプリントは大きくなりません。

AJAX 呼び出しにプロトタイプを使用しています。したがって、onSuccess コールバックに問題があり、これらのメモリ リークが発生していると推測しています。

プロトタイプ/AJAXでメモリリークを防ぐためのヒントはありますか? または、この問題をトラブルシューティングする方法はありますか?

編集:私が使用しているjsグラフ作成ライブラリに問題があることがわかりました。ここで見ることができます。

4

2 に答える 2

11

注意できる最大のことは、イベントとその割り当て方法です。

たとえば、次のシナリオを考えてみましょう (まだ提供していないため)。

<div id="ajaxResponseTarget">
    ...
</div>
<script type="text/javascript">
    $(someButton).observe('click', function() {
        new Ajax.Updater($('ajaxResponseTarget'), someUrl, {
            onSuccess: function() {
                $$('#ajaxResponseTarget .someButtonClass').invoke('observe', 'click', function() {
                    ...
                });
            }
        });
    });
</script>

#ajaxResponseTargetが更新されると (内部的に、Prototype は を使用しますinnerHTML)、イベントを持つ要素は、clickイベントが削除されずにドキュメントから削除されるため、メモリ リークが発生します。2 回目に をクリックsomeButtonすると、イベント ハンドラーが 2 倍になり、ガベージ コレクションで最初のセットを削除できなくなります。

これを回避する方法は、イベント委任を使用することです。

<div id="ajaxResponseTarget">
    ...
</div>
<script type="text/javascript">
    $('ajaxResponseTarget').observe('click', function(e) {
        if(e.element().match('.someButtonClass')) {
            ...
        }
    });
    $(someButton).observe('click', function() {
        new Ajax.Updater($('ajaxResponseTarget'), someUrl);
    });
</script>

DOM イベントの仕組みにより、 の「クリック」は に.someButtonClassも発生します#ajaxResponseTarget。Prototype を使用すると、どの要素がイベントのターゲットであったかを簡単に判断できます。 の要素にはイベントが割り当てられ#ajaxResponseTargetないため、そのコンテンツを 内のターゲットから孤立したイベントに置き換える方法はありません。

于 2008-11-09T16:59:35.657 に答える
-2

私は間違っているかもしれませんが、応答オブジェクトの周りにクロージャーを作成しているようです。各応答オブジェクトは異なるため、メモリ フットプリントが増加します。

于 2008-11-09T16:43:47.920 に答える