Статья первоначально опубликована на моем личном веб -сайте на Как оптимизировать манипуляции с DOM jQuery
Если вы работаете с JavaScript, то, скорее всего, JQuery – это библиотека, которую вы используете довольно часто. JQuery полезен и предоставляет много функций, которые сложнее достичь с помощью базового JavaScript. Из-за того, что он обычно работает на стороне клиента, многие не уделяют слишком много внимания оптимизации кода. Вот почему есть много веб -сайтов, которые загружаются медленно, имеют вялые пользовательские интерфейсы или, похоже, реагируют с задержкой. Итак, в этой статье я покажу методику оптимизации, которая может сэкономить много времени при рендеринге страницы с динамически добавленными элементами.
Наш сценарий: загрузка продуктов без перезагрузки страницы
Давайте посмотрим на общий вариант использования, где эта техника может быть полезна. Вы разработчик, который работает в интернет -магазине. Из -за характера инфраструктуры и требований клиента React не является вариантом, поэтому вы возвращаетесь к более «традиционному» подходу. Существует только одно приложение для сервера: его воспроизведение (Java/Scala), Codeigniter (PHP) или любая другая структура, которые используют шаблон двигателя, отображают DOM страниц.
Теперь, в рамках функции навигации по каталогам, вы получаете частичный результат (по партиям из 100 пунктов) и отображаете их на странице с меню страниц внизу. Когда следующая страница нажимается, вместо того, чтобы физически перейти на новую страницу, вы используете вызовы AJAX, чтобы получить новые элементы и выполнять манипуляции с DOM для их отображения. Шаги такие:
- AJAX CALL TO ITEM? PAGE =
- Получить ответ как JSON
- Очистить существующие отображаемые элементы со страницы
- Восстановите DOM с помощью новых предметов
Первая реализация (плохая): Рендеринг каждого элемента индивидуально
Давайте посмотрим на часть кода. Эта функция создает HTML для продукта и изменяет DOM, так что она отображается на странице (изображение, имя и цена)
function makeItemOnPage(item, itemNo) { // we create a container for the current item var itemContainer = ''; $("#products").append(itemContainer); // we create a div for the product imate and display it var productImage = ''; var currentItemContainer = $("#products").find("#item-" + itemNo); currentItemContainer.append(productImage); $("#productImage-"+itemNo).append(''); // We append the product name and the price currentItemContainer.append('
Давайте разместите 1000 пунктов и увидим время, которое нужно. Я немного преувеличил количество элементов, чтобы общая прибыль от оптимизации была лучше показана. Мы можем легко увидеть, как долго это требуется, используя анализатор производительности браузера. Как видно на изображении, на страницу потребовалось около 1,7 секунды, чтобы элементы были отображены. Это может показаться не так уж много (у нас есть 1000 элементов), но HTML в этом случае довольно прост и не имеет слишком много внутренних объектов. Страница с гораздо более сложным дизайном может легко иметь более сложный HTML -код для каждого элемента. И даже в этом случае пользователь должен ждать почти 2 секунды, пока элементы будут отображаться, не очень хорошо с точки зрения UX. Я думаю, что мы можем много оптимизировать вещи.
Первое, что мы видим, это то, что мы проводим много поиска элементов на странице и многие добавили. Мы ищем контейнер элементов, добавляем Div для текущего контейнера элемента, ищем его, добавляем изображение, добавляем имя и цену, а после этого еще одно добавление для кнопки. Анализируя время в инспекторе производительности, мы видим, что эти добавления занимают довольно много времени, почти равное общему времени. Итак, давайте попробуем создать HTML для всего элемента в качестве одной строки и добавить все это один раз.
Код такой:
function makeItemOnPage(item, itemNo) { // we create a container for the current item var productImageHtml = getProductImageHtml(item, itemNo); var productDetailsHtml = getProductDetailsHtml(item, itemNo); var addToCart = getAddToCartButton(item, itemNo); var itemContainer = ''; itemContainer += productImageHtml; itemContainer += productDetailsHtml; itemContainer += addToCart; itemContainer += ""; $("#products").append(itemContainer); } function getProductImageHtml(item, itemNo) { return ''; } function getProductDetailsHtml(item, itemNo) { return '' + item.name + ' - ' + item.price + '$'; } function getAddToCartButton(item, itemNo) { return ''; }
Теперь, снова выполняя эталон, мы четко видим сокращение времени рендеринга. Сейчас это менее одной секунды, около 1/3 из предыдущего. Это связано с тем, что количество вызовов. Append () было сокращено только до одного на элемент. Но мы можем сделать еще лучше.
Создание необходимого HTML и добавление один раз
Теперь приходит окончательная оптимизация. Вместо того, чтобы создавать каждый просмотр продукта и добавлять его, мы можем сделать это, построив весь список продуктов и добавив полученный HTML в контейнер за один раз. Таким образом, мы называем append (), что приведет только к одному перерисованию элементов пользовательского интерфейса. Код почти идентичен, но вместо того, чтобы вызовать добавление в конце, мы просто возвращаем полученную строку.
function makeItems() { $("#products").empty(); var items = getItems(); var itemNo = 0; var items = ""; for (itemNo = 0; itemNo< items.length; itemNo++) { items += makeItemOnPage(items[itemNo], itemNo); } $("#products").append(items); } function makeItemOnPage(item, itemNo) { // we create a container for the current item var productImageHtml = getProductImageHtml(item, itemNo); var productDetailsHtml = getProductDetailsHtml(item, itemNo); var addToCart = getAddToCartButton(item, itemNo); var itemContainer = ''; itemContainer += productImageHtml; itemContainer += productDetailsHtml; itemContainer += addToCart; itemContainer += ""; return itemContainer; }
Теперь, когда мы получаем наши данные с сервера, после создания строки HML мы называем добавление в контейнер, аналогичный коду справа. Давайте снова займем тестер.
Теперь у нас менее 150 мс в этом конкретном примере, более чем в 4 раза быстрее, чем в предыдущей версии и в 12 раз быстрее, чем первая версия. Полный источник этого примера можно загрузить в оригинальной статье на моем сайте.
Выводы
Я использовал аналогичную технику для оптимизации генерации страниц на основе некоторого ввода для утилиты, работающей только в автономном режиме, которая работает в браузере. Это был просмотрщик журналов и анализатор, и начальная версия заняла около 6 секунд, чтобы обработать файл журнала 3000. После оптимизации вызовов тот же журнал был проанализирован и отображен менее чем за 0,8 секунды, что значительно улучшилось как во времени, так и пользовательском опыте.
Теперь я знаю, что генерирование HTML -кода имеет недостатки, но есть много сценариев, в которых он не только помогает, но и предлагает такие преимущества, как снижение нагрузки на сервер. Если вы осторожны, чтобы правильно разбить генерацию кода и не смешиваете разные элементы в одной и той же функции генератора, код JavaScript может оставаться чистым и простым в обслуживании.
В качестве последнего примечания я в первую очередь являюсь разработчиком в первую очередь, поэтому более опытные пользователи JavaScript могут иметь еще лучшие решения, а также возражения против этого подхода.
Статья первоначально опубликована на моем личном веб -сайте на Как оптимизировать манипуляции с DOM jQuery
Оригинал: “https://dev.to/pazvanti/optimizing-jquery-dom-manipulation-3b5i”