Производительность библиотеки определяется количеством DOM-элементов с автообновлением, частотой таймеров и стоимостью каждого обновления. Понимание этих факторов позволяет применять библиотеку без деградации интерфейса.
Каждое срабатывание таймера:
Date.now() — очень дёшево.element.textContent — вызывает
reflow при изменении.Запись в textContent дорогостоящая только если меняется
— если значение не изменилось, дополнительного reflow нет. Библиотека
всегда записывает новое значение, не проверяя старое.
import { format } from 'timeago.js';
function updateIfChanged(el, locale = 'ru') {
const date = el.getAttribute('datetime');
const newText = format(date, locale);
if (el.textContent !== newText) {
el.textContent = newText;
}
}
| Элементов | Таймеров (прим.) | Нагрузка |
|---|---|---|
| 10 | 10 | Незаметна |
| 100 | 100 | Незначительная |
| 1000 | 1000 | Ощутимая на слабых устройствах |
| 10000 | 10000 | Критическая |
Встроенный механизм render автоматически замедляет
обновление для старых дат:
В результате большинство элементов на реальной странице обновляются редко.
Если таймеры занимают > 1% CPU в idle-режиме — нагрузка избыточна.
При профилировании можно увидеть цепочку вызовов:
Timer Fired
└─ (timeago internal)
└─ format
└─ localeFunc
└─ textContent = "..."
| Подход | CPU | Перерисовки | Автообновление |
|---|---|---|---|
format разово |
Нет | При рендере | Нет |
format + setInterval |
Низкое | Регулярно | Да |
render (встроен в timeago) |
Низкое | Адаптивно | Да |
render + IntersectionObserver |
Минимальное | Только для видимых | Да |
Функция format обрабатывает тысячи вызовов в
секунду:
const iterations = 100000;
const start = performance.now();
for (let i = 0; i < iterations; i++) {
format(Date.now() - i * 1000, 'ru');
}
const elapsed = performance.now() - start;
console.log(`${iterations} вызовов за ${elapsed.toFixed(2)}ms`);
// Обычно: 100000 вызовов за 50-200ms
Каждый элемент, переданный в render, создаёт запись в
WeakMap. Это ~100–200 байт на элемент. Для 1000 элементов — ~200 КБ, что
незначительно.
Критично: если элементы удаляются без cancel, WeakMap не
освобождается немедленно (зависит от GC).
performance.now() — точный замер времени
форматирования.Если текст при обновлении меняет длину (например, “только что” → “1 минуту назад”), это может вызвать Layout Shift. Для предотвращения:
.time-ago {
min-width: 8ch; /* Резервировать минимальное место */
display: inline-block;
}