Утечка памяти в методе jQuery load ()? - PullRequest
4 голосов
/ 29 января 2010

Я искал ответ на этот вопрос, и хотя нашел похожие вопросы, я не смог найти точное соответствие этому.

У меня довольно большое приложение, которое должно загружать страницыв div на другой странице, используя метод jQuery.load ().У меня проблема в том, что при загрузке одной и той же страницы снова и снова в один и тот же div, я вижу, что память браузера значительно увеличивается (утечка памяти).Если я вызываю $ ("*"). Unbind, я, конечно, не вижу утечки, но тогда все было сброшено, так что это не совсем исправление.Следующий пример кода воспроизводит эту проблему:

Test1.htm

<head>
   <title></title>
    <script type="text/javascript" language="javascript" src="Scripts/jquery-1.3.2.js"></script>
        <script type="text/javascript" language="javascript">
        <!--
            var i = 0;
        $(document).ready(function() {
            $("#btn").click(
                function() {
                    i++;
                    $("#Test1").load("Test2.htm", null, function() {
                        //$(document).trigger("test");
                    })
                    $("#count").html(i);
                });
        });
    //-->
    </script>
</head>
<body>
    <img id="btn" src="someimage.png" />
    <h3>We are loading Test2.htm into below div</h3>
    <div>
        Count loads =<span id="count">0</span>
    </div>
    <div id="Test1" style="border-style:solid">EMPTY</div>
</body>

Test2.htm = любая старая HTML-страница ..

Если вы загрузите Test1.htm и нажметенесколько раз, вы заметите, что память браузера постоянно увеличивается.Я считаю, что проблема в том, что загруженные элементы js и DOM никогда не устанавливаются для сборки мусора.В моей реальной системе я пытался удалить (elem.remove () или .empty ()) загруженные элементы, но это не решило проблему.У меня также есть много js-файлов, загруженных с использованием «src», которые я заменил на $ .getScript, и это, похоже, немного улучшилось.Это все обходные пути, и я хотел найти реальное решение этой проблемы.Есть идеи?

Ответы [ 3 ]

4 голосов
/ 29 января 2010

Редактировать: обновление в связи с предоставлением дополнительной информации о test2.htm (страница загружается)

Оригинальный ответ (для исторических целей): я на самом деле не вижу никаких утечек в предоставленном вами коде / разметке - возможно, утечка находится в Test2.htm (который вы не предоставили код / разметка для)?

Новый ответ:

Я бы предположил, что это возможно из-за нескольких загрузок jQuery или других сценариев, которые есть в test2.htm.

Если предположить, что jQuery не протекает путем простого создания экземпляра, а затем обнуления jQuery и $, то при многократной загрузке в памяти останется не менее 2 копий jQuery. При загрузке jQuery сохраняет резервную копию всех предыдущих версий $ и jQuery в _$ и _jQuery - поэтому вы будете загружать как минимум 2 копии jQuery при многократном использовании load ().

Вышеупомянутое предположение, скорее всего, не верно, однако - есть все шансы, что у jQuery есть утечки, даже если вы «разгрузите» его, установив $, jQuery, _$ и _jQuery to null - на самом деле он не предназначен для такой многократной загрузки (однако я уверен, что они позволяют это намеренно, поэтому вы можете использовать noConflict() для загрузки и использования двух разных версий jQuery, если это необходимо).

Вы можете добавить «селектор» к загрузочному URL. Например:

$("#Test1").load("Test2.htm body", null, function() { 
  //callback does nothing
});
//or
$("#Test1").load("Test2.htm div#the_Div_I_Want", null, function() { 
  //callback does nothing
});

Я бы предложил сделать это, если вас не интересуют какие-либо сценарии в результате ajax или, если вы do хотите использовать сценарии, вам нужно выбрать селектор, чтобы отключить только определенные элементы / сценарии. например,

/* load with selector "all elements except scripts whose
   src attribute ends in 'jquery.js'" */
$("#Test1").load("Test2.htm :not(script[src$='jquery.js'])", null, function() { 
  //callback does nothing
});

Также следует отметить, что если вы пропустите аргумент «data» (он у вас будет null) и предоставите функцию в качестве второго аргумента, jQuery правильно определит, что второй аргумент является обратным вызовом, поэтому

$("#Test1").load("Test2.htm :not(script[src$='jquery.js'])", function() { 
  //callback does nothing
});

приемлемо

1 голос
/ 29 января 2010

Хм, возможно, это просто что-то очень простое, но если я установлю $ .ajaxSetup ({cache: false}); до загрузки звонков, я не вижу проблемы. Теперь, конечно, мой «настоящий» код имеет этот вызов, так почему я могу увидеть проблему? Я полагаю, что расширение пользовательского интерфейса Tabs приводит к включению кэширования (на самом деле я не верю этому, но вызывает ложный вызов кэша перед каждой загрузкой, кажется, это исправляет !!)

0 голосов
/ 02 февраля 2010

Хорошо, так что я наконец-то обнаружил проблему, и это вовсе не утечка (что я подозревал), это просто результат присоединения нескольких очень сложных обработчиков к одному и тому же триггеру / событию. Я поднял этот вопрос относительно этого:

Модель событий JQuery и предотвращение дублирования обработчиков

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...