Подтвердить что ты не робот

Организация и производительность кода jQuery

После ряда исследований по этому вопросу я много экспериментировал с шаблонами для упорядочивания кода jQuery (Ребекка Мерфи сделала презентация на этом на конференции jQuery, например).

Вчера я проверил шаблон (показательный) модуля. Результат выглядит немного напоминающим синтаксис YUI:

//global namespace MyNameSpace
if(typeof MNS=="undefined"||!MNS){var MNS={};}

//obfuscate module, just serving as a very simple example
MNS.obfuscate = function(){
    //function to create an email address from obfuscated '@'
    var email = function(){
        $('span.email').each(function(){
            var emailAddress = $(this).html().replace(' [ @ ] ','@');
            $(this).html('<a href="mailto:' + emailAddress + '">' + emailAddress + '</a>');

        });
    };    
    return {
        email: email
    };    
}();

//using the module when the dom ready
jQuery(document).ready(function($){
    MNS.obfuscate.email();
});

В конце концов у меня было несколько модулей. Некоторые из них, естественно, включали "частные члены", которые в этом случае означают переменные и/или функции, которые были важны только для других функций в этом модуле и, таким образом, не попадали в оператор return.

Я думал, что связанные части моего кода (все, что связано с поиском, например), объединенное в модуле, имеет смысл, дает всю структуру.

Но после написания этого, я прочитал статью статьи от Джона (Resig), где он также пишет о производительности шаблона модуля:

"Создание функции с множеством свойств прототипа очень, очень быстро, полностью удаляет шаблон модуля и т.д. из воды. Таким образом, если у вас есть функция частого доступа (возвращающая объект) что вы хотите, чтобы люди взаимодействовали, тогда вам в ваших интересах, чтобы свойства объекта находились в цепочке прототипов и создавали его экземпляр. Вот он в коде:

// Very fast
function User(){}
    User.prototype = { /* Lots of properties ... */ };

// Very slow
function User(){
    return { /* Lots of properties */ };
}

(Джон упоминает, что он не против шаблона модуля "как таковой" - просто чтобы вы знали:)

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

Я не эксперт по JavaScript и, тем более, эксперт, когда дело доходит до тестирования производительности. Итак, во-первых, я не знаю, насколько далеко сказались слова, о которых говорил Джон ( "часто доступная функция (возвращение объекта), с которой вы хотите, чтобы люди взаимодействовали с", множество свойств и т.д.) Применимы к моему коду. Документы, с которыми взаимодействует мой код, не являются огромными, с 100 или 1000 элементами. Так что, возможно, это не проблема.

Но мне показалось, что вместо того, чтобы просто

$('span.email').each(function(){
    var emailAddress = $(this).html().replace(' [ @ ] ','@');
    $(this).html('<a href="mailto:' + emailAddress + '">' + emailAddress + '</a>');
});

(внутри функции domready), я создаю две "дополнительные" функции, обфускацию и электронную почту из-за использования шаблона модуля. Создание дополнительных функций стоит некоторое время. Вопрос в следующем: будет ли это измеримо в моем случае?

Я не уверен, что в моем примере выше создано закрытие (в интересной записи на форуме jQuery я читал следующее: "Существует философская дискуссия о том, создает ли внутренняя функция замыкание, если оно не ссылаться на что-либо на объект внешней переменной функции..." ), но у меня были замыкания в моем реальном коде. И хотя я не думаю, что у меня были какие-либо циркулярные ссылки, я не знаю, как далеко это может привести к высокому потреблению/проблемам памяти с сборкой мусора.

Мне бы очень хотелось услышать ваши данные об этом и, возможно, увидеть некоторые примеры вашего кода. Кроме того, какие инструменты вы предпочитаете получать информацию о времени выполнения, памяти и использовании ЦП?

4b9b3361

Ответ 1

Я также не думаю, что мне нужно наследование на данный момент

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

Объекты, созданные вами, создавая каждый экземпляр из полностью нового объекта {name: member}, менее эффективны, чем созданные вами объекты с помощью new Class с Class.prototype.name= member. В случае прототипа значение member является общим, что приводит к более легким экземплярам.

В вашем примере MNS является одноэлементным, поэтому нет никакой пользы от совместного использования элементов через прототип.

Я не уверен, что в моем примере выше создается закрытие

Да, это так. Даже когда переменные не определены во внешней функции, по-прежнему существует объект LexicalEnvironment и scope, созданный для внешней функции, с привязкой this и arguments. Умный JS-движок может оптимизировать его, поскольку каждая внутренняя функция должна скрывать this и arguments своими собственными копиями, но я не уверен, что любая из существующих реализаций JS на самом деле это делает.

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

Кроме того, какие инструменты вы предпочитаете получать информацию о времени выполнения, памяти и использовании ЦП?

Запущенное место - это просто выполнить код 10000 раз в цикле for и посмотреть, сколько у него больше new Date().getTime(), выполняется несколько раз на столько разных браузеров, сколько вы можете получить.

$(this).html(). replace ('[@]', '@');

(Что это должно делать? В настоящий момент он прочитает HTML-код span в новый String, заменит только первый экземпляр [ @ ] на @ и вернет новый String Это не изменит существующий контент в DOM.)

Ответ 2

Сколько у вас Javascript? По моему опыту, на сайтах с большим количеством кода Javascript на страницах проблемы производительности обычно исходят из кода, который на самом деле что-то делает. Как правило, проблемы связаны с попытками сделать слишком много вещей или пытаться сделать что-то очень плохое. Примером может быть попытка сделать такие вещи, как обработчики привязки, к элементам в строках таблицы (большие таблицы) вместо использования чего-то вроде "живого".

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