Улучшаем производительность select2 с большими списками

  • Vadim Tsukanov
    Разработчик
  • Дата публикации
    18.03.2021
  • Категория
    JavaScript
select2 тормозит
Задача:Быстрый поиск по селекту с 20 000 элементами списка

Select2 — отличный jQuery плагин, встречается на многих современных сайтов, однако что делать если у селекта большое количество значений?
Стандартное решение тормозит на телефонах, при количестве опшенов более 1000, а что делать если их 20000?

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

Для реализации воспользуемся кодом ниже. Инитим селект данной функцией, где selectId — #селекта, а dataSelect — массив значений типа:

items = [];
cities.forEach(function (city) {
    items.push({id: city['code'], text: city['city']});
});

function initSelect2(selectId, dataSelect) {
    var pageSize = 20;
    $.fn.select2.amd.require(["select2/data/array", "select2/utils"],
        function (ArrayData, Utils) {
            
            function CustomData($element, options) {
                CustomData.__super__.constructor.call(this, $element, options);
            }
            
            Utils.Extend(CustomData, ArrayData);
            CustomData.prototype.query = function (params, callback) {
                if (!("page" in params)) {
                    params.page = 1;
                }
                var data = {};
                if (params.term != undefined && params.term != '') {
                    let subData = $.grep(dataSelect, function (n, i) {
                        if (n.text.toLowerCase().indexOf(params.term.toLowerCase()) > -1) {
                            return n;
                        }
                    });
                    data.results = subData.slice((params.page - 1) * pageSize, params.page * pageSize);
                }
                else {
                    data.results = dataSelect.slice((params.page - 1) * pageSize, params.page * pageSize);
                }
                data.pagination = {};
                data.pagination.more = params.page * pageSize < dataSelect.length;
                callback(data);
            };
            
            selectName.select2({
                ajax: {},
                dataAdapter: CustomData,
                width: '100%'
            });
        });
}

Благодаря этому коду нам удалось полностью убрать лаги для списка в 15700 строк. Будем надеяться, что это поможет и Вам.

2 Комментариев
  • muzanaka
    2022-10-25 08:54:14

    уже нет. Сайт, в котором применяли - уже не работает. Использовали для выбора населенных пунктов РФ

  • Илья
    2022-10-25 08:34:03

    А есть демо-версия, чтобы посмотреть это решение в действии?

Оформить заказ в Devstages