Когда использовать Vanilla JavaScript против jQuery? - PullRequest
232 голосов
/ 11 января 2011

Я заметил, отслеживая / пытаясь ответить на распространенные вопросы jQuery, что есть определенные практики, использующие javascript вместо jQuery, которые фактически позволяют вам писать меньше и делать ... ну то же самое,А также может принести выигрыш в производительности.

Конкретный пример

$(this) против this

Внутри события щелчка, ссылающегося на объекты, по которым щелкнули, id

jQuery

$(this).attr("id");

Javascript

this.id;

Существуют ли другие распространенные практики, подобные этой?Где некоторые операции Javascript могут быть выполнены проще, без привлечения JQuery в смесь.Или это редкий случай?(из «ярлыка» jQuery, на самом деле требующего большего количества кода)

РЕДАКТИРОВАТЬ: Хотя я ценю ответы относительно производительности jQuery и простой JavaScript, на самом деле я ищу гораздо более количественные ответы. При использовании jQuery - случаи, когда было бы лучше (удобочитаемость / компактность) использовать простой javascript вместо $().В дополнение к примеру, который я привел в своем первоначальном вопросе.

Ответы [ 13 ]

203 голосов
/ 11 января 2011
  • this.id (как вы знаете)
  • this.value (для большинства типов ввода. Мне известны только проблемы с IE, когда <select> не имеет свойств value, установленных на его <option> элементах, или радиовходы в Safari.)
  • this.className чтобы получить или установить свойство "class" целиком
  • this.selectedIndex против <select> для получения выбранного индекса
  • this.options против <select>, чтобы получить список <option> элементов
  • this.text против <option> для получения его текстового содержимого
  • this.rows против <table>, чтобы получить коллекцию <tr> элементов
  • this.cells против <tr>, чтобы получить его клетки (td & th)
  • this.parentNode чтобы получить прямого родителя
  • this.checked чтобы получить проверенное состояние checkbox Спасибо @Tim Down
  • this.selected, чтобы получить выбранное состояние option Спасибо @Tim Down
  • this.disabled чтобы получить отключенное состояние input Спасибо @Tim Down
  • this.readOnly для получения состояния readOnly input Спасибо @Tim Down
  • this.href против элемента <a>, чтобы получить его href
  • this.hostname против элемента <a>, чтобы получить домен его href
  • this.pathname против элемента <a>, чтобы получить путь к его href
  • this.search против элемента <a>, чтобы получить строку запроса его href
  • this.src против элемента, для которого допустимо иметь src

... Я думаю, вы поняли.

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

В общем, вы можете заменить:

$(el).attr('someName');

с

Выше было плохо сформулировано. getAttribute не является заменой, но он извлекает значение атрибута, отправленного с сервера, и соответствующий ему setAttribute установит его. Необходим в некоторых случаях.

Приведенные ниже предложения как бы охватывают это. См. Этот ответ для лучшего лечения.

el.getAttribute('someName');

... для прямого доступа к атрибуту. Обратите внимание, что атрибуты не совпадают со свойствами (хотя иногда они отражают друг друга). Конечно, setAttribute тоже.

Скажем, у вас возникла ситуация, когда получили страницу, где нужно развернуть все теги определенного типа. Это быстро и просто с jQuery:

$('span').unwrap();  // unwrap all span elements

Но если их много, вы можете захотеть сделать небольшой нативный DOM API:

var spans = document.getElementsByTagName('span');

while( spans[0] ) {
    var parent = spans[0].parentNode;
    while( spans[0].firstChild ) {
        parent.insertBefore( spans[0].firstChild, spans[0]);
    }
    parent.removeChild( spans[0] );
}

Этот код довольно короткий, он работает лучше, чем версия jQuery, и его легко превратить в функцию многократного использования в вашей личной библиотеке.

Может показаться, что у меня бесконечный цикл с внешним while из-за while(spans[0]), но, поскольку мы имеем дело с «живым списком», он обновляется, когда мы делаем parent.removeChild(span[0]);. Это довольно изящная функция, которую мы упускаем при работе с массивом (или объектом, похожим на массив).

60 голосов
/ 11 января 2011

Правильный ответ таков: всегда получит снижение производительности при использовании jQuery вместо «старого» нативного JavaScript. Это потому, что jQuery - это библиотека JavaScript. Это не какая-то необычная новая версия JavaScript.

