#javascript #jquery #performance #code-organization
#javascript #jquery #Производительность #код-организация
Вопрос:
Я боролся с выбором ненавязчивого javascript вместо определения его в синтаксисе html. Я хочу убедить себя пойти по ненавязчивому пути, но у меня возникают проблемы с преодолением проблем, перечисленных ниже. Не могли бы вы, пожалуйста, помочь убедить меня 🙂
1) Когда вы ненавязчиво связываете события, на компьютере клиента возникают дополнительные накладные расходы на поиск этого элемента html, где, как и при выполнении каких-либо действий, вам не нужно повторять DOM.
2) Существует задержка между привязкой событий с помощью document.ready() (jquery) и загрузкой страницы. Это более очевидно на очень больших сайтах.
3) Если вы ненавязчиво привязываете события (onclick и т. Д.), Невозможно просмотреть html-код и узнать, что событие привязано к определенному классу или идентификатору. Это может стать проблематичным при обновлении разметки и непонимании того, что вы можете влиять на код javascript. Существует ли соглашение об именовании при определении элементов css, которые используются для привязки событий javascript (я видел, как ppl использует js_className)
4) Для сайта существуют разные части javascript для разных страниц. Например Header.html содержит навигатор, который запускает события javascript на всех страницах, где как homepage.html и searchPage.html содержит элементы, которые запускают javascript на соответствующих страницах
пример кода sudo:
header.html
<script src="../myJS.js"></script>
<div>Header</div>
<ul>
<li>nav1</li><li>nav2</li>
</ul>
homepage.html
<@include header.html>
<div class="homepageDiv">some stuff</div>
searchpage.html
<@include header.html>
<div class="searchpageDiv">some other stuff</div>
myJS.js
$(document).ready(function(){
$("ul.li").bind("click",doSomething());
$(".homePageDiv").bind("click",doSomethingElse());
$(".searchPageDiv").bind("click",doSomethingSearchy());
});
В этом случае, когда вы находитесь на странице поиска, он все равно попытается найти «homepageDiv», которого не существует, и потерпит неудачу. Это не повлияет на функциональность, но это дополнительный ненужный обход. Я мог бы разбить это на отдельные файлы javascript, но тогда браузеру приходится загружать несколько файлов, и я не могу просто обслуживать один файл и кэшировать его для всех страниц.
Каков наилучший способ использования ненавязчивого javascript, чтобы я мог легко поддерживать (довольно загруженный скриптами) веб-сайт, чтобы другой разработчик знал о привязке скриптов к элементам html при изменении моего кода. И обслуживать код так, чтобы браузер клиента не искал элементы, которые не существуют на определенной странице (но могут существовать на других).
Спасибо!
Ответ №1:
Вы в замешательстве. Ненавязчивый JavaScript — это не просто определение обработчиков событий в программе. Это набор правил для написания JavaScript таким образом, чтобы скрипт не влиял на функциональность другого JavaScript на той же странице. JavaScript — это динамический язык. Любой может вносить изменения во что угодно. Таким образом, если два отдельных скрипта на одной странице определяют глобальную переменную add
следующим образом, последний, определяющий ее, выиграет и повлияет на функциональность первого скрипта.
// script 1
var add = function (a, b) {
return a b;
};
// script 2
add = 5;
//script 1 again
add(2, 3); // error - add is a number, not a function
Теперь, чтобы ответить на ваш вопрос напрямую:
- Дополнительные накладные расходы на поиск элемента в JavaScript и прикрепление к нему прослушивателя событий невелики. Вы можете использовать новый метод DOM
document.querySelector
, чтобы быстро найти элемент и прикрепить к нему прослушиватель событий (для поиска элемента требуется менее 1 мс). - Если вы хотите быстро подключить прослушиватели событий, не делайте этого при загрузке содержимого вашего документа. Прикрепите прослушиватели событий в конце основного раздела или непосредственно после той части вашего HTML-кода, к которой вы хотите прикрепить прослушиватель событий.
- Я не понимаю, как изменение разметки может каким-либо образом повлиять на JavaScript. Если вы попытаетесь подключить прослушиватель событий к элементу, которого нет в JavaScript, он автоматически завершится ошибкой или выдаст исключение. В любом случае, это действительно не повлияет на функциональность остальной части страницы. Кроме того, HTML-дизайнеру действительно не нужно знать о событиях, связанных с каким-либо элементом. Предполагается, что HTML используется только для семантической разметки; CSS используется для стилизации; а JavaScript используется для поведения. Не путайте три.
- Бог дал нам свободу воли. Используйте его. JavaScript поддерживает условное выполнение. Есть
if
заявления. ПосмотритеhomePageDiv
, существует ли он, и только затем присоедините к нему прослушиватель событий.
Попробуйте:
$(document).ready(function () {
$("ul.li").bind("click",doSomething());
if (document.querySelector(".homePageDiv")) {
$(".homePageDiv").bind("click",doSomethingElse());
} else {
$(".searchPageDiv").bind("click",doSomethingSearchy());
}
});
Ваш вопрос имел очень мало общего с ненавязчивым JavaScript. Это показало отсутствие исследований и понимания. Таким образом, я не голосую за это. Извините.
Комментарии:
1. К сожалению, я думаю, что мой главный вопрос упущен. Я понимаю ненавязчивый javascript, и мои вопросы вытекают из одного из его основных принципов — разделения функционального и презентационного уровней (отсюда и все ссылки на события привязки) Я постараюсь переработать свой вопрос, чтобы он был немного понятнее. Спасибо
Ответ №2:
То, что jQuery.ready()
выполняется, не означает, что страница видна конечному пользователю. Это поведение определяется браузерами, и в наши дни здесь действительно нужно учитывать 2 события, поскольку mootools ставит его DomReady
против Load
. Когда jQuery выполняет ready
метод, в котором говорится о загрузке dom, загружается, однако это не означает, что страница готова к просмотру пользователем, Внешние элементы, такие как изображения и даже таблицы стилей и т. Д., Все еще могут загружаться.
Любая привязка, которую вы выполняете, даже крайне неэффективная, будет привязываться намного быстрее, чем все внешние ресурсы, загружаемые браузером, поэтому пользователь IMHO не должен испытывать разницы между отображаемой страницей и доступной функциональностью.
Что касается поиска привязки к элементам в вашем DOM. Вы действительно просто боитесь, что что-то потеряется. На самом деле это не был мой реальный опыт, чаще всего в вашем JS вы можете проверить, на какой странице вы находитесь, и добавить javascript только для этой страницы (как упоминалось выше). После этого операция быстрого поиска в вашем редакторе должна помочь вам найти что-нибудь, если материал потеряется.
Имейте в виду, что при истинном MVC функциональность должна быть отделена от уровня представления. Это именно то, о чем говорит OO javascript или ненавязчивый javascript. Вы должны иметь возможность изменять свой DOM, не нарушая функциональность страницы. Да, если вы измените класс css и / или идентификатор элемента, к которому вы привязываете свой JS, он сломается, однако пользователь не будет знать об этом, и страница, по крайней мере, будет работать. Однако, если это вызывает большую озабоченность, вы можете использовать OO-Javascript и поместить div
‘s или span
‘s в качестве заполнителей в свой dom и использовать их в качестве маркеров для вставки функциональности или сообщения о ее существовании, вы даже можете использовать html-комментарии. Однако, по моему опыту, вы знаете поведение своего сайта и, следовательно, всегда будете знать, что там есть какой-то JS.
Хотя я понимаю большую часть ваших опасений по поводу бесполезных обходов, я думаю, что на данный момент вы зря беспокоитесь о 1 дополнительном обходе. До IE8 раньше было так, что переход с именем тега и идентификатором был намного быстрее, чем мой селектор, но это уже не так, поскольку браузеры стали намного быстрее при использовании только селекторов:
-
$("a#myLink")
— самый медленный. -
$("a.myLink")
— быстрее. -
$("#Link")
— самый быстрый. -
$(".myLink")
— самый быстрый.
По ссылке ниже вы можете видеть, что выполняется до 34 тысяч операций в секунду, поэтому я сомневаюсь, что скорость является проблемой.
Вы можете использовать firebug для проверки скорости каждого из них в случае очень большого dom.
В заключение:
а) Не беспокойтесь о потере js-кода, всегда есть ctrl f
б) Нет задержки, потому что готовность dom не означает, что страница видна для начала.
Обновите фиксированный порядок скорости операций на основе результатов тестов, приведенных здесь, однако имейте в виду, что производительность IE <8 действительно была, если вы не указали контейнер (раньше это было правилом, теперь это, похоже, исключение из правила).
Комментарии:
1. Ваше объяснение скорости селекторов очень неверно и почти противоположно тому, что верно.
2. Вы правы Тестовые образцы с использованием jquery мое тестирование проводилось с помощью библиотеки Prototype, и, по крайней мере, через FB результаты были быстрее… Я обновлю ответ, тем не менее, это только показывает, что нет причин беспокоиться о скорости.
3. К сожалению, люди все еще используют IE7 и ниже, но в целом то, что вы сказали, имеет смысл. Я наткнулся на реализацию пространств имен в javascript, которая, на мой взгляд, может быть хорошим способом управления javascript на уровне страницы.