Tippy.js — это современная библиотека для создания всплывающих подсказок (tooltips) и легких попапов в веб-приложениях. Для эффективного использования в больших проектах часто применяют code splitting — стратегию разделения кода, позволяющую загружать библиотеки и модули только тогда, когда они реально необходимы.
Библиотеку можно установить через npm или использовать CDN:
npm install @popperjs/core tippy.js
Для использования через ES-модули:
import tippy from 'tippy.js';
import 'tippy.js/dist/tippy.css';
Этот подход загружает всю библиотеку целиком. В больших проектах это может быть избыточным, особенно если Tippy используется только на нескольких страницах.
Code splitting позволяет разбить приложение на отдельные чанки, которые подгружаются динамически. Для Tippy.js это особенно актуально, если всплывающие подсказки нужны не на каждой странице.
Пример динамического импорта:
document.querySelectorAll('.tooltip-trigger').forEach(async (el) => {
const { default: tippy } = await import('tippy.js');
import('tippy.js/dist/tippy.css');
tippy(el, {
content: el.getAttribute('data-tooltip'),
animation: 'fade',
delay: [100, 50],
});
});
await import('tippy.js') — динамически загружает
библиотеку только при необходимости.import('tippy.js/dist/tippy.css') — также позволяет
загружать стили динамически, экономя ресурсы на страницах без
подсказок.В конфигурации Webpack динамический импорт автоматически создаёт отдельный чанки. Для Tippy.js рекомендуется:
// В компоненте
const loadTippy = () => import('tippy.js').then(({ default: tippy }) => tippy);
document.querySelectorAll('.tooltip-trigger').forEach(async el => {
const tippy = await loadTippy();
tippy(el, { content: el.dataset.tooltip });
});
Дополнительно можно настроить webpackChunkName для удобного именования файлов:
const tippy = await import(/* webpackChunkName: "tippy" */ 'tippy.js').then(m => m.default);
Это позволяет легче отслеживать чанки в сети и оптимизировать кэширование.
Для Vite и ESBuild используется такой же синтаксис динамического
импорта. Разница только в том, что сборщики автоматически создают
отдельные файлы при import() без дополнительной
настройки.
Tippy.js поддерживает плагины, например followCursor или
sticky. Их также можно загружать динамически, чтобы
уменьшить размер основного бандла:
const { default: tippy } = await import('tippy.js');
const { default: followCursor } = await import('tippy.js/dist/plugins/followCursor');
tippy('.tooltip-trigger', {
content: 'Наведи на меня',
plugins: [followCursor],
});
Для динамического импорта стилей есть несколько подходов:
<link rel="stylesheet" href="...">
с динамическим созданием тега:const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://unpkg.com/tippy.js@6/dist/tippy.css';
document.head.appendChild(link);
Этот метод подходит для приложений, где CSS не включен в основной бандл.
mouseenter или focus для вызова
импорта.document.addEventListener('mouseover', async (e) => {
const target = e.target.closest('.tooltip-trigger');
if (!target || target.dataset.tippyInitialized) return;
const [{ default: tippy },] = await Promise.all([
import('tippy.js'),
import('tippy.js/dist/tippy.css')
]);
tippy(target, {
content: target.dataset.tooltip,
animation: 'scale',
delay: [150, 100]
});
target.dataset.tippyInitialized = 'true';
});
В этом примере:
data-tippy-initialized.Promise.all для одновременной
загрузки JS и CSS.Эта стратегия позволяет эффективно интегрировать Tippy.js в масштабные веб-приложения, снижая нагрузку на основной бандл и ускоряя первичную загрузку страниц. Code splitting становится особенно важным при большом количестве зависимостей и плагинов.