Включите мгновенную навигацию между представлениями в одностраничном приложении (SPA), кэшируя отрисованное состояние неактивных представлений вместо их уничтожения.
Обзор
Обычно, когда пользователь переходит между вкладками или представлениями в одностраничном приложении, разработчики либо удаляют старое представление, либо скрывают его с помощью display: none. В обоих случаях браузеру приходится заново создавать или рассчитывать весь макет и отрисовывать его, когда пользователь возвращается к этому представлению.
При использовании content-visibility: hidden в неактивных представлениях браузер удаляет содержимое элемента из потока макета и прекращает его отрисовку, но сохраняет кэшированное состояние рендеринга в памяти. Когда пользователь возвращается к нему, оно восстанавливается почти мгновенно.
Компромисс между ЦП и ОЗУ
Хотя этот подход дает огромные преимущества в производительности, он требует компромисса, которым необходимо тщательно управлять:
- Экономия ресурсов ЦП: значительная. Браузер полностью пропускает проходы макета и рисования для скрытых представлений.
- Стоимость ОЗУ: высокая. Браузер сохраняет в памяти все узлы DOM, прослушиватели событий и состояние скрытого представления.
Когда этот компромисс становится опасным
- РЕКОМЕНДУЕТСЯ использовать эту стратегию для простых приложений с небольшим, предсказуемым количеством просмотров (например, интерфейс с 3–5 вкладками).
- НЕ КЭШИРУЙТЕ все представления в динамических приложениях, которые генерируют десятки уникальных отчетов или используют бесконечные динамические маршруты. В противном случае память будет перегружена, что может привести к сбою браузера на устройствах с низкой производительностью.
- ОБЯЗАТЕЛЬНО. Если ваше приложение очень динамично, вы ДОЛЖНЫ реализовать стратегию вытеснения (например, кеш LRU), чтобы удалять старые представления при достижении порогового значения памяти.
Реализация
1. Как настроить контейнеры View
Задайте content-visibility: hidden для представлений, которые сейчас неактивны.
.spa-view.inactive {
/* MANDATORY: Use hidden to cache the rendering state of inactive views */
content-visibility: hidden;
/* Optional: Prevent hidden views from taking up physical space in layout flow */
position: absolute;
}
2. Управление фокусом
При переключении между представлениями убедитесь, что фокус клавиатуры работает правильно, чтобы сохранить доступность.
function switchToView(viewId) {
// Hide all views
document.querySelectorAll('.spa-view').forEach(view => {
view.classList.add('inactive');
view.setAttribute('aria-hidden', 'true');
});
// Show the target view
const activeView = document.getElementById(viewId);
activeView.classList.remove('inactive');
activeView.setAttribute('aria-hidden', 'false');
// MANDATORY: Move focus to the new view to ensure a logical tab-order
activeView.focus();
}
Резервные стратегии
Свойство content-visibility деградирует корректно. В браузерах, которые не поддерживают этот атрибут:
- Свойство игнорируется.
- Чтобы браузеры, не поддерживающие эту функцию, не показывали все представления одновременно, добавьте в CSS резервный вариант для
display: none:
@supports not (content-visibility: hidden) {
.spa-view.inactive {
display: none;
}
}