Как сделать эффективные программы веб-интерфейса-это проблема, которую я буду бессознательно рассматривать каждый раз, когда я занимаюсь фронтальной разработкой. Несколько лет назад потрясающие фронт-инженеры в Yahoo опубликовали книгу об улучшении производительности веб-фронта, что вызвало ощущение во всей индустрии технологий веб-разработки, что сделало загадочный вопрос оптимизации веб-фронта на улице, и оптимизация веб-фронта стала простым вопросом, на который могут ответить оба новичка и большие гиганты. Когда вся отрасль знает ответ на шокирующий секрет, существующая технология оптимизации больше не может производить качественный скачок для веб -сайта, который вы разрабатываете. Чтобы сделать производительность веб -сайта, который мы разрабатываем лучше, чем веб -сайты других людей, нам нужно более глубоко думать и зарезервировать лучшие навыки.
Система событий в JavaScript - это первый прорывной момент, о котором я думаю. Почему это система событий JavaScript? Мы все знаем, что веб-фронт содержит три технологии: HTML, CSS и JavaScript. Понятно, как HTML и CSS объединяются: теги стиля, класса, ID и HTML. Нечего говорить, но как JavaScript входит в середину между HTML и CSS и позволяет трем интегрироваться? Наконец, я обнаружил, что эта точка входа является системой событий JavaScript. Независимо от того, как долго или сложный код JavaScript мы пишем, он в конечном итоге отражено в HTML и CSS через систему событий. Поэтому я думал, что, поскольку система событий является точкой входа для интеграции трех, на странице неизбежно будет большое количество операций событий, особенно на сегодняшних все более сложных веб -страницах. Без этих событий код JavaScript, который мы тщательно написали, можно использовать только в библиотеке, а герои бесполезны. Поскольку на странице существует большое количество функций событий, будут ли проблемы, которые влияют на эффективность при написании функций событий, как мы привыкли? Ответ, который я изучал, заключается в том, что это реальная проблема эффективности, и это также серьезная проблема с эффективностью.
Чтобы прояснить мой ответ, я хочу подробно объяснить систему событий JavaScript.
Система событий является точкой входа для слияния JavaScript, HTML и CSS. Эта точка похожа на основную функцию в Java. Все магии начинаются здесь. Так как же браузер завершает эту запись? Я изучал три способа, они:
Метод 1: обработка событий HTML
Обработка событий HTML заключается в том, чтобы записать функции событий непосредственно в тег HTML. Поскольку этот метод написания тесно связан с тегом HTML, он называется обработкой событий HTML. Например, следующий код:
Кода -копия выглядит следующим образом:
<input type = "кнопка" id = "btn" name = "btn" onclick = "alert ('нажмите меня!')"/>
Если функция события Click сложна, написание такого кода определенно принесет неудобства. Поэтому мы часто пишем функцию снаружи, а OnClick напрямую вызывает имя функции, например:
Кода -копия выглядит следующим образом:
<input type = "кнопка" id = "btn" name = "btn" onclick = "btnclk ()"/>
функция btnclk () {
оповещение («Нажмите меня!»);
}
Приведенный выше метод письма является очень красивым методом письма, поэтому многие люди будут бессознательно использовать его в наши дни, но многие люди могут не знать, что последний метод письма на самом деле не так силен, как первый метод письма. Это также проблема, с которой я столкнулся при изучении не блокирующей технологии сценариев загрузки не так давно, потому что в соответствии с принципом оптимизации фронта, код JavaScript часто расположен в нижней части страницы. Когда страница заблокирована сценарием, функция, упомянутая в теге HTML, возможно, еще не была выполнена. В настоящее время мы нажимаем кнопку «Страница», и результат будет сообщено «Функция XXX - неопределенная ошибка». В JavaScript такие ошибки будут пойманы Try and Catch. Поэтому, чтобы сделать код более надежным, у нас будет следующее переписывание:
Кода -копия выглядит следующим образом:
<input type = "кнопка" id = "btn" name = "btn" onclick = "try {btnclk ();} catch (e) {}"/>
Видеть приведенный выше код - это не то, что может быть описано отвратительным человеком.
Метод 2: Обработка событий DOM0
Обработка событий DOM0 - это обработка событий, поддерживаемая всеми браузерами сегодня. Нет проблемы совместимости. Видеть такое предложение сделает все, кто делает веб-фронт, взволнованный. Правило для обработки событий DOM0: каждый элемент DOM имеет свой собственный атрибут обработки событий, которому можно присвоить функцию, такую как следующий код:
Кода -копия выглядит следующим образом:
var btndom = document.getElementById ("btn");
btndom.onclick = function () {
оповещение («Нажмите меня!»);
}
Атрибуты события, обработанные событиями DOM0, определены в форме «on+name», и весь атрибут находится в строчных буквах. Мы знаем, что элемент DOM является объектом JavaScript в коде JavaScript, поэтому очень легко понять обработку событий на уровне DOM0 с точки зрения объекта JavaScript, например, следующего кода:
Кода -копия выглядит следующим образом:
btndom.onclick = null;
Затем событие нажатия кнопки отменено.
Давайте посмотрим на следующий код:
Кода -копия выглядит следующим образом:
btndom.onclick = function () {
оповещение («Нажмите меня!»);
}
btndom.onclick = function () {
Alert («Нажмите Me1111!»);
}
Следующая функция будет перезаписать первую функцию.
Метод 3: обработка событий DOM2 и обработка событий IE
Обработка событий DOM2 является стандартизированным решением по обработке событий, но IE Browser разработал набор функций, а функции аналогичны обработке событий DOM2, но код отличается от этого.
Прежде чем объяснить метод третьего, я должен добавить несколько концепций, иначе я не смогу объяснить сознание метода третьего.
Первая концепция: поток событий
В разработке страницы мы часто сталкиваемся с этой ситуацией. Интервал работы страницы может быть представлен документом в JavaScript. На странице есть дифта. Div эквивалентен наложению элемента документа. В Div есть элемент кнопки. Элемент кнопки накладывает Div, который также эквивалентен наложению документа. Таким образом, проблема в том, что когда мы нажимаем эту кнопку, это поведение нажатия фактически происходит не только в кнопке. И DIV, и документ используются для операций клика. Согласно Logic, эти три элемента могут запустить события щелчка. Поток событий описывает концепцию вышеуказанного сценария. Поток событий означает: порядок событий, полученных со страницы.
Вторая концепция: пузыри событий и захват событий
Пузырьки событий - это решение, предложенное Microsoft для решения проблемы потока событий, в то время как захват событий - это решение для потока событий, предложенное Netscape. Их принципы следующие:
Пузырьковое событие начинается с DIV, за которым следует тело, и, наконец, документ, и захват события перевернут, сначала документ, за которым следует тело, и, наконец, целевой элемент Div. Напротив, решение Microsoft более гуманное и в соответствии с рабочими привычками людей, решение Netscape очень неловко. Это следствие войны браузера. Netscape медленнее и решает проблему потока событий, жертвуя кодом, к которому используются пользователи.
Microsoft разработала новую систему событий в сочетании с Bubble Events, которая обычно известна как обработка событий IE в отрасли. Метод обработки событий IE, как показано в следующем коде:
Кода -копия выглядит следующим образом:
var btndom = document.getElementById ("btn");
btndom.attachevent ("onclick", function () {
оповещение («Нажмите меня!»);
});
Добавьте события через метод AttachmentEvent элемента DOM в разделе IE. По сравнению с обработкой событий DOM0 метод добавления событий изменился от атрибутов к методам, поэтому, когда мы добавляем события, нам необходимо перенести параметры в метод. Метод AttachmentEvent получает два параметра. Первый параметр - тип события. Наименование типа события совпадает с именованием событий в обработке событий DOM0. Второй параметр - функция события. Преимущество использования метода состоит в том, что если мы добавляем событие Click в тот же элемент, как показано ниже:
Кода -копия выглядит следующим образом:
btndom.attachevent ("onclick", function () {
оповещение («Нажмите меня!»);
});
btndom.attachevent ("onclick", function () {
оповещение («Нажмите меня тоже!»);
});
Запустите его, оба диалоговых окна появляются нормально, что позволяет нам добавлять несколько различных событий клика в элемент DOM. Что если мы не хотим события? Что мы должны делать? Я предоставляю метод отключения для удаления событий. Список параметров такой же, как AttachEvent. Если мы хотим удалить определенное событие Click, просто передайте те же параметры, что и событие добавления, как показано в следующем коде:
Кода -копия выглядит следующим образом:
btndom.detachevent ("onclick", function () {
оповещение («Нажмите меня тоже!»);
});
При его запусках последствия очень серьезны, и мы смущены. Второй щелчок не был удален. Что происходит? Ранее я упоминал, что удаление событий требует прохождения параметров, таких как добавление событий. Однако в анонимной функции JavaScript, даже если код двух анонимных функций точно такой же, JavaScript будет использовать разные переменные для их хранения. В результате явление, которое мы видим, не может удалить событие Click, поэтому наш код должен быть написан так:
Кода -копия выглядит следующим образом:
var ftn = function () {
оповещение («Нажмите меня тоже!»);
};
btndom.attachevent ("onclick", ftn);
btndom.detachevent ("onclick", ftn);
Добавлен метод и удаленный метод таким образом указывает на тот же объект, поэтому событие успешно удалено. Сценарий здесь говорит нам, что нам нужно иметь хорошую привычку писать события, которые мы должны определять операции независимо, и не использовать анонимные функции в качестве привычки.
Далее - обработка событий DOM2, его принцип показан на рисунке ниже:
DOM2 - это стандартизированное событие. Используя события DOM2, доставка событий начинается с метода захвата, то есть от документа, а затем до тела. Div - это промежуточная точка. Когда событие достигает промежуточной точки, событие находится на целевой стадии. После того, как событие попадает в целевую стадию, событие начинает пузыриться и обрабатывать, и, наконец, событие заканчивается на документе. (Я указываю на документирование в этой статье, но фактическая ситуация состоит в том, что некоторые браузеры начнут захватывать событие и закончить пузырь в окне. Однако я думаю, что независимо от того, как сам браузер устанавливается во время разработки, он более ориентирован на развитие, чтобы обратить внимание на документ, поэтому я использую документ здесь). Люди используются для классификации целевой стадии как часть пузыря, главным образом потому, что события пузырьков более широко используются в разработке.
Обработка событий DOM2 очень сложно. Когда каждое событие будет вызвано, все элементы будут проходить дважды. По сравнению с событием IE, производительность намного хуже, чем событие IE. Я только пузырись, поэтому мне нужно пройти только один раз. Тем не менее, меньшее обход не означает, что система событий IE более эффективна. Поддержка двух систем событий одновременно принесет большую гибкость в нашу разработку с точки зрения разработки и дизайна. С этой точки зрения события DOM2 все еще очень желательны. Код для события DOM2 заключается в следующем:
Кода -копия выглядит следующим образом:
var btndom = document.getElementById ("btn");
btndom.addeventlistener ("click", function () {
оповещение («Нажмите меня!»);
},ЛОЖЬ);
var ftn = function () {
оповещение («Нажмите меня тоже!»);
};
btndom.addeventListener ("click", ftn, false);
Добавление событий в обработку событий DOM2 использует AddEventListener, который получает один параметр, чем обработка событий IE. Первые два означают то же самое, что и два параметра метода обработки событий IE. Единственное отличие состоит в том, что префикс на удалении удаляется в первом параметре, а третий параметр - логическое значение. Если его значение верно, то событие будет обработано в режиме захвата со значением false. Событие обрабатывается в пузырьках. С третьим параметром мы можем понять, почему элемент события следует запускать дважды в обработке событий DOM2. Цель состоит в том, чтобы быть совместимой с двумя моделями событий. Тем не менее, обратите внимание, что независимо от того, выбираем ли мы захват или пузырь, два обхода будут проводиться навсегда. Если мы выберем один метод обработки событий, то в другом процессе обработки событий не будет запускана функция обработки событий. Это то же самое, что и принцип холостого хода на автомобиле в нейтральной передаче. Благодаря разработке метода событий DOM2 мы знаем, что события DOM2 могут выполнять только один из двух методов обработки событий во время выполнения. Две системы потока событий невозможно спровоцировать одновременно. Следовательно, хотя элемент дважды пересекается, функция события не может быть спровоцирована дважды. Обратите внимание, что я имею в виду, что не провоцируется никаких двух раз, что относится к функции события. Фактически, мы можем имитировать ситуацию, когда две модели потока событий выполняются одновременно, например, следующий код:
Кода -копия выглядит следующим образом:
btndom.addeventlistener ("click", ftn, true);
btndom.addeventListener ("click", ftn, false);
Но этот способ написания является многоэтранной обработкой, которая эквивалентна нажатию кнопки дважды.
Dom2 также предоставляет функцию удаления событий. Эта функция удаляется, написанная следующим образом:
Кода -копия выглядит следующим образом:
btndom.removeeventListener ("Щелкни", ftn, false);
То же самое относится и к событию IE, то есть параметры должны соответствовать параметрам, которые определяют событие. Однако при использовании RemoveEventListener третий параметр не проходит. По умолчанию является удаление события пузыря, потому что по умолчанию неверно, если третий параметр не пройден. Например:
Кода -копия выглядит следующим образом:
btndom.addeventlistener ("click", ftn, true);
btndom.removeeventListener ("Щелкни", ftn);
Запустите его и обнаружите, что событие не было удалено успешно.
Наконец, я хочу сказать, что обработка событий DOM2 хорошо поддерживается в IE9, включая IE9 или выше, а IE8 ниже не поддерживает события DOM2.
Давайте сравним три метода событий ниже, следующим образом:
Сравнение 1: Сравнение одного метода для одной стороны и двух других методов
Способ писать метод один - объединить HTML и JavaScript. У тебя есть я, и ты у меня есть. Углушите этот метод для достижения смешанной разработки HTML и JavaScript. В программном термине это кодовая связь. Кодовая связь не очень хороша, и это очень плохо. Это уровень программиста -новичка, поэтому, как только метод полностью побежден, два других метода выиграют.
Сравнение 2: Метод 2 и Метод 3
Двое из них написаны одинаково. Иногда действительно трудно сказать, кто лучше или хуже. Глядя на приведенный выше контент, мы обнаружили, что самая большая разница между режимом 2 и режимом 3 состоит в том, что в элементе DOM есть только одно событие, и только один раз, в то время как в режиме 3 можно разрешить событие в элементе DOM иметь несколько функций обработки событий. При обработке событий DOM2 режим 3 также может позволить нам точно управлять методом потока событий. Следовательно, функция режима 3 более мощная, чем режим 2, поэтому по сравнению с режимом 3 она немного лучше.
Ниже приведено фокус этой статьи: проблемы производительности систем событий. Чтобы решить проблемы с производительностью, нужно найти фокус. Здесь я подумаю о проблемах производительности систем событий из двух точек фокуса, а именно: уменьшение количества обходов и потребления памяти.
Прежде всего, количество проходов. Независимо от того, захватывает ли это потоки событий или пузырящие потоки событий, они будут пересекать элементы, но все они пройдут, начиная с верхнего окна или документа. Если элемент DOM страницы имеет глубокие отношения между родителями и ребенком, то чем больше элементов вы пересекаете, тем больше вредно будет обработка событий DOM2, тем больше обход. Как решить проблему прохождения этого потока событий? Мой ответ нет. У некоторых друзей здесь могут быть вопросы, почему их больше нет? В системе событий есть объект события, которая является событием. Этот объект имеет метод для предотвращения пузырьков или захвата событий. Почему я говорю, что никого нет? Вопрос этого друга имеет смысл, но если мы хотим использовать этот метод, чтобы уменьшить обход, то наш код будет иметь дело с отношениями между элементами отца и сына и отношениями деда. Если элементы страницы очень много вложены, это задача, которая не может быть выполнена, поэтому мой ответ заключается в том, что проблема обхода не может быть изменена, и мы можем только адаптироваться к ней.
Похоже, что снижение обхода не может решить проблему производительности системы событий, поэтому теперь мы можем только рассмотреть потребление памяти. Я часто слышу, как люди говорят, что C# очень полезен, но это еще лучше для разработки веб-фронта. Мы можем напрямую перетащить кнопку на страницу в C# IDE. После того, как кнопка достигнет страницы, код JavaScript автоматически добавит событие в кнопку. Конечно, функция события внутри является пустой функцией. Поэтому я думаю, что мы можем поместить 100 кнопок на странице таким образом. Если один код не работает, будет обработка 100 кнопок, что очень удобно. Наконец, мы добавляем конкретное событие кнопки в одну из кнопок, чтобы запустить страницу. Эффективна ли эта страница? В JavaScript каждая функция является объектом, и каждый объект потребляет память, поэтому этот бесполезный код функции события 99 должен потреблять много ценной памяти браузера. Конечно, мы не будем делать это в реальной среде разработки, но в сегодняшнюю эпоху популярного и одностраничного развития Ajax-это сумасшедшая и популярная, на веб-странице есть так много событий, что означает, что у каждого события есть функция события, но каждая операция, которую мы запускаем только одно событие. В настоящее время другие события спит во время лежа, что не играет никакой роли и потребляет компьютерную память.
Нам нужно решение, чтобы изменить эту ситуацию, и в реальности действительно есть такое решение. Чтобы четко описать этот план, я хочу сначала добавить некоторые фоновые знания. В обсуждении обработки событий DOM2 я упомянул концепцию целевого объекта. Откладывая метод обработки событий DOM2, существует также концепция целевого объекта в обработке событий захвата и обработке событий пузырьков. Целевой объект является элементом DOM конкретной работы события. Например, кнопка в работе кнопки нажатия является целевым объектом. Независимо от того, какой метод обработки событий, функция события будет содержать объект события. Объект события имеет цель атрибута, цель всегда указывает на целевой объект, а объект события имеет еще один атрибут, CurrentTarget, который указывает на элемент DOM, поступающий в событие захвата или пузырька. Из приведенного выше описания мы знаем, что будь то событие захвата или пузырьковое событие, поток событий будет переходить к документу. Если мы добавим событие Click в документе, а кнопка на странице не добавит событие Click, то мы нажимаем кнопку и знаем, что событие Click в документе будет запускаться. Здесь есть подробная информация о том, что когда событие нажатия документа запускается, цель цели события - кнопка, а не документ, поэтому мы можем написать код таким образом:
Кода -копия выглядит следующим образом:
<input type = "кнопка" id = "btn" name = "btn" value = "кнопка"/>
<a href = "#" id = "aa"> aa </a>
document.addeventlistener ("click", function (evt) {
var target = evt.target;
Switch (target.id) {
Дело "btn":
оповещение («кнопка»);
перерыв;
дело "AA":
оповещение ("a");
перерыв;
}
},ЛОЖЬ);
Запустив его, мы обнаружили, что эффект такой же, как и событие, которое мы написали кнопку отдельно. Но его преимущества являются самоочевидными. Одна функция обрабатывает функцию события всей страницы, и ни одна функция события не является холодной, что идеально. Этот план также имеет профессиональное название: делегация мероприятия. Метод делегата JQUERY выполняется в соответствии с этим принципом. Фактически, эффективность делегирования событий не только отражается в снижении функций событий, но и снижает операции DOM. Например, в приведенном выше примере мы добавляем функцию в документ. Документ является объектом верхнего уровня на странице, а эффективность его чтения очень высока. Когда дело доходит до конкретных событий объектов, мы не используем операцию DOM, а используем целевой атрибут объекта события. Все это может быть обобщено только в одном предложении: это действительно быстро, нет причин быть быстрым.
Делегация мероприятия также может принести нам отличный побочный продукт. Друзья, которые использовали jQuery, должны были использовать метод живого. Функция метода в прямом эфире заключается в том, что вы можете добавить операции событий в элементы страницы. Даже если этого элемента не существует на странице в настоящее время, вы можете добавить его события. После понимания механизма делегирования события, принцип жизни легко понять. На самом деле, в прямом эфире JQUERY осуществляется делегирование событий, и Live также является эффективным способом добавления события.
После понимания делегирования событий мы обнаружим, что метод связывания jQuery является неэффективным методом. Поскольку он использует исходный метод определения событий, мы должны использовать Bind с осторожностью. На самом деле, разработчики jQuery также заметили эту проблему. Новая версия jQuery имеет метод. Метод ON содержит все функции методов связывания, живого и делегирования. Поэтому я предлагаю друзьям, которые прочитали эту статью, отказались от предыдущего метода добавления событий и использования в функциях для добавления событий.
Делегация мероприятия имеет еще одно преимущество. В примере делегирования событий в приведенной выше статье я добавил события в документ. Здесь я хочу сделать сравнение. В jQuery мы привыкли поместить определение событий элементов DOM в метод готовых, как показано ниже:
Кода -копия выглядит следующим образом:
$ (document) .ready (function () {
Xxx.bind ("click", function () {});
});
Функция готового выполняется после загрузки документа Page DOM. Это выполняется первым, чем функция Onload. Это имеет много преимуществ заранее. Одним из преимуществ также является повышение производительности. Определение такого события, как jQuery, также является стандартной практикой. Я считаю, что некоторые друзья должны связать определенные события вне готового и, наконец, обнаружить, что кнопка будет недействительной. Этот недопустимый сценарий иногда занимает минуту, и через некоторое время все будет хорошо. Поэтому мы часто игнорируем принцип этой проблемы и не связываем события в готовой функции. Эта операция на самом деле является связывающим событиями до загрузки DOM, и в соответствии с этим периодом мы на самом деле связываем с ними события. Весьма вероятно, что некоторые элементы не были построены на странице, поэтому связывание событий будет недействительным. Следовательно, причина готового определения событий состоит в том, чтобы гарантировать, что все элементы страницы загружены для определения событий элемента DOM после их загрузки. Тем не менее, проблем можно избежать при использовании делегатов событий. Например, привязывание событий с документом, документ представляет всю страницу, поэтому это самое раннее время для его загрузки. Следовательно, трудно достичь делегатов событий в документе, и также трудно привести к тому, что браузер сообщил о «xxx функции неопределенной». Подводя итог этой функции: код делегирования событий может быть запущен на любом этапе загрузки страницы, что предоставит разработчикам большую свободу в улучшении производительности веб -страницы или улучшении эффектов веб -страницы.
ОК, эта статья была написана. Спокойной ночи.