Причина того, что jQuery является мощным, заключается в том, что он делает некоторые вещи чрезмерно утомительными в кросс-браузерной ситуации (AJAX - один из лучших примеров) и сглаживает несоответствия между множеством доступных браузеров и предоставляет согласованный API , Это также легко облегчает такие понятия, как связывание, подразумеваемая итерация и т. Д., Чтобы упростить совместную работу над группами элементов.

Обучение jQuery не заменит изучение JavaScript. У вас должна быть прочная основа в последнем, чтобы вы в полной мере оценили то, что знание первого облегчает вам.

- отредактировано для включения комментариев -

Поскольку в комментариях быстро указывается (и я согласен со 100%), приведенные выше утверждения относятся к коду бенчмаркинга. «Нативное» решение JavaScript (при условии, что оно хорошо написано) превзойдет решение jQuery, которое выполняет то же самое почти в каждом случае (я хотел бы увидеть пример в противном случае). JQuery ускоряет время разработки, что является значительным преимуществом, которое я не хочу преуменьшать Он обеспечивает легкий для чтения, легкий для понимания код, который некоторые разработчики могут создавать самостоятельно.

По-моему, ответ зависит от того, чего вы пытаетесь достичь. Если, как я полагаю, исходя из вашей ссылки на выигрыш в производительности, вам не хватает максимальной скорости работы приложения, тогда использование jQuery приводит к дополнительным затратам каждый раз, когда вы вызываете $(). Если вы предпочитаете удобочитаемость, согласованность, совместимость с различными браузерами и т. Д., То, безусловно, есть причины отдавать предпочтение jQuery над «нативным» JavaScript.

38 голосов
/ 30 апреля 2013

Есть фреймворк, который называется ... о, угадайте, что?Vanilla JS.Надеюсь, вы получите шутку ...: D Он жертвует разборчивостью кода для производительности ... Сравнивая его с jQuery ниже, вы можете видеть, что получение элемента DOM с помощью ID почти 35X быстрее,:)

Так что, если вы хотите производительности, вам лучше попробовать Vanilla JS и сделать свои собственные выводы.Может быть, у вас не будет JavaScript, зависающего в графическом интерфейсе браузера / блокирующего поток пользовательского интерфейса во время интенсивного кода, как внутри цикла for.

Vanilla JS - это быстрая, легкая, кроссплатформенная инфраструктурасоздание невероятных, мощных приложений JavaScript.

На их домашней странице есть несколько сравнений:

enter image description here

17 голосов
/ 11 января 2011

Уже есть принятый ответ, но я считаю, что ни один из ответов, набранных непосредственно здесь, не может быть исчерпывающим в своем списке нативных методов / атрибутов javascript, который практически гарантирует межбраузерную поддержку.Для этого я могу перенаправить вас в причудливый режим:

http://www.quirksmode.org/compatibility.html

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

Когда я начал серьезно писать веб-приложения, я распечатал все таблицы DOM и повесил их на стенечто я с первого взгляда знаю, что безопасно использовать и что требует взлома.В эти дни я просто гуглю что-то вроде quirksmode parentNode compatibility, когда у меня возникают сомнения.

Как и все остальное, суждение - это в основном вопрос опыта.Я бы не советовал вам читать весь сайт и запоминать все вопросы, чтобы выяснить, когда использовать jQuery, а когда использовать простой JS.Просто будьте в курсе списка.Это достаточно легко для поиска.Со временем у вас разовьется инстинкт предпочтения простого JS.


PS: у PPK (автора сайта) также есть очень хорошая книга, которую я рекомендую прочитать

14 голосов
/ 11 января 2011

Когда:

  1. вы знаете, что существует непревзойденная кросс-браузерная поддержка того, что вы делаете, и
  2. это не намного больше кода для ввода, а
  3. это не значительно менее читабельно, а
  4. вы достаточно уверены, что jQuery не выберет различные реализации на основе браузера для достижения лучшей производительности, тогда:

использовать JavaScript. В противном случае используйте jQuery (если можете).

Редактировать : Этот ответ применяется как при выборе использования jQuery в целом, а не при его исключении, так и при выборе, использовать ли vanilla JS внутри jQuery. Выбор между attr('id') и .id склоняется в пользу JS, а выбор между removeClass('foo') против .className = .className.replace( new Regexp("(?:^|\\s+)"+foo+"(?:\\s+|$)",'g'), '' ) склоняется в пользу jQuery.

