При увеличении объёма данных стандартные HTML-select и даже базовая конфигурация UI-компонентов начинают испытывать проблемы: задержки рендера, высокая нагрузка на DOM, медленный поиск и ухудшение отклика интерфейса. Choices.js предоставляет набор механизмов, позволяющих обрабатывать тысячи и десятки тысяч элементов без критической деградации производительности.
Ключевой принцип работы с большими данными — минимизация количества одновременно отрисованных элементов.
const instance = new Choices('#select', {
searchEnabled: true,
searchResultLimit: 20
});
Параметр searchResultLimit ограничивает число элементов,
отображаемых в выпадающем списке. Это снижает:
При больших наборах данных сортировка становится дорогой операцией.
const instance = new Choices('#select', {
shouldSort: false
});
Отключение сортировки передаёт управление порядком данных на сторону источника (например, сервер или заранее подготовленный массив).
Работа с большими наборами практически всегда требует загрузки данных по мере необходимости.
Choices.js позволяет подключать асинхронный поиск через
callbackOnSearch.
const instance = new Choices('#select', {
searchEnabled: true,
callbackOnSearch: function(value, instance) {
fetch(`/api/items?q=${value}`)
.then(res => res.json())
.then(data => {
instance.setChoices(data, 'value', 'label', true);
});
}
});
При большом количестве вводимых символов без ограничения частоты запросов возникает перегрузка API.
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
Использование с Choices.js:
const fetchData = debounce((value, instance) => {
fetch(`/api/items?q=${value}`)
.then(res => res.json())
.then(data => {
instance.setChoices(data, 'value', 'label', true);
});
}, 300);
const instance = new Choices('#select', {
searchEnabled: true,
callbackOnSearch: fetchData
});
При больших объёмах данных (10k–1M записей) клиентская фильтрация становится неэффективной.
fetch(`/api/products?query=phone&limit=50`)
instance.setChoices(data, 'id', 'name', true);
Для предотвращения перегрузки интерфейса применяется постраничная выдача.
let page = 1;
function loadMore(value, instance) {
fetch(`/api/items?q=${value}&page=${page}`)
.then(res => res.json())
.then(data => {
instance.setChoices(data, 'id', 'label', false);
page++;
});
}
Важно различать режимы:
replaceChoices = true — полная замена списка;replaceChoices = false — добавление новых
элементов.Choices.js в этом режиме используется как «ленивая витрина» данных.
Частые повторные запросы к одним и тем же данным создают избыточную нагрузку.
const cache = new Map();
function getCached(query) {
if (cache.has(query)) {
return Promise.resolve(cache.get(query));
}
return fetch(`/api/items?q=${query}`)
.then(res => res.json())
.then(data => {
cache.set(query, data);
return data;
});
}
Интеграция с Choices.js:
const instance = new Choices('#select', {
callbackOnSearch: (value, instance) => {
getCached(value).then(data => {
instance.setChoices(data, 'id', 'label', true);
});
}
});
Даже при ограниченном числе элементов может возникать нагрузка из-за частых перерисовок.
setChoices в короткий
промежуток времени;let pendingUpdate = null;
function updateChoices(instance, data) {
pendingUpdate = data;
requestAnimationFrame(() => {
if (pendingUpdate) {
instance.setChoices(pendingUpdate, 'id', 'label', true);
pendingUpdate = null;
}
});
}
Встроенный поиск Choices.js может работать в разных режимах.
const instance = new Choices('#select', {
searchEnabled: true,
searchFloor: 2,
searchResultLimit: 15
});
searchFloor — минимальная длина запроса;searchResultLimit — ограничение выдачи;searchEnabled — включение/выключение поиска.При сложных данных стандартный поиск заменяется внешним движком.
const instance = new Choices('#select', {
searchEnabled: true,
callbackOnSearch: (value, instance) => {
const filtered = customSearchEngine(value);
instance.setChoices(filtered, 'id', 'label', true);
}
});
Такой подход позволяет внедрять:
В некоторых сценариях часть данных загружается заранее, чтобы снизить задержки при первом вводе.
fetch('/api/items?initial=true')
.then(res => res.json())
.then(data => {
instance.setChoices(data, 'id', 'label', true);
});
Choices.js при этом используется только для отображения уже подготовленного набора.
При частой смене источников данных важно очищать внутренние структуры.
instance.clearStore();
Дополнительные операции:
removeActiveItems() — очистка выбранных элементов;setChoices([], 'id', 'label', true) — полная
переинициализация.При больших массивах важно контролировать пользовательский ввод.
const instance = new Choices('#select', {
maxItemCount: 5
});
Это предотвращает перегрузку формы и снижает вероятность некорректных сценариев использования.
При использовании Choices.js в условиях больших массивов данных основная архитектура строится вокруг следующих принципов: