Работа с большими списками

При увеличении количества полей ввода с форматированием чисел через AutoNumeric основная нагрузка смещается в сторону управления множеством независимых экземпляров, синхронизации их состояния и минимизации затрат на DOM-операции. Библиотека изначально рассчитана на работу с отдельными элементами, однако при десятках и сотнях инстансов проявляются архитектурные нюансы, связанные с жизненным циклом объектов, обработчиками событий и перерасчётами форматирования.

Ключевой аспект масштабирования заключается в том, что каждый экземпляр AutoNumeric создаёт собственный набор слушателей событий и внутренний state machine для управления вводом, форматированием и нормализацией значений. При росте количества полей линейно увеличивается нагрузка на обработку input/change/paste событий, а также на операции преобразования строкового ввода в числовое представление и обратно.


Централизованное хранение экземпляров

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

  • ключом выступает id DOM-элемента или логический идентификатор поля
  • значением — экземпляр AutoNumeric
  • реестр хранится в Map для обеспечения O(1) доступа

Такая структура позволяет выполнять массовые операции без обхода DOM:

const autoNumericRegistry = new Map();

Инициализация множества полей:

document.querySelectorAll('.price-input').forEach((el) => {
    const instance = new AutoNumeric(el, {
        digitGroupSeparator: ' ',
        decimalCharacter: ',',
        decimalPlaces: 2
    });

    autoNumericRegistry.set(el.id, instance);
});

Использование Map снижает накладные расходы по сравнению с повторным поиском через querySelectorAll при каждой операции обновления.


Массовая инициализация и пакетная обработка

При больших формах (100–500 полей) критически важно выполнять инициализацию пакетно, избегая промежуточных reflow и layout recalculation.

Оптимизированный подход:

  • временное отключение визуального обновления
  • создание всех экземпляров в одном проходе
  • минимизация доступа к layout-свойствам DOM
const fragment = document.createDocumentFragment();
const nodes = document.querySelectorAll('.auto');

nodes.forEach((el) => fragment.appendChild(el));
document.body.appendChild(fragment);

nodes.forEach((el) => {
    const instance = new AutoNumeric(el, config);
    autoNumericRegistry.set(el, instance);
});

Хотя AutoNumeric не требует перемещения DOM, сам принцип пакетной инициализации снижает количество синхронных операций браузера.


Управление значениями в большом наборе полей

При работе с большими формами часто требуется синхронное обновление значений, например пересчёт итогов, валютных конверсий или массовое применение коэффициента.

Прямое обновление через каждый инстанс:

for (const instance of autoNumericRegistry.values()) {
    instance.set(0);
}

Для более сложных операций применяется функция трансформации:

function applyMultiplier(multiplier) {
    for (const instance of autoNumericRegistry.values()) {
        const value = instance.getNumber();
        instance.set(value * multiplier);
    }
}

Ключевой момент — использование getNumber() вместо getFormatted(), поскольку строковое представление требует дополнительного парсинга и может приводить к деградации производительности при массовых операциях.


Оптимизация событийной модели

В больших списках основная нагрузка часто связана не с вычислениями, а с частотой событий ввода. Каждое нажатие клавиши приводит к:

  • нормализации ввода
  • форматированию строки
  • обновлению DOM value
  • триггеру событий изменения состояния

При сотнях полей это создаёт значительный поток событий.

Используется стратегия сглаживания обработки:

let scheduled = false;

function scheduleRecalc() {
    if (scheduled) return;
    scheduled = true;

    requestAnimationFrame(() => {
        recalcTotals();
        scheduled = false;
    });
}

Каждое поле вызывает только постановку задачи, а не немедленный пересчёт.


Динамические списки и добавление элементов

При добавлении новых строк в таблицы или списки важно избегать полной реинициализации всех инстансов. Типичная ошибка — повторный вызов new AutoNumeric() для уже существующих элементов.