13 голосов
/ 11 января 2011

Ответы других были сосредоточены на широком вопросе «JQuery против простого JS». Судя по вашему OP, я думаю, вы просто задались вопросом, когда лучше использовать vanilla JS, если вы уже решили использовать jQuery. Ваш пример является прекрасным примером того, когда вы должны использовать vanilla JS:

$(this).attr('id');

Он медленнее и (на мой взгляд) менее читабелен, чем:

this.id.

Это медленнее, потому что вам нужно раскрутить новый объект JS только для того, чтобы получить атрибут способом jQuery. Теперь, если вы собираетесь использовать $(this) для выполнения других операций, то непременно сохраните этот объект jQuery в переменной и оперируйте этим. Однако я сталкивался со многими ситуациями, когда мне просто нужен атрибут из элемента (например, id или src).

Существуют ли другие распространенные практики? как это? Где определенный Javascript операции могут быть выполнены проще, не вводя jQuery в смесь. Или это редкий случай? (из JQuery "ярлык" на самом деле требует больше кода)

Я думаю, что наиболее распространенным случаем является тот, который вы описываете в своем посте; люди, без всякой необходимости упаковывающие $(this) в объект jQuery. Чаще всего это происходит с id и value (вместо этого используется $(this).val()).

Редактировать: Вот статья , которая объясняет , почему с использованием jQuery в случае attr() медленнее. Исповедь: украл его из тега вики, но я думаю, что стоит упомянуть вопрос.

Снова отредактируйте: Учитывая удобочитаемость / производительность простого доступа к атрибутам напрямую, я бы сказал, что хорошее практическое правило - попытаться использовать this.<attributename>, когда это возможно. Вероятно, в некоторых случаях это не сработает из-за несоответствий в браузере, но, возможно, лучше сначала попробовать это и воспользоваться jQuery, если он не работает.

10 голосов
/ 11 января 2011

Если вас больше всего беспокоит производительность, ваш главный пример - удар по голове. Вызывать jQuery излишне или излишне, IMHO, вторая основная причина низкой производительности (первая - плохой обход DOM).

Это не на самом деле пример того, что вы ищете, но я вижу это так часто, что стоит упомянуть: один из лучших способов повысить производительность ваших сценариев jQuery - это кэшировать jQuery. объекты и / или использовать цепочку:

// poor
$(this).animate({'opacity':'0'}, function() { $(this).remove(); });

// excellent
var element = $(this);
element.animate({'opacity':'0'}, function() { element.remove(); });

// poor
$('.something').load('url');
$('.something').show();

// excellent
var something = $('#container').children('p.something');
something.load('url').show();
8 голосов
/ 11 января 2011

Я обнаружил, что JS и JQ частично совпадают. Код, который вы показали, является хорошим примером этого. Честно говоря, лучшая причина использовать JQ поверх JS - просто совместимость с браузерами. Я всегда склоняюсь к JQ, даже если я могу что-то сделать в JS.

6 голосов
/ 11 января 2011

Это мое личное мнение, но поскольку jQuery в любом случае является JavaScript, я думаю, что теоретически он не может работать лучше, чем vanilla JS.

Но практически он может работать лучше, чем рукописный JS, так какнаписанный код может быть не таким эффективным, как jQuery.

Итог - для небольших вещей я склонен использовать vanilla JS, для интенсивных проектов JS мне нравится использовать jQuery, а не изобретать велосипед - это также более продуктивно.

3 голосов
/ 23 марта 2013

Список активных свойств первого ответа this в качестве элемента DOM довольно полон.

Вам также может быть интересно узнать некоторые другие.

Когда это документ:

  • this.forms для получения HTMLCollection форм текущего документа,
  • this.anchors для получения HTMLCollection всех HTMLAnchorElements с установленным name
  • this.images для получения HTMLCollection всех HTMLImageElement s
  • и то же самое для устаревших апплетов, что и this.applets

При работе с document.forms, document.forms[formNameOrId] получает так называемую или идентифицированную форму.

Когда это форма:

  • this[inputNameOrId], чтобы получить так называемое или идентифицированное поле

Когда это поле формы:

  • this.type для получения типа поля

При изучении селекторов jQuery мы часто пропускаем изучение уже существующих свойств элементов HTML, к которым так быстро получить доступ.

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