3

ajax 呼び出しを介して .html ファイルのデータ全体を div にロードしています。html ページには、 HTC (html コンポーネント) がページ上の要素とバインドするために必要なリンク、スクリプト タグが含まれています。

ページの構造は次のようになります。

ここに画像の説明を入力 このようなHTMLページをロードするためにjQueryを使用しています

<body>
<input type="radio" class="openpage" id="0001">
<input type="radio" class="openpage" id="0002">
<input type="radio" class="openpage" id="0003">
<input type="radio" class="openpage" id="0004">

<div id="loadPage"></div>
<script>
$(document).ready(function(){
  $(".openpage").on("click",function(){
    $("#loadPage").load($(this).attr("id")+".html",function(){
    //load a page with many htc bindings and external references

    //trigger some onload functions which are not called automatically in IE
    //confirmed this is in chrome

    });
  });
})
</script>

</body>

これに伴う問題は、ラジオ ボタンをクリックしてページをロードすると、IE のメモリが増え続け、いくつかのページをロードした後にブラウザが応答を停止することです。タスク マネージャーでメモリが増えているのがわかります。

アプリケーションは IE 5、6、7、8、9 で実行され、IE10 では互換モードで実行されます。Chrome で同じシナリオを再現しようとしましたが、問題はありませんでした。したがって、IE固有のメモリ管理関連の問題だと思います。

私は多くの記事を読みましたが、確信が持てませんでした.SO でこの質問も読みましたが、私の場合は受け入れられないページの一部のみを読み込むことを提案しています.この記事は関連しているようですが、メモリリークの正確な原因はわかりません私の場合。

上記の本文全体は、実際には iframe 内にあります。回避策として、ラジオ ボタンを 8 回クリックした後にメイン ページを含むフレームをリロードします。以下を使用して、各ロードの前にものをクリアしようとしました:

$("#loadPages").empty();

$("#loadPages").find("*").off();

$.ajaxSetup({ cache: false });

しかし、何も機能しません。したがって、jquery が htc を介して登録されたイベントをクリアできるかどうかは疑問です。

1)この場合のメモリリークの理由を説明していただけると助かります

2) そして一般的に、多くのリソースをロードした後にブラウザでメモリ リークが発生する理由。これは最新のブラウザーでは発生しませんが、古いブラウザーで発生した理由です。

3) フレームを更新せずにブラウザーのメモリを解放する方法はありますか。

4)ブラウザのメモリに存在するすべてのリソースを確認する方法はありますか?

4

2 に答える 2

4

いくつかのワークフローがあります。

  • 既存の DOM 構造を動的に読み込まれた構造に置き換えます。
  • ロード後に追加のイベント処理を配線します。

ここから:

  • DOM ノードを削除/置換しても、イベントは引き続きバインドされます
  • イベント ハンドラーにバインドされているため、DOM ノードをクリアできない場合があります。
  • DOM ノードはメモリ内に保持され、UI から切り離されますが、依然としてメモリ リークが発生します。

オプションは次のとおりです。

  • DOM からそれらのノードをクリアし、新しいコンテンツをロードできるようにする前に、既存の構造のすべてのイベントを必ずクリアしてください。
  • 表示用に複数のノードを用意し、それぞれを 1 回だけロードします。
  • ノードが存在するかどうかを確認し、交換するのではなく、単純に切り離してください。

IE には、JavaScript とレンダリング エンジン用に個別の COM チャネルがあります。JS のオブジェクト/状態は UI/DOM ノードへの参照を保持できます...そして DOM ノードは JS イベント ハンドラーを参照できます。多くの場合、これは、これらの部分がガベージ コレクションされないことを意味し、メモリ使用量の増加につながります。以前のバージョンでははるかに悪化していましたが、それでも発生します。

他のブラウザーでも同様の問題が発生する可能性がありますが、IE はこの動作をより早く表示する傾向があります。これは、寿命の長い単一ページ アプリケーションでもよく発生します。

各リソースを独自の DOM ノードに 1 回だけロードする場合は、そのノードを単純にデタッチ/再アタッチできます。また、イベントの伝播に依存して、親ノードからのイベントをリッスンすることもできます。これらのいずれかにより、競合のリスクとオーバーヘッドが軽減されます。

イベント ハンドラーの登録解除に関しては、jQuery に登録し、jQuery を使用してノード (およびその子) を削除/削除する限り、jQuery はほとんどの場合よりもうまく機能します。

于 2015-02-24T22:18:10.020 に答える
1

xhr リクエストの使用を検討したことがありますか? ajax を使用してコンテンツをターゲットにロードできます。私はあなたの質問にサンプルフィドルをしました。それを見てください。乾杯。

スニペット

function getXmlHttpRequest() {
  var xmlhttp;
  if (window.XMLHttpRequest) {
    xmlhttp = new XMLHttpRequest();
    // code for IE7+, Firefox, Chrome, Opera, Safari

  } else if (window.ActiveXObject) {
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    // code for IE5 and IE6
  } else {
    alert("Browser doesn't support Ajax..!!");
  }

  return xmlhttp;
}

function loadPage(pageTitle) {
  //pageTitle = pageTitle + ".html";
  xmlhttp = getXmlHttpRequest();
  if (xmlhttp != null) {
    xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState < 4) {
        document.getElementById('loadPage').innerHTML = "Content Loading...!";
      } else if (xmlhttp.readyState == 4) {
        var res = xmlhttp.responseText;
        document.getElementById('loadPage').innerHTML = res;
      }
    }
    xmlhttp.open("GET", pageTitle, true);
    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlhttp.send(null);
  }
}

function showAlert() {
  alert("This is me!");
}
$(document).ready(function() {
  $(".openpage").on("click", function() {
    loadPage($(this).attr("id"));
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<input type="radio" class="openpage" name="radio-group" id="https://dl.dropboxusercontent.com/u/105580681/xhr-fiddle/0001.html">
<input type="radio" class="openpage" name="radio-group" id="https://dl.dropboxusercontent.com/u/105580681/xhr-fiddle/0002.html">
<input type="radio" class="openpage" name="radio-group" id="https://dl.dropboxusercontent.com/u/105580681/xhr-fiddle/0003.html">
<input type="radio" class="openpage" name="radio-group" id="https://dl.dropboxusercontent.com/u/105580681/xhr-fiddle/0004.html">
<div id="loadPage"></div>

このフィドルでは、ドロップボックス リンクを使用して html ファイルをロードしています。0001 ~ 0004 の ID 番号の最初のアイデアを使用できます。
ただし、html ページのコンテンツ全体をロードしている場合、その外部 html ページから対象のメイン ページの内部まですべてがロードされます。

例:

<div id="loadPage">
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <div>Content of HTML 0001 Page</div>
</div>

これは、メイン ページの DOM ファイルに影響します。ページの機能が失われることはありませんが、これは優れたプログラミング手法ではありません。そのため、対象の要素に表示するコンテンツを xxxx.html ファイルに書き込むか読み込む必要があるでしょう。 XMLHttpRequest Mozilla MDN

の使用 から詳細を学ぶFormData オブジェクトの使用 Mozilla MDN

于 2015-02-27T01:52:15.537 に答える