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

При использовании Tippy.js с большими наборами элементов, необходимо учитывать производительность, управление состояниями и оптимизацию рендеринга всплывающих подсказок. Для списков с сотнями или тысячами элементов стандартная инициализация tippy() на каждом элементе может привести к тормозам и высокому потреблению памяти.


Ленивое создание подсказок (Lazy Initialization)

Создание подсказки только при необходимости значительно снижает нагрузку:

tippy.delegate(document.body, {
  target: '.list-item',
  content: (reference) => reference.getAttribute('data-tooltip'),
  delay: 100,
  interactive: true,
});

Пояснения:

  • delegate позволяет не инициализировать подсказки для каждого элемента сразу.
  • target определяет CSS-селектор элементов, для которых будет работать делегирование.
  • Функция content вычисляется только в момент появления подсказки.

Это особенно эффективно для динамически обновляемых списков или элементов, загружаемых по скроллу.


Использование виртуального рендеринга

Для списков с огромным количеством элементов, стоит комбинировать Tippy.js с виртуальными списками (например, Virtualized List):

import { FixedSizeList } from 'react-window';

const Row = ({ index, style }) => (
  
Элемент {index}
); {Row}
  • Tippy можно подключить через delegate, чтобы не создавать отдельные экземпляры на все 10 000 элементов.
  • Подсказки создаются только для видимых элементов в списке.

Оптимизация производительности

  1. Объединение подсказок: Если несколько элементов показывают одинаковую информацию, можно использовать один экземпляр Tippy с динамическим контентом:
const tooltip = tippy(document.body, { 
  content: '', 
  trigger: 'manual',
  placement: 'right',
});

document.body.addEventListener('mouseover', (e) => {
  const target = e.target.closest('.list-item');
  if (!target) return;
  tooltip.setContent(target.getAttribute('data-tooltip'));
  tooltip.show(target);
});

document.body.addEventListener('mouseout', () => tooltip.hide());
  1. Минимизация событий на каждом элементе: Избегать отдельного mouseover/mouseout на сотнях элементов, вместо этого использовать событийное делегирование через родительский контейнер.

  2. Уменьшение количества DOM-элементов подсказки: Подсказка создается один раз, а её содержимое обновляется динамически.


Настройка интерактивности

Для больших списков часто требуется, чтобы подсказка оставалась открытой при наведении на неё:

tippy.delegate(document.body, {
  target: '.list-item',
  content: (ref) => ref.getAttribute('data-tooltip'),
  interactive: true,
  delay: [100, 200], // задержка показа и скрытия
  maxWidth: 250
});
  • interactive: true позволяет удерживать подсказку при перемещении курсора на сам tooltip.
  • delay помогает предотвратить быстрое мерцание при движении по списку.

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

Для списков, которые обновляются через AJAX или WebSocket, используется метод setContent:

const tooltip = tippy(document.body, { content: '', trigger: 'manual' });

function updateTooltipData(index, text) {
  const element = document.querySelector(`.list-item[data-index="${index}"]`);
  if (element._tippy) {
    element._tippy.setContent(text);
  }
}
  • Позволяет обновлять подсказки без пересоздания экземпляров.
  • Сохраняется высокая производительность даже при изменении данных тысяч элементов.

Принципы работы с большими списками

  • Использовать делегирование событий вместо индивидуальной инициализации.
  • Создавать подсказку только при необходимости.
  • Минимизировать DOM-операции, обновляя контент динамически.
  • Использовать виртуальные списки для огромного количества элементов.
  • Контролировать интерактивность и задержки для удобства пользователя.

Полезные параметры для больших списков

Параметр Назначение
delegate Делегирование подсказок на родительский контейнер
content Функция динамического контента для каждого элемента
interactive Позволяет удерживать подсказку при наведении
delay Контроль времени появления и скрытия
maxWidth Ограничение ширины подсказки для компактности
trigger Управление событиями открытия (например, manual для ручного контроля)

Эти инструменты позволяют использовать Tippy.js с тысячами элементов без тормозов, обеспечивая при этом гибкость и динамичность интерфейса.