Корректная модель:

  • инициализация только новых элементов
  • регистрация инстанса в общем реестре
  • отсутствие повторной привязки к уже обработанным DOM-узлам
function addRow(el) {
    const input = el.querySelector('input.price');

    const instance = new AutoNumeric(input, config);
    autoNumericRegistry.set(input.id, instance);
}

Удаление элемента требует обязательного вызова dispose или аналогичного метода освобождения:

function removeRow(id) {
    const instance = autoNumericRegistry.get(id);

    if (instance) {
        instance.remove();
        autoNumericRegistry.delete(id);
    }
}

Очистка и уничтожение экземпляров

В условиях долгоживущих SPA-приложений утечки памяти возникают при сохранении ссылок на DOM-элементы или обработчики событий AutoNumeric.

Жизненный цикл должен завершаться явно:

  • удаление слушателей событий
  • освобождение ссылки на DOM
  • удаление из реестра
function destroyAll() {
    for (const instance of autoNumericRegistry.values()) {
        instance.remove();
    }

    autoNumericRegistry.clear();
}

Особое внимание требуется при работе с модальными окнами и табами, где DOM пересоздаётся, но логические ссылки часто сохраняются.


Виртуализация списков

При тысячах строк стандартная DOM-модель становится неэффективной. AutoNumeric в таких случаях применяется только к видимым элементам.

Принцип виртуализации:

  • в DOM присутствует ограниченное окно элементов
  • при прокрутке элементы переиспользуются
  • инстансы AutoNumeric привязываются к переиспользуемым input

Псевдологика:

function onRenderVisibleRows(rows) {
    cleanupInvisibleInstances();

    rows.forEach((row) => {
        if (!autoNumericRegistry.has(row.input.id)) {
            const instance = new AutoNumeric(row.input, config);
            autoNumericRegistry.set(row.input.id, instance);
        }
    });
}

В таких условиях идентификатор элемента становится критически важным, поскольку DOM-узлы постоянно переиспользуются.


Батчевые операции над списками

При необходимости выполнить массовое изменение значений или конфигурации применяется пакетный режим:

  • отключение реактивных обработчиков
  • выполнение изменений
  • восстановление обработчиков
function batchUpdate(callback) {
    disableListeners();

    callback();

    enableListeners();
}

Это предотвращает каскадные перерасчёты, которые возникают при последовательных set() вызовах.


Интеграция с формами большого размера

При работе с формами, содержащими десятки секций, важно отделять логическую модель данных от UI-слоя AutoNumeric.

Подход:

  • AutoNumeric отвечает только за форматирование
  • состояние формы хранится отдельно
  • синхронизация происходит при submit или debounced update
function serializeForm() {
    const data = {};

    for (const [id, instance] of autoNumericRegistry.entries()) {
        data[id] = instance.getNumber();
    }

    return data;
}

Такой подход исключает зависимость бизнес-логики от DOM-состояния.


Типичные ошибки при масштабировании

При увеличении количества инстансов AutoNumeric наиболее частые проблемы возникают из-за архитектурных решений:

  • повторная инициализация на одном элементе без destroy
  • хранение экземпляров без очистки реестра
  • использование строкового значения вместо числового API
  • отсутствие батчирования массовых операций
  • прямое чтение DOM value вместо обращения к instance API
  • отсутствие контроля над динамически добавляемыми элементами

Каждая из этих ошибок проявляется не сразу, но при росте количества полей приводит к деградации производительности и нестабильности состояния ввода.


Производственная модель управления списками

При промышленном использовании AutoNumeric в больших формах формируется устойчивая модель:

  • единый реестр экземпляров
  • строгий жизненный цикл создания и уничтожения
  • разделение UI и данных
  • минимизация количества синхронных обновлений DOM
  • виртуализация при превышении порога элементов
  • пакетные операции вместо поэлементных изменений

Такая структура обеспечивает стабильное поведение даже при сотнях одновременно активных числовых полей ввода и сложной логике пересчётов.