2015-04-10 2 views
4

Этот вопрос касается того, как функция jQuery содержит элементы HTML и может ли быть влияние на сбор мусора.Возникает ли влияние функции jQuery на сборку мусора?

Рассмотрите две следующие функции, которые отображают или скрывают определенный элемент <div> на странице HTML.

function showError() { $("div#error").show(); } 
function hideError() { $("div#error").hide(); } 

Эти две функции всегда вызова JQuery найти < Див > элемент в дереве DOM; они могут быть переработан, чтобы устранить накладные расходы функции JQuery один раз, как таковой:

var divError = $("div#error"); 
function showError() { divError.show(); } 
function hideError() { divError.hide(); } 

Но в этом случае переменная divError ослаблен в глобальном масштабе; мы могли бы сделать какой-то трюк с помощью функции:

var showError, hideError; 
(function() { 
    var divError = $("div#error"); 
    showError = function() { divError.show(); } 
    hideError = function() { divError.hide(); } 
})(); 

Во всех этих случаях, какое влияние оказывает сбор мусора? Является ли проблемой иметь результат вызова функции jQuery, плавающей в глобальной области?

Является ли хорошей дисциплиной, чтобы попытаться свести к минимуму вызов функции jQuery? Должны ли эти примеры следовать или избегать?

Если я заменил jQuery в этих примерах на document.getElementById(), чтобы получить элемент HTML, применимы ли те же проблемы?

+0

Не уверен, но выполняет [эту помощь] (http://stackoverflow.com/questions/864516/what-is-javascript-garbage-collection)? –

ответ

2

Garbage Collection

Если вы делаете несколько из них, то не беспокойтесь об этом. Любой один из случаев пользователя, показанный здесь, если он используется сам по себе, не будет отрицательно влиять на использование памяти.

памяти след

Они начинают иметь влияние потенциал когда сделано в большом цикле. Each time a function object is created, it can take up to 754 bytes of memory. Если вы создадите многие из них, например 1000, вы можете на короткое время нажать 1 МБ памяти в зависимости от браузера, который ничтожно мал. 10 000 становится немного хуже (~ 10 МБ), 100 000 (~ 100 МБ) становится неприятным, и 1 000 000 (~ 1 ГБ), вероятно, начнут вызывать некоторые серьезные проблемы в зависимости от клиента в виде минутного блокировки пользовательского интерфейса.

сфера

сборщик мусора станет фактором в предыдущей ситуации, когда объекты не сохраняются в текущем контексте выполнения. Каждый контекст выполнения имеет лексическую и переменную среду. Переменная среда является той, которая будет иметь право на сбор мусора, если текущий контекст выполнения теряет область действия. Однако отметить, что допустимый только означает, что это произойдет sometime и не дает никаких обещаний о том, когда.

Чтобы уменьшить растущий объем памяти, гарантируя, что реализация контекста функции реализована для того, чтобы как можно быстрее потерять область действия, убедитесь, что сборщик мусора имеет возможность как можно быстрее собирать данные. Опять же, возможность сбора не может быть реализована в течение некоторого времени.

Реализация

Что все это разыгрывается до закрывает над переменными, так как только их ссылки нет, они имеют право на получение коллекции в какой-то момент в будущем, когда это удобно для сборщика мусора.

производительность

В дополнение к этому, относятся к вызову функции JQuery не должны быть значительными, если они используются в одиночку. Единственный раз, когда повторяется запрос, становится проблема, когда у вас более 10 000 элементов DOM, в которых у вас могут возникнуть другие проблемы; и когда вы собираетесь перебирать тысячи раз и хотите избежать накапливания миллисекунд. Оптимизация всего, что занимает менее 10 миллисекунд, вероятно, является микро-оптимизацией. 10-100 является дискреционным, и более 100, безусловно, гарантированы.

Кроме того, в любое время, когда элемент получает доступ по идентификатору, к нему напрямую обращаются через поиск словаря (хеш-таблицы), который является O (1). Это означает, что ваш DOM не нужно полностью разбирать. Однако это может быть не всегда так, поэтому я предполагаю, что мы не можем просто остановиться там.

Так что если это используется только один раз, то здесь нет ничего плохого в вашем первом сценарии (нет необходимости использовать div здесь, id - поиск O (1)).

function showError() { $("#error").show(); } 
function hideError() { $("#error").hide(); } 

Однако, если по какой-то причине строка для идентификатора является селектором класса, и они делаются в большом количестве как-то в цикле, вы хотите, чтобы убедиться, что определение функции области видимости цикла , и что селектор элементов кэшируется (кэширование само по себе представляет интересный боковой случай, когда набор кешированных элементов может не соответствовать набору страниц для таких вещей, как селектор классов на динамических страницах, - но это крайний случай).

сфера

Родитель сфера важна, потому что вы никогда не хотите быть выполнение кода в глобальном масштабе. Таким образом, в то время как эти два сделать то же самое

var divError = $("div#error"); 
function showError() { divError.show(); } 
function hideError() { divError.hide(); } 

и

var showError, hideError; 
(function() { 
var divError = $("div#error"); 
showError = function() { divError.show(); } 
hideError = function() { divError.hide(); } 
})(); 

(обратите внимание, что, поскольку анонимные функции в IIFE имеют переменные среды, на который ссылается его лексической средой и, как следствие, не будет иметь права для сбора мусора до тех пор, пока лексическая среда не будет допущена)

Они оба рассматривают область действия несколько иначе. Первый будет выставлять переменную divError, а вторая - нет. В узкой среде это не имеет большого значения, поскольку столкновения в лексической и переменной среде менее вероятны, но в глобальном пространстве имен это может быть проблематично, поскольку лексическая среда не будет собрана до тех пор, пока вся страница не будет выгружена. Это называется polluting the global namespace.

Альтернативы

В конце концов, весь этот анализ сводится к чему-то должно было быть довольно тривиально. Если вы хотите иметь глобальный доступ к этому элементу, сохраните его в безопасной уже используемой глобальной переменной. Поскольку вы используете jQuery, вы можете просто использовать $.

$.errorDiv = $("#error"); 

и когда вы хотите, чтобы переключить его, просто используйте переключатель :) Или скрыть/показать, если вы не уверены в состоянии или как-то называть его, чтобы показать два раза.

$.errorDiv.toggle(); 
$.errorDiv.show(); 
$.errorDiv.hide(); 

Этот последний раздел может не применяться как непосредственно, я понимаю, потому что это, вероятно, было простым воспроизведением подобного поведения.

Смежные вопросы